From a160b2fdef9628a02e01b2549b2454f1932b3c02 Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sat, 4 Nov 2023 18:51:28 +0900 Subject: [PATCH 01/13] New design for preview --- .../Customize/EditingTenkeyCustardView.swift | 269 +++++++++--------- 1 file changed, 140 insertions(+), 129 deletions(-) diff --git a/MainApp/Customize/EditingTenkeyCustardView.swift b/MainApp/Customize/EditingTenkeyCustardView.swift index c49d913d..0a5d7c46 100644 --- a/MainApp/Customize/EditingTenkeyCustardView.swift +++ b/MainApp/Customize/EditingTenkeyCustardView.swift @@ -150,160 +150,171 @@ struct EditingTenkeyCustardView: CancelableEditor { } Toggle("自動的にタブバーに追加", isOn: $editingItem.addTabBarAutomatically) } - CustardFlickKeysView(models: models, tabDesign: .init(width: layout.rowCount, height: layout.columnCount, interfaceSize: interfaceSize, orientation: MainAppDesign.keyboardOrientation), layout: layout) {(view: FlickKeyView, x: Int, y: Int) in - if editingItem.emptyKeys.contains(.gridFit(x: x, y: y)) { - if !isCovered(at: (x, y)) { - Button { - editingItem.emptyKeys.remove(.gridFit(x: x, y: y)) - } label: { - view.disabled(true) - .opacity(0) - .overlay( - Rectangle().stroke(style: .init(lineWidth: 2, dash: [5])) - ) - .overlay( - Image(systemName: "plus.circle") - .foregroundStyle(.accentColor) - ) - } + HStack { + Spacer() + if showPreview { + Button("閉じる", systemImage: "xmark.circle") { + showPreview = false } } else { - NavigationLink(destination: CustardInterfaceKeyEditor(data: $editingItem.keys[.gridFit(x: x, y: y)])) { - view.disabled(true) - .border(Color.primary) + Button("プレビュー", systemImage: "eye") { + showPreview = true } - .contextMenu { - // TODO: これ、OSのクリップボード使ったほうがいいのかも - // TODO: Swap、DuplicateみたいなAPIも追加したい - Button { - copiedKey = editingItem.keys[.gridFit(x: x, y: y)] - } label: { - Label("コピーする", systemImage: "doc.on.doc") - } - Button { - if let copiedKey { - editingItem.keys[.gridFit(x: x, y: y)] = copiedKey + } + } + .labelStyle(.iconOnly) + .font(.title) + .padding(.horizontal, 8) + if !showPreview { + CustardFlickKeysView(models: models, tabDesign: .init(width: layout.rowCount, height: layout.columnCount, interfaceSize: interfaceSize, orientation: MainAppDesign.keyboardOrientation), layout: layout) {(view: FlickKeyView, x: Int, y: Int) in + if editingItem.emptyKeys.contains(.gridFit(x: x, y: y)) { + if !isCovered(at: (x, y)) { + Button { + editingItem.emptyKeys.remove(.gridFit(x: x, y: y)) + } label: { + view.disabled(true) + .opacity(0) + .overlay( + Rectangle().stroke(style: .init(lineWidth: 2, dash: [5])) + ) + .overlay( + Image(systemName: "plus.circle") + .foregroundStyle(.accentColor) + ) } - } label: { - Label("ペーストする", systemImage: "doc.on.clipboard") } - .disabled(copiedKey == nil) - Button { - editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount - for px in 0 ..< Int(layout.rowCount) { - for py in (y + 1 ..< Int(layout.columnCount)).reversed() { - editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] - } - } - for px in 0 ..< Int(layout.rowCount) { - editingItem.keys[.gridFit(x: px, y: y + 1)] = nil + } else { + NavigationLink(destination: CustardInterfaceKeyEditor(data: $editingItem.keys[.gridFit(x: x, y: y)])) { + view.disabled(true) + .border(Color.primary) + } + .contextMenu { + // TODO: これ、OSのクリップボード使ったほうがいいのかも + // TODO: Swap、DuplicateみたいなAPIも追加したい + Button { + copiedKey = editingItem.keys[.gridFit(x: x, y: y)] + } label: { + Label("コピーする", systemImage: "doc.on.doc") } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where y + 1 <= py: - return .gridFit(x: px, y: py + 1) - default: - return item + Button { + if let copiedKey { + editingItem.keys[.gridFit(x: x, y: y)] = copiedKey } + } label: { + Label("ペーストする", systemImage: "doc.on.clipboard") } - } label: { - Label("下に行を追加", systemImage: "plus") - } - Button { - editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount - for px in 0 ..< Int(layout.rowCount) { - for py in (y ..< Int(layout.columnCount)).reversed() { - editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] + .disabled(copiedKey == nil) + Button { + editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount + for px in 0 ..< Int(layout.rowCount) { + for py in (y + 1 ..< Int(layout.columnCount)).reversed() { + editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] + } } + for px in 0 ..< Int(layout.rowCount) { + editingItem.keys[.gridFit(x: px, y: y + 1)] = nil + } + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where y + 1 <= py: + return .gridFit(x: px, y: py + 1) + default: + return item + } + } + } label: { + Label("下に行を追加", systemImage: "plus") } - for px in 0 ..< Int(layout.rowCount) { - editingItem.keys[.gridFit(x: px, y: y)] = nil - } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where y <= py: - return .gridFit(x: px, y: py + 1) - default: - return item + Button { + editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount + for px in 0 ..< Int(layout.rowCount) { + for py in (y ..< Int(layout.columnCount)).reversed() { + editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] + } + } + for px in 0 ..< Int(layout.rowCount) { + editingItem.keys[.gridFit(x: px, y: y)] = nil + } + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where y <= py: + return .gridFit(x: px, y: py + 1) + default: + return item + } } + } label: { + Label("上に行を追加", systemImage: "plus") } - } label: { - Label("上に行を追加", systemImage: "plus") - } - Button { - editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount - for px in (x + 1 ..< Int(layout.rowCount)).reversed() { + Button { + editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount + for px in (x + 1 ..< Int(layout.rowCount)).reversed() { + for py in 0 ..< Int(layout.columnCount) { + editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] + } + } for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] + editingItem.keys[.gridFit(x: x + 1, y: py)] = nil } - } - for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: x + 1, y: py)] = nil - } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where x + 1 <= px: - return .gridFit(x: px + 1, y: py) - default: - return item + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where x + 1 <= px: + return .gridFit(x: px + 1, y: py) + default: + return item + } } + } label: { + Label("右に列を追加", systemImage: "plus") } - } label: { - Label("右に列を追加", systemImage: "plus") - } - Button { - editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount - for px in (x ..< Int(layout.rowCount)).reversed() { + Button { + editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount + for px in (x ..< Int(layout.rowCount)).reversed() { + for py in 0 ..< Int(layout.columnCount) { + editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] + } + } for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] + editingItem.keys[.gridFit(x: x, y: py)] = nil } + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where x <= px: + return .gridFit(x: px + 1, y: py) + default: + return item + } + } + } label: { + Label("左に列を追加", systemImage: "plus") + } - for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: x, y: py)] = nil + Divider() + Button(role: .destructive) { + editingItem.emptyKeys.insert(.gridFit(x: x, y: y)) + } label: { + Label("削除する", systemImage: "trash") + .foregroundStyle(.red) } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where x <= px: - return .gridFit(x: px + 1, y: py) - default: - return item - } + Button(role: .destructive) { + removeRow(y: y) + } label: { + Label("この行を削除", systemImage: "trash") + .foregroundStyle(.red) + } + Button(role: .destructive) { + removeColumn(x: x) + } label: { + Label("この列を削除", systemImage: "trash") + .foregroundStyle(.red) } - } label: { - Label("左に列を追加", systemImage: "plus") - - } - Divider() - Button(role: .destructive) { - editingItem.emptyKeys.insert(.gridFit(x: x, y: y)) - } label: { - Label("削除する", systemImage: "trash") - .foregroundStyle(.red) - } - Button(role: .destructive) { - removeRow(y: y) - } label: { - Label("この行を削除", systemImage: "trash") - .foregroundStyle(.red) - } - Button(role: .destructive) { - removeColumn(x: x) - } label: { - Label("この列を削除", systemImage: "trash") - .foregroundStyle(.red) } } } + .environmentObject(variableStates) + } else { + KeyboardPreview(defaultTab: .custard(custard)) } - .environmentObject(variableStates) - } - // FIXME: editingItemを更新しても`custard`が変更されない不具合 - BottomSheetView( - isOpen: $showPreview, - maxHeight: Design.keyboardScreenHeight(upsideComponent: nil, orientation: MainAppDesign.keyboardOrientation) + 40, - minHeight: 0 - ) { - KeyboardPreview(defaultTab: .custard(custard)) } } .onChange(of: layout) {_ in From bdd621a07876e76b8d1cbc06f264b3860495d668 Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sun, 5 Nov 2023 16:07:51 +0900 Subject: [PATCH 02/13] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Customize/EditingTenkeyCustardView.swift | 364 ++++++++---------- 1 file changed, 171 insertions(+), 193 deletions(-) diff --git a/MainApp/Customize/EditingTenkeyCustardView.swift b/MainApp/Customize/EditingTenkeyCustardView.swift index 0a5d7c46..70c2af9d 100644 --- a/MainApp/Customize/EditingTenkeyCustardView.swift +++ b/MainApp/Customize/EditingTenkeyCustardView.swift @@ -113,223 +113,201 @@ struct EditingTenkeyCustardView: CancelableEditor { var body: some View { VStack { - GeometryReader {_ in - VStack { - Form { - TextField("タブの名前", text: $editingItem.tabName) - .textFieldStyle(.roundedBorder) - .submitLabel(.done) - Button("プレビュー") { - showPreview = true - UIApplication.shared.closeKeyboard() - } - HStack { - Text("縦方向キー数") - Spacer() - IntegerTextField("縦方向キー数", text: $editingItem.columnCount, range: 1 ... .max) - .keyboardType(.numberPad) - .textFieldStyle(.roundedBorder) - .submitLabel(.done) - } - HStack { - Text("横方向キー数") - Spacer() - IntegerTextField("横方向キー数", text: $editingItem.rowCount, range: 1 ... .max) - .keyboardType(.numberPad) - .textFieldStyle(.roundedBorder) - .submitLabel(.done) - } - Picker("言語", selection: $editingItem.language) { - Text("なし").tag(CustardLanguage.none) - Text("日本語").tag(CustardLanguage.ja_JP) - Text("英語").tag(CustardLanguage.en_US) + Form { + TextField("タブの名前", text: $editingItem.tabName) + .textFieldStyle(.roundedBorder) + .submitLabel(.done) + Button("プレビュー") { + showPreview = true + UIApplication.shared.closeKeyboard() + } + HStack { + Text("縦方向キー数") + Spacer() + IntegerTextField("縦方向キー数", text: $editingItem.columnCount, range: 1 ... .max) + .keyboardType(.numberPad) + .textFieldStyle(.roundedBorder) + .submitLabel(.done) + } + HStack { + Text("横方向キー数") + Spacer() + IntegerTextField("横方向キー数", text: $editingItem.rowCount, range: 1 ... .max) + .keyboardType(.numberPad) + .textFieldStyle(.roundedBorder) + .submitLabel(.done) + } + Picker("言語", selection: $editingItem.language) { + Text("なし").tag(CustardLanguage.none) + Text("日本語").tag(CustardLanguage.ja_JP) + Text("英語").tag(CustardLanguage.en_US) + } + Picker("入力方式", selection: $editingItem.inputStyle) { + Text("そのまま入力").tag(CustardInputStyle.direct) + Text("ローマ字かな入力").tag(CustardInputStyle.roman2kana) + } + Toggle("自動的にタブバーに追加", isOn: $editingItem.addTabBarAutomatically) + } + HStack { + Spacer() + if showPreview { + Button("閉じる", systemImage: "xmark.circle") { + showPreview = false + } + } else { + Button("プレビュー", systemImage: "eye") { + showPreview = true + } + } + } + .labelStyle(.iconOnly) + .font(.title) + .padding(.horizontal, 8) + if !showPreview { + CustardFlickKeysView(models: models, tabDesign: .init(width: layout.rowCount, height: layout.columnCount, interfaceSize: interfaceSize, orientation: MainAppDesign.keyboardOrientation), layout: layout) {(view: FlickKeyView, x: Int, y: Int) in + if editingItem.emptyKeys.contains(.gridFit(x: x, y: y)) { + if !isCovered(at: (x, y)) { + Button { + editingItem.emptyKeys.remove(.gridFit(x: x, y: y)) + } label: { + view.disabled(true) + .opacity(0) + .overlay( + Rectangle().stroke(style: .init(lineWidth: 2, dash: [5])) + ) + .overlay( + Image(systemName: "plus.circle") + .foregroundStyle(.accentColor) + ) + } } - Picker("入力方式", selection: $editingItem.inputStyle) { - Text("そのまま入力").tag(CustardInputStyle.direct) - Text("ローマ字かな入力").tag(CustardInputStyle.roman2kana) + } else { + NavigationLink(destination: CustardInterfaceKeyEditor(data: $editingItem.keys[.gridFit(x: x, y: y)])) { + view.disabled(true) + .border(Color.primary) } - Toggle("自動的にタブバーに追加", isOn: $editingItem.addTabBarAutomatically) - } - HStack { - Spacer() - if showPreview { - Button("閉じる", systemImage: "xmark.circle") { - showPreview = false + .contextMenu { + // TODO: これ、OSのクリップボード使ったほうがいいのかも + // TODO: Swap、DuplicateみたいなAPIも追加したい + Button("コピーする", systemImage: "doc.on.doc") { + copiedKey = editingItem.keys[.gridFit(x: x, y: y)] } - } else { - Button("プレビュー", systemImage: "eye") { - showPreview = true + Button("ペーストする", systemImage: "doc.on.clipboard") { + if let copiedKey { + editingItem.keys[.gridFit(x: x, y: y)] = copiedKey + } } - } - } - .labelStyle(.iconOnly) - .font(.title) - .padding(.horizontal, 8) - if !showPreview { - CustardFlickKeysView(models: models, tabDesign: .init(width: layout.rowCount, height: layout.columnCount, interfaceSize: interfaceSize, orientation: MainAppDesign.keyboardOrientation), layout: layout) {(view: FlickKeyView, x: Int, y: Int) in - if editingItem.emptyKeys.contains(.gridFit(x: x, y: y)) { - if !isCovered(at: (x, y)) { - Button { - editingItem.emptyKeys.remove(.gridFit(x: x, y: y)) - } label: { - view.disabled(true) - .opacity(0) - .overlay( - Rectangle().stroke(style: .init(lineWidth: 2, dash: [5])) - ) - .overlay( - Image(systemName: "plus.circle") - .foregroundStyle(.accentColor) - ) + .disabled(copiedKey == nil) + Button("下に行を追加", systemImage: "plus") { + editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount + for px in 0 ..< Int(layout.rowCount) { + for py in (y + 1 ..< Int(layout.columnCount)).reversed() { + editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] } } - } else { - NavigationLink(destination: CustardInterfaceKeyEditor(data: $editingItem.keys[.gridFit(x: x, y: y)])) { - view.disabled(true) - .border(Color.primary) + for px in 0 ..< Int(layout.rowCount) { + editingItem.keys[.gridFit(x: px, y: y + 1)] = nil } - .contextMenu { - // TODO: これ、OSのクリップボード使ったほうがいいのかも - // TODO: Swap、DuplicateみたいなAPIも追加したい - Button { - copiedKey = editingItem.keys[.gridFit(x: x, y: y)] - } label: { - Label("コピーする", systemImage: "doc.on.doc") - } - Button { - if let copiedKey { - editingItem.keys[.gridFit(x: x, y: y)] = copiedKey - } - } label: { - Label("ペーストする", systemImage: "doc.on.clipboard") - } - .disabled(copiedKey == nil) - Button { - editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount - for px in 0 ..< Int(layout.rowCount) { - for py in (y + 1 ..< Int(layout.columnCount)).reversed() { - editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] - } - } - for px in 0 ..< Int(layout.rowCount) { - editingItem.keys[.gridFit(x: px, y: y + 1)] = nil - } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where y + 1 <= py: - return .gridFit(x: px, y: py + 1) - default: - return item - } - } - } label: { - Label("下に行を追加", systemImage: "plus") + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where y + 1 <= py: + return .gridFit(x: px, y: py + 1) + default: + return item } - Button { - editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount - for px in 0 ..< Int(layout.rowCount) { - for py in (y ..< Int(layout.columnCount)).reversed() { - editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] - } - } - for px in 0 ..< Int(layout.rowCount) { - editingItem.keys[.gridFit(x: px, y: y)] = nil - } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where y <= py: - return .gridFit(x: px, y: py + 1) - default: - return item - } - } - } label: { - Label("上に行を追加", systemImage: "plus") + } + } + Button("上に行を追加", systemImage: "plus") { + editingItem.columnCount = Int(editingItem.columnCount)?.advanced(by: 1).description ?? editingItem.columnCount + for px in 0 ..< Int(layout.rowCount) { + for py in (y ..< Int(layout.columnCount)).reversed() { + editingItem.keys[.gridFit(x: px, y: py + 1)] = editingItem.keys[.gridFit(x: px, y: py)] } - Button { - editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount - for px in (x + 1 ..< Int(layout.rowCount)).reversed() { - for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] - } - } - for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: x + 1, y: py)] = nil - } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where x + 1 <= px: - return .gridFit(x: px + 1, y: py) - default: - return item - } - } - } label: { - Label("右に列を追加", systemImage: "plus") + } + for px in 0 ..< Int(layout.rowCount) { + editingItem.keys[.gridFit(x: px, y: y)] = nil + } + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where y <= py: + return .gridFit(x: px, y: py + 1) + default: + return item } - Button { - editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount - for px in (x ..< Int(layout.rowCount)).reversed() { - for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] - } - } - for py in 0 ..< Int(layout.columnCount) { - editingItem.keys[.gridFit(x: x, y: py)] = nil - } - editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in - switch item { - case .gridFit(x: let px, y: let py) where x <= px: - return .gridFit(x: px + 1, y: py) - default: - return item - } - } - } label: { - Label("左に列を追加", systemImage: "plus") - + } + } + Button("右に列を追加", systemImage: "plus") { + editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount + for px in (x + 1 ..< Int(layout.rowCount)).reversed() { + for py in 0 ..< Int(layout.columnCount) { + editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] } - Divider() - Button(role: .destructive) { - editingItem.emptyKeys.insert(.gridFit(x: x, y: y)) - } label: { - Label("削除する", systemImage: "trash") - .foregroundStyle(.red) + } + for py in 0 ..< Int(layout.columnCount) { + editingItem.keys[.gridFit(x: x + 1, y: py)] = nil + } + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where x + 1 <= px: + return .gridFit(x: px + 1, y: py) + default: + return item } - Button(role: .destructive) { - removeRow(y: y) - } label: { - Label("この行を削除", systemImage: "trash") - .foregroundStyle(.red) + } + } + Button("左に列を追加", systemImage: "plus") { + editingItem.rowCount = Int(editingItem.rowCount)?.advanced(by: 1).description ?? editingItem.rowCount + for px in (x ..< Int(layout.rowCount)).reversed() { + for py in 0 ..< Int(layout.columnCount) { + editingItem.keys[.gridFit(x: px + 1, y: py)] = editingItem.keys[.gridFit(x: px, y: py)] } - Button(role: .destructive) { - removeColumn(x: x) - } label: { - Label("この列を削除", systemImage: "trash") - .foregroundStyle(.red) + } + for py in 0 ..< Int(layout.columnCount) { + editingItem.keys[.gridFit(x: x, y: py)] = nil + } + editingItem.emptyKeys = editingItem.emptyKeys.mapSet { item in + switch item { + case .gridFit(x: let px, y: let py) where x <= px: + return .gridFit(x: px + 1, y: py) + default: + return item } } } + Divider() + Button("削除する", systemImage: "trash", role: .destructive) { + editingItem.emptyKeys.insert(.gridFit(x: x, y: y)) + } + Button("この行を削除", systemImage: "trash", role: .destructive) { + removeRow(y: y) + } + Button("この列を削除", systemImage: "trash", role: .destructive) { + removeColumn(x: x) + } } - .environmentObject(variableStates) - } else { - KeyboardPreview(defaultTab: .custard(custard)) } } + .environmentObject(variableStates) + } else { + KeyboardPreview(defaultTab: .custard(custard)) } - .onChange(of: layout) {_ in - updateModel() + } + .onChange(of: layout) {_ in + updateModel() + } + .background(Color.secondarySystemBackground) + .navigationBarBackButtonHidden(true) + .navigationTitle(Text("カスタムタブを作る")) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button("キャンセル", role: .cancel, action: {self.cancel()}) } - .background(Color.secondarySystemBackground) - .navigationBarBackButtonHidden(true) - .navigationTitle(Text("カスタムタブを作る")) - .navigationBarItems( - leading: Button("キャンセル", role: .cancel, action: {self.cancel()}), - trailing: Button("保存") { + ToolbarItem(placement: .topBarTrailing) { + Button("保存") { self.save() self.dismiss() } - ) + } } .onAppear { variableStates.setInterfaceSize(orientation: MainAppDesign.keyboardOrientation, screenWidth: SemiStaticStates.shared.screenWidth) From 2982236a5c3cf6972bd9681fed3c6d8b7a2bd030 Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sun, 5 Nov 2023 16:31:34 +0900 Subject: [PATCH 03/13] Update for consistency --- .../Customize/EditingScrollCustardView.swift | 125 ++++++++++-------- 1 file changed, 68 insertions(+), 57 deletions(-) diff --git a/MainApp/Customize/EditingScrollCustardView.swift b/MainApp/Customize/EditingScrollCustardView.swift index 02da40e7..40d7eb89 100644 --- a/MainApp/Customize/EditingScrollCustardView.swift +++ b/MainApp/Customize/EditingScrollCustardView.swift @@ -18,9 +18,9 @@ fileprivate extension CustardInterfaceLayoutScrollValue.ScrollDirection { var label: LocalizedStringKey { switch self { case .vertical: - return "縦" + "縦" case .horizontal: - return "横" + "横" } } } @@ -49,70 +49,81 @@ struct EditingScrollCustardView: CancelableEditor { var body: some View { VStack { - GeometryReader {geometry in - VStack { - Form { - TextField("タブの名前", text: $editingItem.tabName) - .submitLabel(.done) - Text("一行ずつ登録したい文字や単語を入力してください") - Button("プレビュー") { - UIApplication.shared.closeKeyboard() - showPreview = true - } - DisclosureGroup("詳細設定") { - HStack { - Text("スクロール方向") - Spacer() - Picker("スクロール方向", selection: $editingItem.direction) { - Text("縦").tag(CustardInterfaceLayoutScrollValue.ScrollDirection.vertical) - Text("横").tag(CustardInterfaceLayoutScrollValue.ScrollDirection.horizontal) - } - .pickerStyle(.segmented) - } - HStack { - Text("縦方向キー数") - Spacer() - IntegerTextField("縦方向キー数", text: $editingItem.columnCount, range: 1 ... .max) - .keyboardType(.numberPad) - .textFieldStyle(.roundedBorder) - .submitLabel(.done) - } - HStack { - Text("横方向キー数") - Spacer() - IntegerTextField("横方向キー数", text: $editingItem.rowCount, range: 1 ... .max) - .keyboardType(.numberPad) - .textFieldStyle(.roundedBorder) - .submitLabel(.done) - } - Toggle("自動的にタブバーに追加", isOn: $editingItem.addTabBarAutomatically) + Form { + TextField("タブの名前", text: $editingItem.tabName) + .submitLabel(.done) + Button("プレビュー") { + UIApplication.shared.closeKeyboard() + showPreview = true + } + DisclosureGroup("詳細設定") { + HStack { + Text("スクロール方向") + Spacer() + Picker("スクロール方向", selection: $editingItem.direction) { + Text("縦").tag(CustardInterfaceLayoutScrollValue.ScrollDirection.vertical) + Text("横").tag(CustardInterfaceLayoutScrollValue.ScrollDirection.horizontal) } + .pickerStyle(.segmented) } - .frame(height: geometry.size.height * 0.4) - - TextEditor(text: $editingItem.words) - .frame(height: geometry.size.height * 0.6) - + HStack { + Text("縦方向キー数") + Spacer() + IntegerTextField("縦方向キー数", text: $editingItem.columnCount, range: 1 ... .max) + .keyboardType(.numberPad) + .textFieldStyle(.roundedBorder) + .submitLabel(.done) + } + HStack { + Text("横方向キー数") + Spacer() + IntegerTextField("横方向キー数", text: $editingItem.rowCount, range: 1 ... .max) + .keyboardType(.numberPad) + .textFieldStyle(.roundedBorder) + .submitLabel(.done) + } + Toggle("自動的にタブバーに追加", isOn: $editingItem.addTabBarAutomatically) } - BottomSheetView( - isOpen: $showPreview, - maxHeight: Design.keyboardScreenHeight(upsideComponent: nil, orientation: MainAppDesign.keyboardOrientation) + 40, - minHeight: 0 - ) { - KeyboardPreview(defaultTab: .custard(makeCustard(data: editingItem))) + } + HStack { + Text("一行ずつ登録したい文字や単語を入力してください") + Spacer() + if showPreview { + Button("閉じる", systemImage: "xmark.circle") { + showPreview = false + } + .font(.title) + } else { + Button("プレビュー", systemImage: "eye") { + showPreview = true + } + .font(.title) } } + .labelStyle(.iconOnly) + .padding(.horizontal, 8) + if showPreview { + KeyboardPreview(defaultTab: .custard(makeCustard(data: editingItem))) + } else { + TextEditor(text: $editingItem.words) + .frame(maxHeight: .infinity) + } } .background(Color.secondarySystemBackground) .navigationBarBackButtonHidden(true) - .navigationBarTitle(Text("カスタムタブを作る"), displayMode: .inline) - .navigationBarItems( - leading: Button("キャンセル", action: cancel), - trailing: Button("保存") { - self.save() - self.dismiss() + .navigationTitle(Text("カスタムタブを作る")) + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button("キャンセル", role: .cancel, action: {self.cancel()}) } - ) + ToolbarItem(placement: .topBarTrailing) { + Button("保存") { + self.save() + self.dismiss() + } + } + } } private func makeCustard(data: UserMadeGridScrollCustard) -> Custard { From 4b13e7fb64fe27fc11c48324557ce1e6ae18b18d Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Thu, 9 Nov 2023 18:36:30 +0900 Subject: [PATCH 04/13] =?UTF-8?q?=E6=88=BB=E3=82=8B=E3=83=9C=E3=82=BF?= =?UTF-8?q?=E3=83=B3=E3=82=92=E5=A4=A7=E3=81=8D=E3=81=8F=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/KeyboardViews/View/SpecialTabs/EmojiTab.swift | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/AzooKeyCore/Sources/KeyboardViews/View/SpecialTabs/EmojiTab.swift b/AzooKeyCore/Sources/KeyboardViews/View/SpecialTabs/EmojiTab.swift index 3d9226ca..975a0b2a 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/SpecialTabs/EmojiTab.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/SpecialTabs/EmojiTab.swift @@ -275,12 +275,8 @@ struct EmojiTab: View { }), width: functionKeyWidth, height: footerHeight) } - private func tabBarKey() -> SimpleKeyView { - SimpleKeyView(model: SimpleKeyModel(keyLabelType: .image("list.bullet"), unpressedKeyColorType: .special, pressActions: [.setTabBar(.toggle)], longPressActions: .none), width: functionKeyWidth, height: footerHeight) - } - private func backTabKey() -> SimpleKeyView { - SimpleKeyView(model: SimpleKeyModel(keyLabelType: .image("arrow.uturn.backward"), unpressedKeyColorType: .special, pressActions: [.moveTab(.system(.last_tab))], longPressActions: .none), width: functionKeyWidth, height: footerHeight) + SimpleKeyView(model: SimpleKeyModel(keyLabelType: .text("戻る"), unpressedKeyColorType: .special, pressActions: [.moveTab(.system(.last_tab))], longPressActions: .none), width: functionKeyWidth * 2, height: footerHeight) } private func genreKey(_ genre: Genre) -> some View { @@ -334,7 +330,6 @@ struct EmojiTab: View { HStack(spacing: 0) { backTabKey() - tabBarKey() ForEach(allGenre, id: \.self) { genre in if !self.emojis[genre, default: []].isEmpty { genreKey(genre) From e84b6933c850f96137843fcfa4a1673be9a3e6eb Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Fri, 10 Nov 2023 23:25:50 +0900 Subject: [PATCH 05/13] Add 'Next Candidate' option --- .../AzooKeyKeyboardViewExtension.swift | 4 +++ .../KeyboardSetting/BoolKeyboardSetting.swift | 11 +++++++ ...nSpecificKeyboardViewSettingProvider.swift | 1 + .../FlickKeyboard/FlickDataProvider.swift | 29 +++++++++---------- .../KeyView/FlickNextCandidateKeyModel.swift | 17 ++++++++--- .../View/KeyboardBar/ResultBar.swift | 2 +- .../QwertyKeyboard/QwertyDataProvider.swift | 12 +++++--- MainApp/Setting/SettingTab.swift | 18 +++++++++--- Resources/Localizable.xcstrings | 22 ++++++++++++++ 9 files changed, 87 insertions(+), 29 deletions(-) diff --git a/AzooKeyCore/Sources/AzooKeyUtils/AzooKeyKeyboardViewExtension.swift b/AzooKeyCore/Sources/AzooKeyUtils/AzooKeyKeyboardViewExtension.swift index 39d77a4c..a6a6e562 100644 --- a/AzooKeyCore/Sources/AzooKeyUtils/AzooKeyKeyboardViewExtension.swift +++ b/AzooKeyCore/Sources/AzooKeyUtils/AzooKeyKeyboardViewExtension.swift @@ -98,6 +98,10 @@ public enum AzooKeyKeyboardViewExtension: ApplicationSpecificKeyboardViewExtensi UseShiftKey.value } + public static var useNextCandidateKey: Bool { + UseNextCandidateKey.value + } + public static var displayCursorBarAutomatically: Bool { DisplayCursorBarAutomatically.value } diff --git a/AzooKeyCore/Sources/AzooKeyUtils/KeyboardSetting/BoolKeyboardSetting.swift b/AzooKeyCore/Sources/AzooKeyUtils/KeyboardSetting/BoolKeyboardSetting.swift index d1794bb2..edba3133 100644 --- a/AzooKeyCore/Sources/AzooKeyUtils/KeyboardSetting/BoolKeyboardSetting.swift +++ b/AzooKeyCore/Sources/AzooKeyUtils/KeyboardSetting/BoolKeyboardSetting.swift @@ -201,6 +201,17 @@ public extension KeyboardSettingKey where Self == UseShiftKey { static var useShiftKey: Self { .init() } } +public struct UseNextCandidateKey: BoolKeyboardSettingKey { + public static let title: LocalizedStringKey = "次候補キーを使う" + public static let explanation: LocalizedStringKey = "キーボードで入力中、空白キーに「次候補」機能を表示します" + public static let defaultValue = false + public static let key: String = "use_next_candidate_key" +} + +public extension KeyboardSettingKey where Self == UseNextCandidateKey { + static var useNextCandidateKey: Self { .init() } +} + public struct HideResetButtonInOneHandedMode: BoolKeyboardSettingKey { public static let title: LocalizedStringKey = "片手モードで解除ボタンを表示しない" public static let explanation: LocalizedStringKey = "片手モードの際に表示される解除ボタンを非表示にします。片手モードの調整はタブバーのボタンから行えます。" diff --git a/AzooKeyCore/Sources/KeyboardViews/ApplicationSpecificKeyboardViewSettingProvider.swift b/AzooKeyCore/Sources/KeyboardViews/ApplicationSpecificKeyboardViewSettingProvider.swift index 11ed50a4..874d061c 100644 --- a/AzooKeyCore/Sources/KeyboardViews/ApplicationSpecificKeyboardViewSettingProvider.swift +++ b/AzooKeyCore/Sources/KeyboardViews/ApplicationSpecificKeyboardViewSettingProvider.swift @@ -30,6 +30,7 @@ import Foundation static var enablePasteButton: Bool { get } static var hideResetButtonInOneHandedMode: Bool { get } static var useShiftKey: Bool { get } + static var useNextCandidateKey: Bool { get } /// タブバーボタンを表示する /// - note: このオプションは一度削除を決めたが、ユーザから強い要望があったので維持することにした。 diff --git a/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/FlickDataProvider.swift b/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/FlickDataProvider.swift index 49bc8df7..47470403 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/FlickDataProvider.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/FlickDataProvider.swift @@ -15,6 +15,16 @@ struct FlickDataProvider { Extension.SettingProvider.preferredLanguage } + // 第5列 + @MainActor static func functionalKeys() -> [any FlickKeyModelProtocol] { + return [ + FlickKeyModel.delete, + Extension.SettingProvider.useNextCandidateKey ? FlickNextCandidateKeyModel.shared : FlickSpaceKeyModel.shared, + FlickEnterKeyModel.shared + ] + } + + // 第1列 @MainActor static func TabKeys() -> [any FlickKeyModelProtocol] { let first: any FlickKeyModelProtocol = { switch preferredLanguage.first { @@ -262,12 +272,7 @@ struct FlickDataProvider { FlickKanaSymbolsKeyModel.shared ], // 第5列 - [ - FlickKeyModel.delete, - FlickSpaceKeyModel.shared, - FlickEnterKeyModel.shared - ] - + Self.functionalKeys() ] } @@ -426,11 +431,7 @@ struct FlickDataProvider { ]) ], // 第5列 - [ - FlickKeyModel.delete, - FlickSpaceKeyModel.shared, - FlickEnterKeyModel.shared - ] + Self.functionalKeys() ] } // 縦に並べる @@ -617,11 +618,7 @@ struct FlickDataProvider { ]) ], // 第5列 - [ - FlickKeyModel.delete, - FlickSpaceKeyModel.shared, - FlickEnterKeyModel.shared - ] + Self.functionalKeys() ] } diff --git a/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/KeyView/FlickNextCandidateKeyModel.swift b/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/KeyView/FlickNextCandidateKeyModel.swift index 44e21300..59dd8181 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/KeyView/FlickNextCandidateKeyModel.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/FlickKeyboard/KeyView/FlickNextCandidateKeyModel.swift @@ -26,16 +26,25 @@ struct FlickNextCandidateKeyModel [CustardKit.FlickDirection: FlickedKeyModel] { - [ - .left: FlickedKeyModel( + let leftFlickKey = if variableStates.resultModel.selection != nil { + FlickedKeyModel( + labelType: .text("前候補"), + pressActions: [.selectCandidate(.offset(-1))], + longPressActions: .init(repeat: [.selectCandidate(.offset(-1))]) + ) + } else { + FlickedKeyModel( labelType: .text("←"), pressActions: [.moveCursor(-1)], longPressActions: .init(repeat: [.moveCursor(-1)]) - ), + ) + } + return [ + .left: leftFlickKey, .top: FlickedKeyModel( labelType: .text("全角"), pressActions: [.input(" ")] diff --git a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift index af35e3de..f3471ddf 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift @@ -121,7 +121,7 @@ struct ResultBar: View { .onChange(of: variableStates.resultModel.selection) { value in if let value { withAnimation(.easeIn(duration: 0.05)) { - scrollViewProxy.scrollTo(value, anchor: .trailing) + scrollViewProxy.scrollTo(value, anchor: .center) } } } diff --git a/AzooKeyCore/Sources/KeyboardViews/View/QwertyKeyboard/QwertyDataProvider.swift b/AzooKeyCore/Sources/KeyboardViews/View/QwertyKeyboard/QwertyDataProvider.swift index 6106d9d7..cdd5d10a 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/QwertyKeyboard/QwertyDataProvider.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/QwertyKeyboard/QwertyDataProvider.swift @@ -47,6 +47,10 @@ struct QwertyDataProvider { ) } + @MainActor static func spaceKey() -> any QwertyKeyModelProtocol { + Extension.SettingProvider.useNextCandidateKey ? QwertyNextCandidateKeyModel() : QwertySpaceKeyModel() + } + // 横に並べる @MainActor static var numberKeyboard: [[any QwertyKeyModelProtocol]] {[ [ @@ -240,7 +244,7 @@ struct QwertyDataProvider { [ Self.tabKeys(rowInfo: (0, 2, 1, 1)).languageKey, Self.tabKeys(rowInfo: (0, 2, 1, 1)).changeKeyboardKey, - QwertyNextCandidateKeyModel(), + Self.spaceKey(), QwertyEnterKeyModel.shared ] ] @@ -462,7 +466,7 @@ struct QwertyDataProvider { [ Self.tabKeys(rowInfo: (0, 2, 1, 1)).languageKey, Self.tabKeys(rowInfo: (0, 2, 1, 1)).changeKeyboardKey, - QwertyNextCandidateKeyModel(), + Self.spaceKey(), QwertyEnterKeyModel.shared ] ]} @@ -507,7 +511,7 @@ struct QwertyDataProvider { [ Self.tabKeys(rowInfo: (0, 2, 1, 1)).numbersKey, Self.tabKeys(rowInfo: (0, 2, 1, 1)).changeKeyboardKey, - QwertyNextCandidateKeyModel(), + Self.spaceKey(), QwertyEnterKeyModel.shared ] ]} @@ -564,7 +568,7 @@ struct QwertyDataProvider { [ Self.tabKeys(rowInfo: (0, 2, 1, 1)).numbersKey, Self.tabKeys(rowInfo: (0, 2, 1, 1)).changeKeyboardKey, - QwertyNextCandidateKeyModel(), + Self.spaceKey(), QwertyEnterKeyModel.shared ] ]} diff --git a/MainApp/Setting/SettingTab.swift b/MainApp/Setting/SettingTab.swift index bccc8ae4..edc82e30 100644 --- a/MainApp/Setting/SettingTab.swift +++ b/MainApp/Setting/SettingTab.swift @@ -30,6 +30,13 @@ struct SettingTabView: View { return false } + private func isCustard(_ layout: LanguageLayout) -> Bool { + if case .custard = layout { + return true + } + return false + } + var body: some View { NavigationView { Form { @@ -44,8 +51,14 @@ struct SettingTabView: View { } Group { - Section(header: Text("カスタムキー")) { + Section("カスタムキー") { CustomKeysSettingView() + if !self.isCustard(appStates.japaneseLayout) || !self.isCustard(appStates.englishLayout) { + BoolSettingView(.useNextCandidateKey) + } + if self.canQwertyLayout(appStates.englishLayout) { + BoolSettingView(.useShiftKey) + } if !SemiStaticStates.shared.needsInputModeSwitchKey, self.canFlickLayout(appStates.japaneseLayout) { BoolSettingView(.enablePasteButton) } @@ -80,9 +93,6 @@ struct SettingTabView: View { if self.canFlickLayout(appStates.japaneseLayout) { FlickSensitivitySettingView(.flickSensitivity) } - if self.canQwertyLayout(appStates.englishLayout) { - BoolSettingView(.useShiftKey) - } } } Group { diff --git a/Resources/Localizable.xcstrings b/Resources/Localizable.xcstrings index dd17c5f1..bfbea330 100644 --- a/Resources/Localizable.xcstrings +++ b/Resources/Localizable.xcstrings @@ -2462,6 +2462,17 @@ } } }, + "キーボードで入力中、空白キーに「次候補」機能を表示します" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "While composing, the space key will change into the 'Next Candidate' key" + } + } + } + }, "キーボードの入力方式" : { "localizations" : { "en" : { @@ -7891,6 +7902,17 @@ } } }, + "次候補キーを使う" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Use 'Next Candidate' Key" + } + } + } + }, "正しくない形式のファイルです" : { "localizations" : { "en" : { From 83ecd3022400304efa4136d65b5d167ac81e55bb Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Fri, 10 Nov 2023 23:36:23 +0900 Subject: [PATCH 06/13] clean up --- MainApp/Setting/SettingTab.swift | 148 ++++++++++++++----------------- 1 file changed, 69 insertions(+), 79 deletions(-) diff --git a/MainApp/Setting/SettingTab.swift b/MainApp/Setting/SettingTab.swift index edc82e30..f196b730 100644 --- a/MainApp/Setting/SettingTab.swift +++ b/MainApp/Setting/SettingTab.swift @@ -40,101 +40,90 @@ struct SettingTabView: View { var body: some View { NavigationView { Form { - Group { - Section(header: Text("キーボードの種類")) { - NavigationLink("キーボードの種類を設定する", destination: KeyboardLayoutTypeDetailsView()) - } + Section("キーボードの種類") { + NavigationLink("キーボードの種類を設定する", destination: KeyboardLayoutTypeDetailsView()) } - Section(header: Text("ライブ変換")) { + Section("ライブ変換") { BoolSettingView(.liveConversion) NavigationLink("詳しい設定", destination: LiveConversionSettingView()) } - - Group { - Section("カスタムキー") { - CustomKeysSettingView() - if !self.isCustard(appStates.japaneseLayout) || !self.isCustard(appStates.englishLayout) { - BoolSettingView(.useNextCandidateKey) - } - if self.canQwertyLayout(appStates.englishLayout) { - BoolSettingView(.useShiftKey) - } - if !SemiStaticStates.shared.needsInputModeSwitchKey, self.canFlickLayout(appStates.japaneseLayout) { - BoolSettingView(.enablePasteButton) - } - } - Section(header: Text("バー")) { - BoolSettingView(.useReflectStyleCursorBar) - BoolSettingView(.displayTabBarButton) - BoolSettingView(.enableClipboardHistoryManagerTab) - if SemiStaticStates.shared.hasFullAccess { - NavigationLink("「ペーストを許可」のダイアログについて", destination: PasteFromOtherAppsPermissionTipsView()) - } - NavigationLink("タブバーを編集", destination: EditingTabBarView(manager: $appStates.custardManager)) + Section("カスタムキー") { + CustomKeysSettingView() + if !self.isCustard(appStates.japaneseLayout) || !self.isCustard(appStates.englishLayout) { + BoolSettingView(.useNextCandidateKey) } - // デバイスが触覚フィードバックをサポートしている場合のみ表示する - if SemiStaticStates.shared.hapticsAvailable { - Section(header: Text("サウンドと振動")) { - BoolSettingView(.enableKeySound) - BoolSettingView(.enableKeyHaptics) - } - } else { - Section(header: Text("サウンド")) { - BoolSettingView(.enableKeySound) - } + if self.canQwertyLayout(appStates.englishLayout) { + BoolSettingView(.useShiftKey) } - Section(header: Text("表示")) { - KeyboardHeightSettingView(.keyboardHeightScale) - FontSizeSettingView(.keyViewFontSize, .key, availableValueRange: 15 ... 28) - FontSizeSettingView(.resultViewFontSize, .result, availableValueRange: 12...24) - } - Section(header: Text("操作性")) { - BoolSettingView(.hideResetButtonInOneHandedMode) - if self.canFlickLayout(appStates.japaneseLayout) { - FlickSensitivitySettingView(.flickSensitivity) - } + if !SemiStaticStates.shared.needsInputModeSwitchKey, self.canFlickLayout(appStates.japaneseLayout) { + BoolSettingView(.enablePasteButton) } } - Group { - Section(header: Text("変換")) { - BoolSettingView(.englishCandidate) - BoolSettingView(.halfKanaCandidate) - BoolSettingView(.fullRomanCandidate) - BoolSettingView(.typographyLetter) - BoolSettingView(.unicodeCandidate) - MarkedTextSettingView(.markedTextSetting) - ContactImportSettingView() - NavigationLink("絵文字と顔文字", destination: AdditionalDictManageView()) - } - - Section(header: Text("言語")) { - PreferredLanguageSettingView() + Section("バー") { + BoolSettingView(.useReflectStyleCursorBar) + BoolSettingView(.displayTabBarButton) + BoolSettingView(.enableClipboardHistoryManagerTab) + if SemiStaticStates.shared.hasFullAccess { + NavigationLink("「ペーストを許可」のダイアログについて", destination: PasteFromOtherAppsPermissionTipsView()) } - - Section(header: Text("ユーザ辞書")) { - BoolSettingView(.useOSUserDict) - NavigationLink("azooKeyユーザ辞書", destination: AzooKeyUserDictionaryView()) + NavigationLink("タブバーを編集", destination: EditingTabBarView(manager: $appStates.custardManager)) + } + // デバイスが触覚フィードバックをサポートしている場合のみ表示する + if SemiStaticStates.shared.hapticsAvailable { + Section("サウンドと振動") { + BoolSettingView(.enableKeySound) + BoolSettingView(.enableKeyHaptics) } - - Section(header: Text("テンプレート")) { - NavigationLink("テンプレートの管理", destination: TemplateListView()) - } - - Section(header: Text("学習機能")) { - LearningTypeSettingView() - MemoryResetSettingItemView() + } else { + Section("サウンド") { + BoolSettingView(.enableKeySound) } + } + Section("表示") { + KeyboardHeightSettingView(.keyboardHeightScale) + FontSizeSettingView(.keyViewFontSize, .key, availableValueRange: 15 ... 28) + FontSizeSettingView(.resultViewFontSize, .result, availableValueRange: 12...24) + } - Section(header: Text("カスタムタブ")) { - NavigationLink("カスタムタブの管理", destination: ManageCustardView(manager: $appStates.custardManager)) + Section("操作性") { + BoolSettingView(.hideResetButtonInOneHandedMode) + if self.canFlickLayout(appStates.japaneseLayout) { + FlickSensitivitySettingView(.flickSensitivity) } } - Section(header: Text("オープンソースソフトウェア")) { + Section("変換") { + BoolSettingView(.englishCandidate) + BoolSettingView(.halfKanaCandidate) + BoolSettingView(.fullRomanCandidate) + BoolSettingView(.typographyLetter) + BoolSettingView(.unicodeCandidate) + MarkedTextSettingView(.markedTextSetting) + ContactImportSettingView() + NavigationLink("絵文字と顔文字", destination: AdditionalDictManageView()) + } + Section("言語") { + PreferredLanguageSettingView() + } + Section("ユーザ辞書") { + BoolSettingView(.useOSUserDict) + NavigationLink("azooKeyユーザ辞書", destination: AzooKeyUserDictionaryView()) + } + Section("テンプレート") { + NavigationLink("テンプレートの管理", destination: TemplateListView()) + } + Section("学習機能") { + LearningTypeSettingView() + MemoryResetSettingItemView() + } + Section("カスタムタブ") { + NavigationLink("カスタムタブの管理", destination: ManageCustardView(manager: $appStates.custardManager)) + } + Section("オープンソースソフトウェア") { Text("azooKeyはオープンソースソフトウェアであり、GitHubでソースコードを公開しています。") FallbackLink("View azooKey on GitHub", destination: URL(string: "https://github.com/ensan-hcl/azooKey")!) NavigationLink("Acknowledgements", destination: OpenSourceSoftwaresLicenseView()) } - Section(header: Text("このアプリについて")) { + Section("このアプリについて") { NavigationLink("お問い合わせ", destination: ContactView()) FallbackLink("プライバシーポリシー", destination: URL(string: "https://azookey.netlify.app/PrivacyPolicy")!) .foregroundStyle(.primary) @@ -149,11 +138,12 @@ struct SettingTabView: View { HStack { Text("バージョン") Spacer() - Text(SharedStore.currentAppVersion?.description ?? "取得中です") + Text(verbatim: SharedStore.currentAppVersion?.description ?? "取得中です") } } } - .navigationBarTitle(Text("設定"), displayMode: .large) + .navigationTitle("設定") + .navigationBarTitleDisplayMode(.large) .onAppear { if appStates.requestReviewManager.shouldTryRequestReview, appStates.requestReviewManager.shouldRequestReview() { if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene { From 6e8ccac89bbb3b5719e8a509658035b389226a21 Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sat, 11 Nov 2023 01:35:05 +0900 Subject: [PATCH 07/13] Add 'news' section to the home tab and improve design --- MainApp/General/IconNavigationLink.swift | 37 ++++++++ .../DynamicTypeSettingFailureTips.swift | 26 ----- MainApp/Tips/News/TipsNewsSection.swift | 63 +++++++++++++ .../Tips/News/UseContactInfoSettingNews.swift | 32 +++++++ .../Tips/News/UseNextCandidateKeyNews.swift | 20 ++++ MainApp/Tips/News/UseShiftKeyNews.swift | 20 ++++ MainApp/Tips/TipsView.swift | 41 +++----- Resources/Localizable.xcstrings | 94 +++++++++++++++++++ azooKey.xcodeproj/project.pbxproj | 32 ++++++- 9 files changed, 308 insertions(+), 57 deletions(-) create mode 100644 MainApp/General/IconNavigationLink.swift delete mode 100644 MainApp/Tips/Articles/DynamicTypeSettingFailureTips.swift create mode 100644 MainApp/Tips/News/TipsNewsSection.swift create mode 100644 MainApp/Tips/News/UseContactInfoSettingNews.swift create mode 100644 MainApp/Tips/News/UseNextCandidateKeyNews.swift create mode 100644 MainApp/Tips/News/UseShiftKeyNews.swift diff --git a/MainApp/General/IconNavigationLink.swift b/MainApp/General/IconNavigationLink.swift new file mode 100644 index 00000000..e5a9cf56 --- /dev/null +++ b/MainApp/General/IconNavigationLink.swift @@ -0,0 +1,37 @@ +// +// IconNavigationLink.swift +// azooKey +// +// Created by miwa on 2023/11/11. +// Copyright © 2023 DevEn3. All rights reserved. +// + +import SwiftUI + +struct IconNavigationLink: View { + init(_ titleKey: LocalizedStringKey, systemImage: String, imageColor: Color? = nil, destination: Destination) { + self.titleKey = titleKey + self.systemImage = systemImage + self.imageColor = imageColor + self.destination = destination + } + + var titleKey: LocalizedStringKey + var systemImage: String + var imageColor: Color? + var destination: Destination + + var body: some View { + NavigationLink(destination: destination) { + Label( + title: { + Text(titleKey) + }, + icon: { + Image(systemName: systemImage) + .foregroundStyle(imageColor ?? .primary) + .font(.caption) + }) + } + } +} diff --git a/MainApp/Tips/Articles/DynamicTypeSettingFailureTips.swift b/MainApp/Tips/Articles/DynamicTypeSettingFailureTips.swift deleted file mode 100644 index c15e443a..00000000 --- a/MainApp/Tips/Articles/DynamicTypeSettingFailureTips.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// DynamicTypeSettingFailureTips.swift -// MainApp -// -// Created by ensan on 2020/10/19. -// Copyright © 2020 ensan. All rights reserved. -// - -import Foundation -import SwiftUI - -struct DynamicTypeSettingFailureTipsView: View { - var body: some View { - TipsContentView("端末の文字サイズ設定が反映されない") { - TipsContentParagraph { - Text("端末の文字サイズの設定を変更しても、キーボードに表示される文字の大きさが変わらないことがあります。") - Text("一度端末を再起動していただくと設定が反映されます。") - } - - TipsContentParagraph { - Text("azooKeyの設定タブよりキーの文字サイズを設定することが可能です。そちらもお試しください。") - } - - } - } -} diff --git a/MainApp/Tips/News/TipsNewsSection.swift b/MainApp/Tips/News/TipsNewsSection.swift new file mode 100644 index 00000000..92e23111 --- /dev/null +++ b/MainApp/Tips/News/TipsNewsSection.swift @@ -0,0 +1,63 @@ +// +// TipsNewsSection.swift +// azooKey +// +// Created by miwa on 2023/11/11. +// Copyright © 2023 DevEn3. All rights reserved. +// + +import SwiftUI + +struct TipsNewsSection: View { + @AppStorage("read_article_iOS15_service_termination") private var readArticle_iOS15_service_termination = false + @EnvironmentObject private var appStates: MainAppStates + + @MainActor + private var needUseShiftKeySettingNews: Bool { + appStates.englishLayout == .qwerty + } + + @MainActor + private var neadUseNextCandidateKeySettingNews: Bool { + if case .custard = appStates.japaneseLayout, case .custard = appStates.englishLayout { + false + } else { + true + } + } + + var iOS15TerminationNewsViewLabel: some View { + Label( + title: { + Text("iOS15のサポートを終了します") + }, + icon: { + Image(systemName: "exclamationmark.circle.fill") + .foregroundStyle(.red) + .font(.caption) + } + ) + } + var body: some View { + if #unavailable(iOS 16) { + Section("お知らせ") { + NavigationLink(destination: iOS15TerminationNewsView($readArticle_iOS15_service_termination)) { + if !readArticle_iOS15_service_termination { + iOS15TerminationNewsViewLabel + } else { + iOS15TerminationNewsViewLabel.labelStyle(.titleOnly) + } + } + } + } + Section("新機能") { + if needUseShiftKeySettingNews { + IconNavigationLink("シフトキーが使えるようになりました!", systemImage: "shift", imageColor: .orange, destination: UseShiftKeyNews()) + } + if neadUseNextCandidateKeySettingNews { + IconNavigationLink("次候補キーが使えるようになりました!", systemImage: "sparkles", imageColor: .orange, destination: UseNextCandidateKeyNews()) + } + IconNavigationLink("連絡先情報を読み込めるようになりました!", systemImage: "person.text.rectangle", imageColor: .orange, destination: UseContactInfoSettingNews()) + } + } +} diff --git a/MainApp/Tips/News/UseContactInfoSettingNews.swift b/MainApp/Tips/News/UseContactInfoSettingNews.swift new file mode 100644 index 00000000..83cf4f7c --- /dev/null +++ b/MainApp/Tips/News/UseContactInfoSettingNews.swift @@ -0,0 +1,32 @@ +// +// UseContactInfoSettingNews.swift +// azooKey +// +// Created by miwa on 2023/11/11. +// Copyright © 2023 DevEn3. All rights reserved. +// + +import SwiftUI +import class KeyboardViews.SemiStaticStates + +struct UseContactInfoSettingNews: View { + @EnvironmentObject private var appStates: MainAppStates + + var body: some View { + TipsContentView("変換に連絡先データを利用") { + TipsContentParagraph { + Text("「連絡先」アプリのデータを使って、家族や友人、職場の人の名前を素早く入力することができます。") + } + BoolSettingView(.enableContactImport) + + TipsContentParagraph { + if !SemiStaticStates.shared.hasFullAccess { + Text("この機能を利用するには、「フルアクセス」の許可が必要です。詳しくはこちらをお読みください") + NavigationLink("フルアクセスが必要な機能を使う", destination: FullAccessTipsView()) + } + Text("この機能を利用するには、連絡先データの利用の許可が必要です。機能を有効化しようとすると、許可を求める画面が表示されるので、「許可」を選んでください") + } + + } + } +} diff --git a/MainApp/Tips/News/UseNextCandidateKeyNews.swift b/MainApp/Tips/News/UseNextCandidateKeyNews.swift new file mode 100644 index 00000000..c44a4c85 --- /dev/null +++ b/MainApp/Tips/News/UseNextCandidateKeyNews.swift @@ -0,0 +1,20 @@ +// +// UseNextCandidateKeyNews.swift +// azooKey +// +// Created by miwa on 2023/11/11. +// Copyright © 2023 DevEn3. All rights reserved. +// + +import SwiftUI + +struct UseNextCandidateKeyNews: View { + var body: some View { + TipsContentView("シフトキーを使う") { + TipsContentParagraph { + Text("空白キーに「次候補」ボタンを表示するには、次の設定をオンにしてください") + } + BoolSettingView(.useNextCandidateKey) + } + } +} diff --git a/MainApp/Tips/News/UseShiftKeyNews.swift b/MainApp/Tips/News/UseShiftKeyNews.swift new file mode 100644 index 00000000..31b080cb --- /dev/null +++ b/MainApp/Tips/News/UseShiftKeyNews.swift @@ -0,0 +1,20 @@ +// +// UseShiftKeyNews.swift +// azooKey +// +// Created by miwa on 2023/11/10. +// Copyright © 2023 DevEn3. All rights reserved. +// + +import SwiftUI + +struct UseShiftKeyNews: View { + var body: some View { + TipsContentView("シフトキーを使う") { + TipsContentParagraph { + Text("Qwerty英語キーボードでシフトキーを使いたい場合、次の設定をオンにしてください") + } + BoolSettingView(.useShiftKey) + } + } +} diff --git a/MainApp/Tips/TipsView.swift b/MainApp/Tips/TipsView.swift index 10a912aa..c23d2b26 100644 --- a/MainApp/Tips/TipsView.swift +++ b/MainApp/Tips/TipsView.swift @@ -11,12 +11,10 @@ import SwiftUI struct TipsTabView: View { @EnvironmentObject private var appStates: MainAppStates - @AppStorage("read_article_iOS15_service_termination") private var readArticle_iOS15_service_termination = false - var body: some View { NavigationView { Form { - Section(header: Text("キーボードを使えるようにする")) { + Section("キーボードを使えるようにする") { if !appStates.isKeyboardActivated { Text("キーボードを有効化する") .onTapGesture { @@ -25,36 +23,25 @@ struct TipsTabView: View { } NavigationLink("入力方法を選ぶ", destination: SelctInputStyleTipsView()) } - if #unavailable(iOS 16) { - Section(header: Text("お知らせ")) { - HStack { - if !readArticle_iOS15_service_termination { - Image(systemName: "exclamationmark.circle.fill") - .foregroundStyle(.red) - } - NavigationLink("iOS15のサポートを終了します", destination: iOS15TerminationNewsView($readArticle_iOS15_service_termination)) - } - } - } - - Section(header: Text("便利な使い方")) { - NavigationLink("片手モードを使う", destination: OneHandedModeTipsView()) - NavigationLink("カーソルを自由に移動する", destination: CursorMoveTipsView()) - NavigationLink("文頭まで一気に消す", destination: SmoothDeleteTipsView()) - NavigationLink("漢字を拡大表示する", destination: KanjiLargeTextTipsView()) - NavigationLink("大文字に固定する", destination: CapsLockTipsView()) - NavigationLink("タイムスタンプを使う", destination: TemplateSettingTipsView()) - NavigationLink("キーをカスタマイズする", destination: CustomKeyTipsView()) - NavigationLink("フルアクセスが必要な機能を使う", destination: FullAccessTipsView()) + TipsNewsSection() + Section("便利な使い方") { + let imageColor = Color.blue + IconNavigationLink("片手モードを使う", systemImage: "aspectratio", imageColor: imageColor, destination: OneHandedModeTipsView()) + IconNavigationLink("カーソルを自由に移動する", systemImage: "arrowtriangle.left.and.line.vertical.and.arrowtriangle.right", imageColor: imageColor, destination: CursorMoveTipsView()) + IconNavigationLink("文頭まで一気に消す", systemImage: "xmark", imageColor: imageColor, destination: SmoothDeleteTipsView()) + IconNavigationLink("漢字を拡大表示する", systemImage: "plus.magnifyingglass", imageColor: imageColor, destination: KanjiLargeTextTipsView()) + IconNavigationLink("大文字に固定する", systemImage: "capslock.fill", imageColor: imageColor, destination: CapsLockTipsView()) + IconNavigationLink("タイムスタンプを使う", systemImage: "clock", imageColor: imageColor, destination: TemplateSettingTipsView()) + IconNavigationLink("キーをカスタマイズする", systemImage: "hammer", imageColor: imageColor, destination: CustomKeyTipsView()) + IconNavigationLink("フルアクセスが必要な機能を使う", systemImage: "lock.open", imageColor: imageColor, destination: FullAccessTipsView()) if SemiStaticStates.shared.hasFullAccess { - NavigationLink("「ほかのAppからペースト」について", destination: PasteFromOtherAppsPermissionTipsView()) + IconNavigationLink("「ほかのAppからペースト」について", systemImage: "doc.on.clipboard", imageColor: imageColor, destination: PasteFromOtherAppsPermissionTipsView()) } } - Section(header: Text("困ったときは")) { + Section("困ったときは") { NavigationLink("インストール直後、特定のアプリでキーボードが開かない", destination: KeyboardBehaviorIssueAfterInstallTipsView()) NavigationLink("特定のアプリケーションで入力がおかしくなる", destination: UseMarkedTextTipsView()) - NavigationLink("端末の文字サイズ設定が反映されない", destination: DynamicTypeSettingFailureTipsView()) NavigationLink("絵文字や顔文字の変換候補を表示したい", destination: EmojiKaomojiTipsView()) NavigationLink("バグの報告や機能のリクエストをしたい", destination: ContactView()) } diff --git a/Resources/Localizable.xcstrings b/Resources/Localizable.xcstrings index bfbea330..79937292 100644 --- a/Resources/Localizable.xcstrings +++ b/Resources/Localizable.xcstrings @@ -449,6 +449,16 @@ } } }, + "「連絡先」アプリのデータを使って、家族や友人、職場の人の名前を素早く入力することができます。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "You can now quickly input the names of family, friends, and colleagues by using data from the 'Contacts' app." + } + } + } + }, "「連絡先」へのアクセスを許可する必要があります" : { "localizations" : { "en" : { @@ -1057,6 +1067,7 @@ } }, "azooKeyの設定タブよりキーの文字サイズを設定することが可能です。そちらもお試しください。" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -1454,6 +1465,16 @@ } } }, + "Qwerty英語キーボードでシフトキーを使いたい場合、次の設定をオンにしてください" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "If you want to use the Shift key on the Qwerty English keyboard, please turn on the following setting." + } + } + } + }, "unicode変換" : { "extractionState" : "manual", "localizations" : { @@ -3234,6 +3255,26 @@ } } }, + "この機能を利用するには、「フルアクセス」の許可が必要です。詳しくはこちらをお読みください" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "To use this feature, 'Full Access' permission is required. Please read more details here." + } + } + } + }, + "この機能を利用するには、連絡先データの利用の許可が必要です。機能を有効化しようとすると、許可を求める画面が表示されるので、「許可」を選んでください" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "To utilize this feature, permission to access contact data is necessary. When attempting to enable the function, a screen requesting permission will appear. Please select 'Allow' when prompted." + } + } + } + }, "この行を削除" : { "localizations" : { "en" : { @@ -3460,6 +3501,16 @@ } } }, + "シフトキーが使えるようになりました!" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Shift key is now available!" + } + } + } + }, "シフトキーを使う" : { "extractionState" : "manual", "localizations" : { @@ -5130,6 +5181,7 @@ } }, "一度端末を再起動していただくと設定が反映されます。" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -7255,6 +7307,16 @@ } } }, + "新機能" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "New Features" + } + } + } + }, "方向" : { "localizations" : { "en" : { @@ -7902,6 +7964,16 @@ } } }, + "次候補キーが使えるようになりました!" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The next candidate key is now available!" + } + } + } + }, "次候補キーを使う" : { "extractionState" : "manual", "localizations" : { @@ -8526,7 +8598,18 @@ } } }, + "空白キーに「次候補」ボタンを表示するには、次の設定をオンにしてください" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "To display the 'Next Candidate' button on the space key, please turn on the following setting." + } + } + } + }, "端末の文字サイズの設定を変更しても、キーボードに表示される文字の大きさが変わらないことがあります。" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -8543,6 +8626,7 @@ } }, "端末の文字サイズ設定が反映されない" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -9671,6 +9755,16 @@ } } }, + "連絡先情報を読み込めるようになりました!" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "azooKey can now utilize contact information!" + } + } + } + }, "選ぶ" : { "localizations" : { "en" : { diff --git a/azooKey.xcodeproj/project.pbxproj b/azooKey.xcodeproj/project.pbxproj index 1444fb74..965375b5 100644 --- a/azooKey.xcodeproj/project.pbxproj +++ b/azooKey.xcodeproj/project.pbxproj @@ -153,7 +153,6 @@ 1AED0A612A6D22CB005B87E5 /* AzooKeyUtils in Frameworks */ = {isa = PBXBuildFile; productRef = 1AED0A602A6D22CB005B87E5 /* AzooKeyUtils */; }; 1AF28CE0253C9FFC0012CF94 /* CursorMoveTips.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF28CDF253C9FFC0012CF94 /* CursorMoveTips.swift */; }; 1AF28CE6253CA0F50012CF94 /* KanjiLargeText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF28CE5253CA0F50012CF94 /* KanjiLargeText.swift */; }; - 1AF28D00253DA5250012CF94 /* DynamicTypeSettingFailureTips.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF28CFF253DA5250012CF94 /* DynamicTypeSettingFailureTips.swift */; }; 1AF306022A00070000B4DAC3 /* KanaKanjiConverterModule in Frameworks */ = {isa = PBXBuildFile; productRef = 1AF306012A00070000B4DAC3 /* KanaKanjiConverterModule */; }; 1AF616B4256D409E001A0B32 /* MemoryResetSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF616B3256D409E001A0B32 /* MemoryResetSetting.swift */; }; 1AF6784A25CC20B400F3987B /* ThemeTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF6784925CC20B400F3987B /* ThemeTab.swift */; }; @@ -167,6 +166,11 @@ 1AFA57662584815B00477DC2 /* QwertyCustomKeysItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFA57652584815A00477DC2 /* QwertyCustomKeysItemView.swift */; }; 1AFB68422518C48100C649C4 /* OpenSourceSoftwaresLicenseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFB68412518C48100C649C4 /* OpenSourceSoftwaresLicenseView.swift */; }; 1AFE773026077E0E0041D74D /* WalkthroughState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFE772F26077E0E0041D74D /* WalkthroughState.swift */; }; + 5531AA392AFE7C7B00A9642A /* UseShiftKeyNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA382AFE7C7B00A9642A /* UseShiftKeyNews.swift */; }; + 5531AA3B2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA3A2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift */; }; + 5531AA3E2AFE800E00A9642A /* UseContactInfoSettingNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA3D2AFE800E00A9642A /* UseContactInfoSettingNews.swift */; }; + 5531AA402AFE81FB00A9642A /* TipsNewsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA3F2AFE81FB00A9642A /* TipsNewsSection.swift */; }; + 5531AA422AFE82BE00A9642A /* IconNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA412AFE82BE00A9642A /* IconNavigationLink.swift */; }; 557D9DFB2ABEE7970028F3A0 /* ContactAuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557D9DFA2ABEE7970028F3A0 /* ContactAuthManager.swift */; }; 557D9DFD2ABEF6560028F3A0 /* ContactImportSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557D9DFC2ABEF6560028F3A0 /* ContactImportSettingView.swift */; }; 557D9DFF2ABF2B9D0028F3A0 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 557D9DFE2ABF2B9D0028F3A0 /* InfoPlist.xcstrings */; }; @@ -347,7 +351,6 @@ 1AE70BEA258E5767009B9B8B /* TemplateEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateEditingView.swift; sourceTree = ""; }; 1AF28CDF253C9FFC0012CF94 /* CursorMoveTips.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CursorMoveTips.swift; sourceTree = ""; }; 1AF28CE5253CA0F50012CF94 /* KanjiLargeText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KanjiLargeText.swift; sourceTree = ""; }; - 1AF28CFF253DA5250012CF94 /* DynamicTypeSettingFailureTips.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicTypeSettingFailureTips.swift; sourceTree = ""; }; 1AF3060029FE6C2800B4DAC3 /* AzooKeyCore */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = AzooKeyCore; sourceTree = ""; }; 1AF616B3256D409E001A0B32 /* MemoryResetSetting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryResetSetting.swift; sourceTree = ""; }; 1AF6784925CC20B400F3987B /* ThemeTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeTab.swift; sourceTree = ""; }; @@ -360,6 +363,11 @@ 1AFA57652584815A00477DC2 /* QwertyCustomKeysItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QwertyCustomKeysItemView.swift; sourceTree = ""; }; 1AFB68412518C48100C649C4 /* OpenSourceSoftwaresLicenseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSourceSoftwaresLicenseView.swift; sourceTree = ""; }; 1AFE772F26077E0E0041D74D /* WalkthroughState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalkthroughState.swift; sourceTree = ""; }; + 5531AA382AFE7C7B00A9642A /* UseShiftKeyNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseShiftKeyNews.swift; sourceTree = ""; }; + 5531AA3A2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseNextCandidateKeyNews.swift; sourceTree = ""; }; + 5531AA3D2AFE800E00A9642A /* UseContactInfoSettingNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseContactInfoSettingNews.swift; sourceTree = ""; }; + 5531AA3F2AFE81FB00A9642A /* TipsNewsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipsNewsSection.swift; sourceTree = ""; }; + 5531AA412AFE82BE00A9642A /* IconNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconNavigationLink.swift; sourceTree = ""; }; 557D9DFA2ABEE7970028F3A0 /* ContactAuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactAuthManager.swift; sourceTree = ""; }; 557D9DFC2ABEF6560028F3A0 /* ContactImportSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactImportSettingView.swift; sourceTree = ""; }; 557D9DFE2ABF2B9D0028F3A0 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; @@ -536,6 +544,7 @@ children = ( 1A4E09042527390100E7ABE5 /* TipsView.swift */, 1ACEEFE82566601700899DA2 /* TipsViewComponent.swift */, + 5531AA3C2AFE7F2500A9642A /* News */, 1ACEEFE72566600700899DA2 /* Articles */, ); path = Tips; @@ -852,6 +861,7 @@ 1A4A3255262FAAFD00EDAB08 /* CancelableEditor.swift */, 1AFA575F2584810800477DC2 /* Focus.swift */, 1A3022AE2631663200E4495C /* OnEnterBackground.swift */, + 5531AA412AFE82BE00A9642A /* IconNavigationLink.swift */, 1AFA4BB2257E169100477DC2 /* PasteButton.swift */, 1AD4454226AA8E93003CF854 /* LargeButtonStyle.swift */, 1A3A160D2528C70800A5BA4F /* HeaderLogoView.swift */, @@ -875,7 +885,6 @@ 1AFA57592583051500477DC2 /* CapslockTips.swift */, 1AC8A5812594EF6500B71E5A /* TemplateSettingTipsView.swift */, 1AA346C72568294300B41A16 /* CustomKeyTipsView.swift */, - 1AF28CFF253DA5250012CF94 /* DynamicTypeSettingFailureTips.swift */, 1A2B2B5E299480B40048332A /* UseMarkedTextTipsView.swift */, 1A2B2B602994846B0048332A /* KeyboardBehaviorIssueAfterInstallTipsView.swift */, 1A9B0A2C25635090004203BB /* EmojiKaomojiView.swift */, @@ -931,6 +940,17 @@ path = Theme; sourceTree = ""; }; + 5531AA3C2AFE7F2500A9642A /* News */ = { + isa = PBXGroup; + children = ( + 5531AA3D2AFE800E00A9642A /* UseContactInfoSettingNews.swift */, + 5531AA382AFE7C7B00A9642A /* UseShiftKeyNews.swift */, + 5531AA3A2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift */, + 5531AA3F2AFE81FB00A9642A /* TipsNewsSection.swift */, + ); + path = News; + sourceTree = ""; + }; 557D9DF92ABEE78D0028F3A0 /* ContactImportSetting */ = { isa = PBXGroup; children = ( @@ -1293,6 +1313,7 @@ 1AB8C3FE25E35B3C00D39BC5 /* ManageCustardView.swift in Sources */, 1AAC102729B25D060020BDE9 /* KeyboardHeightSettingView.swift in Sources */, 1AFE773026077E0E0041D74D /* WalkthroughState.swift in Sources */, + 5531AA392AFE7C7B00A9642A /* UseShiftKeyNews.swift in Sources */, 1AFA4BB3257E169100477DC2 /* PasteButton.swift in Sources */, 1A7B147325F6602E00BE2472 /* CustomizeTabWalkthrough.swift in Sources */, 1AB8C3DE25E2854C00D39BC5 /* CodableActionDataEditor.swift in Sources */, @@ -1309,9 +1330,11 @@ 1AE102CF25D3713C00CA7277 /* TrimmingView.swift in Sources */, 1A9B0A5025642C38004203BB /* EnableAzooKeyViewComponent.swift in Sources */, 1AD4454626AAB8E4003CF854 /* DisclosuringList.swift in Sources */, + 5531AA402AFE81FB00A9642A /* TipsNewsSection.swift in Sources */, 1AB5076B255ECC3C003C0BF2 /* Trie.swift in Sources */, 1A2B2B612994846B0048332A /* KeyboardBehaviorIssueAfterInstallTipsView.swift in Sources */, 1A4A3256262FAAFD00EDAB08 /* CancelableEditor.swift in Sources */, + 5531AA3E2AFE800E00A9642A /* UseContactInfoSettingNews.swift in Sources */, 1A3DC1CA2500D44B002CAA93 /* ContentView.swift in Sources */, 1AF6A54725FCF1240037D5ED /* OneHandedModeTips.swift in Sources */, 1AB50760255EC23C003C0BF2 /* AdditionalDictManageView.swift in Sources */, @@ -1322,6 +1345,7 @@ 1A4057DF255843330073C6F7 /* BoolSettingView.swift in Sources */, 1AC8A5822594EF6500B71E5A /* TemplateSettingTipsView.swift in Sources */, 1A3ACF1725FB78BF007E9938 /* ContainerInternalSetting.swift in Sources */, + 5531AA3B2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift in Sources */, 1A9218DE2550FB9C005F45C4 /* SmoothDeleteTipsView.swift in Sources */, 1A12E25825C4484200316009 /* DataUpdateView.swift in Sources */, 1A3A160E2528C70800A5BA4F /* HeaderLogoView.swift in Sources */, @@ -1339,7 +1363,6 @@ 1A5C7EAC25F36A6E00A7CBA8 /* PreferredLanguageSettingView.swift in Sources */, 1AE1023625D0C99200CA7277 /* PhotoPicker.swift in Sources */, 1A2C293926273E9900DFE465 /* DraggableView.swift in Sources */, - 1AF28D00253DA5250012CF94 /* DynamicTypeSettingFailureTips.swift in Sources */, 1AE1025625D1788300CA7277 /* Capture.swift in Sources */, 1A10D7F825E4E8D30095CB67 /* CustardInformationView.swift in Sources */, 1AD4454326AA8E93003CF854 /* LargeButtonStyle.swift in Sources */, @@ -1351,6 +1374,7 @@ 1AE70BE1258DB4B9009B9B8B /* TemplateListView.swift in Sources */, 1A855C7829EA8A6400DD3702 /* ShareWordView.swift in Sources */, 1AF616B4256D409E001A0B32 /* MemoryResetSetting.swift in Sources */, + 5531AA422AFE82BE00A9642A /* IconNavigationLink.swift in Sources */, 1AE1913625D4A3370044EE4B /* ThemeShareView.swift in Sources */, 557D9DFD2ABEF6560028F3A0 /* ContactImportSettingView.swift in Sources */, 1AFA57602584810800477DC2 /* Focus.swift in Sources */, From 670d19821e3d87432142e103f56f7e89f79ad77a Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sat, 11 Nov 2023 01:45:26 +0900 Subject: [PATCH 08/13] =?UTF-8?q?=E3=82=A2=E3=83=8B=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E3=82=92=E6=B8=9B=E3=82=89=E3=81=97?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift index f3471ddf..45bae445 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift @@ -146,7 +146,7 @@ struct ResultBar: View { } } } - .animation(.easeIn(duration: 0.2), value: variableStates.resultModel.displayState) + .animation(.easeIn(duration: 0.2), value: variableStates.resultModel.displayState == .nothing) } private func pressed(candidate: any ResultViewItemData) { From 80eeb24167ddb3e62b316888d6abdace8bd19711 Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sat, 11 Nov 2023 09:50:41 +0900 Subject: [PATCH 09/13] =?UTF-8?q?=E3=81=95=E3=81=BE=E3=81=96=E3=81=BE?= =?UTF-8?q?=E3=81=AA=E7=9D=80=E3=81=9B=E6=9B=BF=E3=81=88=E3=81=A7=E9=81=B8?= =?UTF-8?q?=E6=8A=9E=E5=80=99=E8=A3=9C=E3=81=AE=E3=83=8F=E3=82=A4=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=83=88=E3=81=8C=E5=AE=89=E5=AE=9A=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/KeyboardBar/ResultBar.swift | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift index 45bae445..e2fd3f70 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift @@ -103,7 +103,7 @@ struct ResultBar: View { KeyboardFeedback.click() self.pressed(candidate: data.candidate) } - .buttonStyle(ResultButtonStyle(height: buttonHeight, selected: data.id == variableStates.resultModel.selection)) + .buttonStyle(ResultButtonStyle(height: buttonHeight, selected: .init(selection: variableStates.resultModel.selection, index: data.id))) .contextMenu { ResultContextMenuView(candidate: data.candidate, displayResetLearningButton: Extension.SettingProvider.canResetLearningForCandidate, index: data.id) } @@ -210,30 +210,56 @@ struct ResultContextMenuView: View { } struct ResultButtonStyle: ButtonStyle { + enum SelectionState: Sendable { + case nothing + case this + case other + init(selection: Int?, index: Int) { + if let selection { + if selection == index { + self = .this + } else { + self = .other + } + } else { + self = .nothing + } + } + } private let height: CGFloat private let userSizePreference: Double - private let selected: Bool + private let selected: SelectionState @Environment(Extension.Theme.self) private var theme - @MainActor init(height: CGFloat, selected: Bool = false) { + @MainActor init(height: CGFloat, selected: SelectionState = .nothing) { self.userSizePreference = Extension.SettingProvider.resultViewFontSize self.height = height self.selected = selected } + private func background(configuration: Configuration) -> any ShapeStyle { + if configuration.isPressed { + theme.pushedKeyFillColor.color.opacity(0.5) + } else { + switch self.selected { + case .nothing: theme.resultBackgroundColor.color + case .this: Material.thin + case .other: theme.resultBackgroundColor.color.opacity(0.5) + } + } + } + func makeBody(configuration: Configuration) -> some View { configuration.label .font(Design.fonts.resultViewFont(theme: theme, userSizePrefrerence: self.userSizePreference)) .frame(height: height) .padding(.all, 5) .foregroundStyle(theme.resultTextColor.color) // 文字色は常に不透明度1で描画する - .background( - (configuration.isPressed || self.selected) ? - theme.pushedKeyFillColor.color.opacity(0.5) : - theme.resultBackgroundColor.color - ) + .background(AnyShapeStyle(background(configuration: configuration))) .cornerRadius(5.0) + .compositingGroup() + .contentShape(Rectangle()) .animation(nil, value: configuration.isPressed) } } From d3f9cd6ab76c4ebe4f447441fa448c1efddc6d25 Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sat, 11 Nov 2023 09:59:00 +0900 Subject: [PATCH 10/13] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/KeyboardBar/ResultBar.swift | 51 +++++++------------ 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift index e2fd3f70..67d741f0 100644 --- a/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift +++ b/AzooKeyCore/Sources/KeyboardViews/View/KeyboardBar/ResultBar.swift @@ -58,11 +58,9 @@ struct ResultBar: View { tabBarButton } if let undoButtonAction { - Button { + Button("取り消す", systemImage: "arrow.uturn.backward") { KeyboardFeedback.click() self.action.registerAction(undoButtonAction.action, variableStates: variableStates) - } label: { - Label("取り消す", systemImage: "arrow.uturn.backward") } .buttonStyle(ResultButtonStyle(height: buttonHeight)) } @@ -172,40 +170,27 @@ struct ResultContextMenuView: View { } var body: some View { - Group { - Button(action: { - variableStates.magnifyingText = candidate.text - variableStates.boolStates.isTextMagnifying = true - }) { - Text("大きな文字で表示する") - Image(systemName: "plus.magnifyingglass") - } - if displayResetLearningButton { - Button(action: { - action.notifyForgetCandidate(candidate, variableStates: variableStates) - }) { - Text("この候補の学習をリセットする") - Image(systemName: "clear") - } + Button("大きな文字で表示", systemImage: "plus.magnifyingglass") { + variableStates.magnifyingText = candidate.text + variableStates.boolStates.isTextMagnifying = true + } + if displayResetLearningButton { + Button("この候補の学習をリセットする", systemImage: "clear") { + action.notifyForgetCandidate(candidate, variableStates: variableStates) } - if SemiStaticStates.shared.hasFullAccess { - Button { - Task { @MainActor in - await action.notifyReportWrongConversion(candidate, index: index, variableStates: variableStates) - } - } label: { - Label("誤変換を報告", systemImage: "exclamationmark.bubble") + } + if SemiStaticStates.shared.hasFullAccess { + Button("誤変換を報告", systemImage: "exclamationmark.bubble") { + Task { @MainActor in + await action.notifyReportWrongConversion(candidate, index: index, variableStates: variableStates) } } - #if DEBUG - Button(action: { - debug(self.candidate.getDebugInformation()) - }) { - Text("デバッグ情報を表示する") - Image(systemName: "ladybug.fill") - } - #endif } + #if DEBUG + Button("デバッグ情報を表示する", systemImage: "ladybug.fill"){ + debug(self.candidate.getDebugInformation()) + } + #endif } } From 0f2e48ee65abf35f70f6c7a9b6f820a0afff6360 Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sat, 11 Nov 2023 10:12:10 +0900 Subject: [PATCH 11/13] Update version --- MainApp/UpdateInformationView.swift | 7 +++++++ azooKey.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/MainApp/UpdateInformationView.swift b/MainApp/UpdateInformationView.swift index f54e7634..40023f2e 100644 --- a/MainApp/UpdateInformationView.swift +++ b/MainApp/UpdateInformationView.swift @@ -16,6 +16,13 @@ struct UpdateInformationView: View { Group { // version 2.2系 Group { + VersionView("2.2.1", releaseDate: "2023年11月12日") { + ParagraphView("機能を改善しました。") { + "「空白キー」に換えて「次候補」キーを選べるようになりました" + "Qwertyキーボードで常に「次候補キー」が表示されていた問題を修正しました" + "デザインを改善しました" + } + } VersionView("2.2", releaseDate: "2023年11月3日") { if #unavailable(iOS 16) { ParagraphView("お知らせ。") { diff --git a/azooKey.xcodeproj/project.pbxproj b/azooKey.xcodeproj/project.pbxproj index 965375b5..64cfc8b4 100644 --- a/azooKey.xcodeproj/project.pbxproj +++ b/azooKey.xcodeproj/project.pbxproj @@ -1671,7 +1671,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.2; + MARKETING_VERSION = 2.2.1; OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature BareSlashRegexLiterals -enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature DisableOutwardActorInference -enable-upcoming-feature ImportObjcForwardDeclarations"; PRODUCT_BUNDLE_IDENTIFIER = DevEn3.azooKey; PRODUCT_NAME = azooKey; @@ -1708,7 +1708,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES_THIN; - MARKETING_VERSION = 2.2; + MARKETING_VERSION = 2.2.1; OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ImplicitOpenExistentials"; PRODUCT_BUNDLE_IDENTIFIER = DevEn3.azooKey; PRODUCT_NAME = azooKey; From 12679fda5b0a13b83a3f94a2c85608ed23f4b85c Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Sat, 11 Nov 2023 14:23:53 +0900 Subject: [PATCH 12/13] Add tips for debugging custom actions --- ...ustomActionWorksUnexpectedlyTipsView.swift | 39 ++++ MainApp/Tips/TipsView.swift | 1 + Resources/Localizable.xcstrings | 200 ++++++++++++------ azooKey.xcodeproj/project.pbxproj | 4 + 4 files changed, 180 insertions(+), 64 deletions(-) create mode 100644 MainApp/Tips/Articles/CustomActionWorksUnexpectedlyTipsView.swift diff --git a/MainApp/Tips/Articles/CustomActionWorksUnexpectedlyTipsView.swift b/MainApp/Tips/Articles/CustomActionWorksUnexpectedlyTipsView.swift new file mode 100644 index 00000000..a9144115 --- /dev/null +++ b/MainApp/Tips/Articles/CustomActionWorksUnexpectedlyTipsView.swift @@ -0,0 +1,39 @@ +// +// CustomActionWorksUnexpectedlyTipsView.swift +// azooKey +// +// Created by miwa on 2023/11/11. +// Copyright © 2023 DevEn3. All rights reserved. +// + +import SwiftUI + +struct CustomActionWorksUnexpectedlyTipsView: View { + var body: some View { + TipsContentView("カスタムアクションがうまく動かない") { + TipsContentParagraph { + Text("カスタムキーで高度なアクションを設定した際、思った通りに動かないことがあります。") + Text("カスタムアクションをうまく設定するためのヒントを紹介します。") + } + TipsContentParagraph { + Text("カスタムアクションが思った通りに動かない場合、実現したい操作をなるべくそのまま実行することが重要です。") + Text("例えば、「()を入力して一文字カーソルを左に動かす」というアクションを作ることを考えます。") + Text("このとき、実際のキーボードでは「(」を入力し、「)」を入力し、ついで「確定」を押します。azooKeyは自動でカーソルを移動するので、これで実現したい操作が完了します。") + Text("カスタムアクションでこれを再現する場合、「(」の入力→「)」の入力→「確定」の順でアクションを設定すれば上手く動きます。") + Text("ただし、まとめられるアクションはまとめた方が効率よく動きます。今回の場合では「()」の入力→「確定」の順にすることで、より良いカスタムアクションになります。") + } + + TipsContentParagraph { + Text("ライブ変換などの設定によって、思っていない挙動が発生することがあります。") + Text("例えば、ひらがなで「あさ」を入力するアクションを設定していても、ライブ変換がオンになっている場合自動で「朝」になってしまいます。") + Text("これを防ぐには、一文字ずつ入力して確定することができます。つまり、「あ」の入力→「確定」→「さ」の入力→「確定」の順で実行することで、ひらがなの「あさ」を入力することができます") + } + TipsContentParagraph { + Text("一部のアクションは、設定によって異なる動作をします。") + Text("ライブ変換がオンになっている場合、入力中のカーソル移動は無効になります。カーソルを移動する前に一度「確定」を挟むことで、思った通りの挙動になります。") + Text("「ペースト」アクションにはフルアクセスの許可が必要で、これがない場合思った通りに動かないことがあります。") + } + + } + } +} diff --git a/MainApp/Tips/TipsView.swift b/MainApp/Tips/TipsView.swift index c23d2b26..0004ba0b 100644 --- a/MainApp/Tips/TipsView.swift +++ b/MainApp/Tips/TipsView.swift @@ -42,6 +42,7 @@ struct TipsTabView: View { Section("困ったときは") { NavigationLink("インストール直後、特定のアプリでキーボードが開かない", destination: KeyboardBehaviorIssueAfterInstallTipsView()) NavigationLink("特定のアプリケーションで入力がおかしくなる", destination: UseMarkedTextTipsView()) + NavigationLink("カスタムアクションがうまく動かない", destination: CustomActionWorksUnexpectedlyTipsView()) NavigationLink("絵文字や顔文字の変換候補を表示したい", destination: EmojiKaomojiTipsView()) NavigationLink("バグの報告や機能のリクエストをしたい", destination: ContactView()) } diff --git a/Resources/Localizable.xcstrings b/Resources/Localizable.xcstrings index 79937292..b8aecaec 100644 --- a/Resources/Localizable.xcstrings +++ b/Resources/Localizable.xcstrings @@ -325,6 +325,16 @@ } } }, + "「ペースト」アクションにはフルアクセスの許可が必要で、これがない場合思った通りに動かないことがあります。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The 'Paste' action requires full access permission, and it may not function as expected if this permission is not granted." + } + } + } + }, "「ペーストを許可」のダイアログについて" : { "localizations" : { "en" : { @@ -1066,23 +1076,6 @@ } } }, - "azooKeyの設定タブよりキーの文字サイズを設定することが可能です。そちらもお試しください。" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "On the Settings tab in azooKey, you can set key font size. Please try it." - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "" - } - } - } - }, "azooKeyは、キーボードの振動フィードバックや、キーボードからのペーストを実現するために、フルアクセスの許可が必要です。フルアクセスを許可していただくことで、これらの機能が使用できます。" : { "localizations" : { "en" : { @@ -2031,6 +2024,46 @@ } } }, + "カスタムアクションがうまく動かない" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Custom actions doesn't work as expected" + } + } + } + }, + "カスタムアクションが思った通りに動かない場合、実現したい操作をなるべくそのまま実行することが重要です。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "If your custom action isn't working as expected, it's crucial to try to replicate the desired operation as closely as possible." + } + } + } + }, + "カスタムアクションでこれを再現する場合、「(」の入力→「)」の入力→「確定」の順でアクションを設定すれば上手く動きます。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "If you want to replicate this using a custom action, set up the action in the following order: input '(' -> input ')' -> confirm. This should work as expected." + } + } + } + }, + "カスタムアクションをうまく設定するためのヒントを紹介します。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Here are some tips for setting up custom actions successfully." + } + } + } + }, "カスタムキー" : { "localizations" : { "en" : { @@ -2047,6 +2080,16 @@ } } }, + "カスタムキーで高度なアクションを設定した際、思った通りに動かないことがあります。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "When setting up advanced actions with custom keys, they may not work as expected." + } + } + } + }, "カスタムキーの設定" : { "localizations" : { "en" : { @@ -3159,6 +3202,16 @@ } } }, + "このとき、実際のキーボードでは「(」を入力し、「)」を入力し、ついで「確定」を押します。azooKeyは自動でカーソルを移動するので、これで実現したい操作が完了します。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "In this case, you would input '(' and then ')', followed by pressing 'Enter' on the actual keyboard. Since azooKey automatically moves the cursor, this sequence accomplishes the desired action." + } + } + } + }, "この列を削除" : { "localizations" : { "en" : { @@ -3373,6 +3426,16 @@ } } }, + "これを防ぐには、一文字ずつ入力して確定することができます。つまり、「あ」の入力→「確定」→「さ」の入力→「確定」の順で実行することで、ひらがなの「あさ」を入力することができます" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "To prevent this, you can input one character at a time and confirm. In other words, executing the sequence: input 'あ' -> confirm -> input 'さ' -> confirm allows you to input the hiragana 'あさ'." + } + } + } + }, "サイズの調整モードがオンになります。左右の白い部分をドラッグし、好みのサイズに調整してください。" : { "localizations" : { "en" : { @@ -3740,6 +3803,16 @@ } } }, + "ただし、まとめられるアクションはまとめた方が効率よく動きます。今回の場合では「()」の入力→「確定」の順にすることで、より良いカスタムアクションになります。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "However, for more efficient performance, it is recommended to consolidate actions when possible. In this case, combining the input of '()' and the confirmation steps into a single action would create a more effective custom action." + } + } + } + }, "タブ" : { "localizations" : { "en" : { @@ -4972,6 +5045,26 @@ } } }, + "ライブ変換がオンになっている場合、入力中のカーソル移動は無効になります。カーソルを移動する前に一度「確定」を挟むことで、思った通りの挙動になります。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "When live conversion is enabled, cursor movement during input is disabled. To achieve the desired behavior, insert a 'confirm' action before moving the cursor." + } + } + } + }, + "ライブ変換などの設定によって、思っていない挙動が発生することがあります。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unexpected behaviors may occur due to settings such as live conversion." + } + } + } + }, "ライブ変換の設定" : { "localizations" : { "en" : { @@ -5180,13 +5273,12 @@ } } }, - "一度端末を再起動していただくと設定が反映されます。" : { - "extractionState" : "stale", + "一行ずつ登録したい文字や単語を入力してください" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Please reboot your device, and the setting can work." + "value" : "List up letters and sentences you want to use in this custom tab in line-separated format" } }, "ja" : { @@ -5197,12 +5289,12 @@ } } }, - "一行ずつ登録したい文字や単語を入力してください" : { + "一覧" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "List up letters and sentences you want to use in this custom tab in line-separated format" + "value" : "List" } }, "ja" : { @@ -5213,18 +5305,12 @@ } } }, - "一覧" : { + "一部のアクションは、設定によって異なる動作をします。" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "List" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "" + "value" : "Some actions may exhibit different behaviors depending on the configuration settings." } } } @@ -5471,6 +5557,26 @@ } } }, + "例えば、「()を入力して一文字カーソルを左に動かす」というアクションを作ることを考えます。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Consider creating an action, for instance, where you input '()' and move the cursor one character to the left." + } + } + } + }, + "例えば、ひらがなで「あさ」を入力するアクションを設定していても、ライブ変換がオンになっている場合自動で「朝」になってしまいます。" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "For instance, even if you've set up an action to input 'あさ' in hiragana, when live conversion is enabled, it may automatically change to '朝'." + } + } + } + }, "便利なボタンを追加" : { "localizations" : { "en" : { @@ -8608,40 +8714,6 @@ } } }, - "端末の文字サイズの設定を変更しても、キーボードに表示される文字の大きさが変わらないことがあります。" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sometimes the setting of your device's font size doesn't affect the keyboard." - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "" - } - } - } - }, - "端末の文字サイズ設定が反映されない" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Setting of device's font size doesn't work" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "" - } - } - } - }, "第1言語" : { "localizations" : { "en" : { diff --git a/azooKey.xcodeproj/project.pbxproj b/azooKey.xcodeproj/project.pbxproj index 64cfc8b4..807998de 100644 --- a/azooKey.xcodeproj/project.pbxproj +++ b/azooKey.xcodeproj/project.pbxproj @@ -166,6 +166,7 @@ 1AFA57662584815B00477DC2 /* QwertyCustomKeysItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFA57652584815A00477DC2 /* QwertyCustomKeysItemView.swift */; }; 1AFB68422518C48100C649C4 /* OpenSourceSoftwaresLicenseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFB68412518C48100C649C4 /* OpenSourceSoftwaresLicenseView.swift */; }; 1AFE773026077E0E0041D74D /* WalkthroughState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFE772F26077E0E0041D74D /* WalkthroughState.swift */; }; + 5525377F2AFF1C8000F1E253 /* CustomActionWorksUnexpectedlyTipsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5525377E2AFF1C8000F1E253 /* CustomActionWorksUnexpectedlyTipsView.swift */; }; 5531AA392AFE7C7B00A9642A /* UseShiftKeyNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA382AFE7C7B00A9642A /* UseShiftKeyNews.swift */; }; 5531AA3B2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA3A2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift */; }; 5531AA3E2AFE800E00A9642A /* UseContactInfoSettingNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5531AA3D2AFE800E00A9642A /* UseContactInfoSettingNews.swift */; }; @@ -363,6 +364,7 @@ 1AFA57652584815A00477DC2 /* QwertyCustomKeysItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QwertyCustomKeysItemView.swift; sourceTree = ""; }; 1AFB68412518C48100C649C4 /* OpenSourceSoftwaresLicenseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSourceSoftwaresLicenseView.swift; sourceTree = ""; }; 1AFE772F26077E0E0041D74D /* WalkthroughState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalkthroughState.swift; sourceTree = ""; }; + 5525377E2AFF1C8000F1E253 /* CustomActionWorksUnexpectedlyTipsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomActionWorksUnexpectedlyTipsView.swift; sourceTree = ""; }; 5531AA382AFE7C7B00A9642A /* UseShiftKeyNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseShiftKeyNews.swift; sourceTree = ""; }; 5531AA3A2AFE7F1400A9642A /* UseNextCandidateKeyNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseNextCandidateKeyNews.swift; sourceTree = ""; }; 5531AA3D2AFE800E00A9642A /* UseContactInfoSettingNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseContactInfoSettingNews.swift; sourceTree = ""; }; @@ -887,6 +889,7 @@ 1AA346C72568294300B41A16 /* CustomKeyTipsView.swift */, 1A2B2B5E299480B40048332A /* UseMarkedTextTipsView.swift */, 1A2B2B602994846B0048332A /* KeyboardBehaviorIssueAfterInstallTipsView.swift */, + 5525377E2AFF1C8000F1E253 /* CustomActionWorksUnexpectedlyTipsView.swift */, 1A9B0A2C25635090004203BB /* EmojiKaomojiView.swift */, 1AAC102829B4EE4A0020BDE9 /* FullAccessTipsView.swift */, 1A3B4E2729D7E348005F0CDC /* PasteFromOtherAppsPermissionTipsView.swift */, @@ -1351,6 +1354,7 @@ 1A3A160E2528C70800A5BA4F /* HeaderLogoView.swift in Sources */, 1AF6784A25CC20B400F3987B /* ThemeTab.swift in Sources */, 1A9B0A4925642935004203BB /* EnableAzooKeyView.swift in Sources */, + 5525377F2AFF1C8000F1E253 /* CustomActionWorksUnexpectedlyTipsView.swift in Sources */, 1AD5E17826AB230F001B4FF7 /* CustomKeysSettingView.swift in Sources */, 1A347FE828D22FA2007D7852 /* LiveConversionSettingView.swift in Sources */, 1ACB07CA25E552940077DE04 /* EditingScrollCustardView.swift in Sources */, From 1566e89736c194e6beeffe3d2970019af439edeb Mon Sep 17 00:00:00 2001 From: ensan-hcl Date: Mon, 13 Nov 2023 08:44:17 +0900 Subject: [PATCH 13/13] Update to version 2.2.2 --- MainApp/UpdateInformationView.swift | 5 +++++ azooKey.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/MainApp/UpdateInformationView.swift b/MainApp/UpdateInformationView.swift index 40023f2e..41ac56ec 100644 --- a/MainApp/UpdateInformationView.swift +++ b/MainApp/UpdateInformationView.swift @@ -16,6 +16,11 @@ struct UpdateInformationView: View { Group { // version 2.2系 Group { + VersionView("2.2.2", releaseDate: "2023年11月13日") { + ParagraphView("不具合を修正しました。") { + "起動に関する問題を修正しました" + } + } VersionView("2.2.1", releaseDate: "2023年11月12日") { ParagraphView("機能を改善しました。") { "「空白キー」に換えて「次候補」キーを選べるようになりました" diff --git a/azooKey.xcodeproj/project.pbxproj b/azooKey.xcodeproj/project.pbxproj index 807998de..2cfca961 100644 --- a/azooKey.xcodeproj/project.pbxproj +++ b/azooKey.xcodeproj/project.pbxproj @@ -1675,7 +1675,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature BareSlashRegexLiterals -enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature DisableOutwardActorInference -enable-upcoming-feature ImportObjcForwardDeclarations"; PRODUCT_BUNDLE_IDENTIFIER = DevEn3.azooKey; PRODUCT_NAME = azooKey; @@ -1712,7 +1712,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES_THIN; - MARKETING_VERSION = 2.2.1; + MARKETING_VERSION = 2.2.2; OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ImplicitOpenExistentials"; PRODUCT_BUNDLE_IDENTIFIER = DevEn3.azooKey; PRODUCT_NAME = azooKey;