From c8cbf8249741e2c587cb4113a6f7dec09b2c5519 Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Tue, 8 Oct 2024 23:20:50 -0400 Subject: [PATCH 1/3] horizontal scrollable candidates --- patches/hallelujah.patch | 6 +-- uipanel/CMakeLists.txt | 2 + uipanel/Candidate.swift | 34 ++++++++++++++ uipanel/CandidateBar.swift | 93 ++++++++++++++++++++++++++++++++++++++ uipanel/keyboardui.swift | 10 ++++ uipanel/uipanel.cpp | 8 ++-- 6 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 uipanel/Candidate.swift create mode 100644 uipanel/CandidateBar.swift diff --git a/patches/hallelujah.patch b/patches/hallelujah.patch index 0ddccec..92c43ab 100644 --- a/patches/hallelujah.patch +++ b/patches/hallelujah.patch @@ -1,12 +1,12 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 02daeea..bcc8397 100644 +index 7ffcf34..a57a061 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,8 +12,6 @@ option(ENABLE_TEST "Build Test" On) option(BUILD_DATA "Build data" On) find_package(Gettext REQUIRED) --find_package(Fcitx5Core 5.0.0 REQUIRED) +-find_package(Fcitx5Core 5.1.9 REQUIRED) -find_package(Fcitx5Module REQUIRED COMPONENTS Spell TestFrontend) find_package(PkgConfig REQUIRED) @@ -75,7 +75,7 @@ index dcbd627..6b0f00d 100644 + \" +) diff --git a/src/hallelujah.h b/src/hallelujah.h -index 115ad79..c35bd7e 100644 +index ace78e7..2a371b8 100644 --- a/src/hallelujah.h +++ b/src/hallelujah.h @@ -71,7 +71,6 @@ private: diff --git a/uipanel/CMakeLists.txt b/uipanel/CMakeLists.txt index e4d4735..212243f 100644 --- a/uipanel/CMakeLists.txt +++ b/uipanel/CMakeLists.txt @@ -2,6 +2,8 @@ add_library(KeyboardUI STATIC keyboardui.swift Key.swift Keyboard.swift + Candidate.swift + CandidateBar.swift ) set_target_properties(KeyboardUI PROPERTIES Swift_MODULE_NAME KeyboardUI) target_compile_options(KeyboardUI PUBLIC "$<$:-cxx-interoperability-mode=default>") diff --git a/uipanel/Candidate.swift b/uipanel/Candidate.swift new file mode 100644 index 0000000..e7c6dd2 --- /dev/null +++ b/uipanel/Candidate.swift @@ -0,0 +1,34 @@ +import UIKit + +class CandidateView: UICollectionViewCell { + static let identifier = "CandidateView" + + let wordLabel: UILabel = { + let label = UILabel() + label.textAlignment = .center + label.font = UIFont.systemFont(ofSize: 18) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + contentView.addSubview(wordLabel) + setupConstraints() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupConstraints() { + NSLayoutConstraint.activate([ + wordLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), + wordLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + ]) + } + + func configure(with word: String) { + wordLabel.text = word + } +} diff --git a/uipanel/CandidateBar.swift b/uipanel/CandidateBar.swift new file mode 100644 index 0000000..81e2b33 --- /dev/null +++ b/uipanel/CandidateBar.swift @@ -0,0 +1,93 @@ +import UIKit + +class CandidateCollectionView: UIView { + + var words = [String]() + + private var collectionView: UICollectionView! + + override init(frame: CGRect) { + super.init(frame: frame) + setupCollectionView() + setupConstraints() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupCollectionView() { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .horizontal + + collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.backgroundColor = UIColor.clear + collectionView.delegate = self + collectionView.dataSource = self + collectionView.register( + CandidateView.self, forCellWithReuseIdentifier: CandidateView.identifier) + + addSubview(collectionView) + } + + private func setupConstraints() { + NSLayoutConstraint.activate([ + collectionView.leadingAnchor.constraint(equalTo: leadingAnchor), + collectionView.trailingAnchor.constraint(equalTo: trailingAnchor), + collectionView.topAnchor.constraint(equalTo: topAnchor), + collectionView.bottomAnchor.constraint(equalTo: bottomAnchor), + collectionView.heightAnchor.constraint(equalToConstant: 35), + ]) + } + + func updateCandidates(_ candidates: [String]) { + words = candidates + collectionView.reloadData() + } +} + +extension CandidateCollectionView: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) + -> Int + { + return words.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) + -> UICollectionViewCell + { + guard + let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: CandidateView.identifier, for: indexPath) as? CandidateView + else { + return UICollectionViewCell() + } + cell.configure(with: words[indexPath.item]) + return cell + } +} + +extension CandidateCollectionView: UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + logger.error("Selected word: \(words[indexPath.item])") + } +} + +extension CandidateCollectionView: UICollectionViewDelegateFlowLayout { + func collectionView( + _ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, + sizeForItemAt indexPath: IndexPath + ) -> CGSize { + let word = words[indexPath.item] + let width = word.size(withAttributes: [.font: UIFont.systemFont(ofSize: 18)]).width + 20 + return CGSize(width: width, height: 35) + } + + func collectionView( + _ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, + minimumLineSpacingForSectionAt section: Int + ) -> CGFloat { + return 10 + } +} diff --git a/uipanel/keyboardui.swift b/uipanel/keyboardui.swift index 0d636b8..d9487d0 100644 --- a/uipanel/keyboardui.swift +++ b/uipanel/keyboardui.swift @@ -3,10 +3,14 @@ import OSLog import UIKit let logger = Logger(subsystem: "org.fcitx.Fcitx5", category: "FcitxLog") +let candidateCollectionView = CandidateCollectionView() private func setupMainLayout(_ client: FcitxProtocol) { let mainStackView = client.getView() + candidateCollectionView.translatesAutoresizingMaskIntoConstraints = false + mainStackView.addArrangedSubview(candidateCollectionView) + let keyboardView = Keyboard(client) keyboardView.translatesAutoresizingMaskIntoConstraints = false mainStackView.addArrangedSubview(keyboardView) @@ -21,3 +25,9 @@ public func showKeyboardAsync(_ clientPtr: UnsafeMutableRawPointer) { setupMainLayout(client) } } + +public func setCandidatesAsync(_ candidates: [String]) { + DispatchQueue.main.async { + candidateCollectionView.updateCandidates(candidates) + } +} diff --git a/uipanel/uipanel.cpp b/uipanel/uipanel.cpp index a16e59e..d318c73 100644 --- a/uipanel/uipanel.cpp +++ b/uipanel/uipanel.cpp @@ -21,15 +21,17 @@ void UIPanel::update(UserInterfaceComponent component, case UserInterfaceComponent::InputPanel: { const InputPanel &inputPanel = inputContext->inputPanel(); int size = 0; + auto candidates = swift::Array::init(); if (const auto &list = inputPanel.candidateList()) { size = list->size(); for (int i = 0; i < size; i++) { const auto &candidate = list->candidate(i); - FCITX_INFO() - << instance_->outputFilter(inputContext, candidate.text()) - .toString(); + candidates.append( + instance_->outputFilter(inputContext, candidate.text()) + .toString()); } } + KeyboardUI::setCandidatesAsync(candidates); break; } case UserInterfaceComponent::StatusArea: From ae88c708b7a30556807ec1e09fb033c7d5da201f Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Tue, 8 Oct 2024 23:22:47 -0400 Subject: [PATCH 2/3] update hallelujah --- engines/fcitx5-hallelujah | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/fcitx5-hallelujah b/engines/fcitx5-hallelujah index ac94e7d..82aafcd 160000 --- a/engines/fcitx5-hallelujah +++ b/engines/fcitx5-hallelujah @@ -1 +1 @@ -Subproject commit ac94e7d27f831704682863182d53583cf8f7cd6a +Subproject commit 82aafcdc020df3f6004c3055159c8a6fdc2aec2f From f47a9f56bd420c54a928a51e6d0ac56bfe648874 Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Tue, 8 Oct 2024 23:35:09 -0400 Subject: [PATCH 3/3] =?UTF-8?q?=E7=94=BB=E8=9B=87=E6=B7=BB=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uipanel/CandidateBar.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/uipanel/CandidateBar.swift b/uipanel/CandidateBar.swift index 81e2b33..23a2947 100644 --- a/uipanel/CandidateBar.swift +++ b/uipanel/CandidateBar.swift @@ -70,7 +70,6 @@ extension CandidateCollectionView: UICollectionViewDataSource { extension CandidateCollectionView: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - logger.error("Selected word: \(words[indexPath.item])") } }