Skip to content

Commit

Permalink
Change free text annotation font size to float (#1000)
Browse files Browse the repository at this point in the history
* Change free text annotation font size to float

* Move free text annotation general parameters to AnnotationsConfig
  • Loading branch information
mvasilak authored Aug 26, 2024
1 parent dc0821a commit 1d39208
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 124 deletions.
5 changes: 3 additions & 2 deletions Zotero/Controllers/AnnotationConverter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct AnnotationConverter {
var text: String?
let paths: [[CGPoint]]
var lineWidth: CGFloat?
var fontSize: UInt?
var fontSize: CGFloat?
var rotation: UInt?

if let annotation = annotation as? PSPDFKit.NoteAnnotation {
Expand Down Expand Up @@ -112,7 +112,8 @@ struct AnnotationConverter {
paths = []
} else if let annotation = annotation as? PSPDFKit.FreeTextAnnotation {
type = .freeText
fontSize = UInt(annotation.fontSize)
let roundedFontSize = AnnotationsConfig.roundFreeTextAnnotationFontSize(annotation.fontSize)
fontSize = roundedFontSize
rotation = annotation.rotation
paths = []
rects = self.rects(fromTextAnnotation: annotation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import RealmSwift
struct EditAnnotationFontSizeDbRequest: DbRequest {
let key: String
let libraryId: LibraryIdentifier
let size: UInt
let size: CGFloat

var needsWrite: Bool { return true }

Expand Down
7 changes: 7 additions & 0 deletions Zotero/Models/AnnotationsConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ struct AnnotationsConfig {
static let keyKey = "Zotero:Key"
// Line width of image annotation in PDF document.
static let imageAnnotationLineWidth: CGFloat = 2
// Free text annotation font size minimum, maximum, increment and rounding
static let freeTextAnnotationFontSizeMinimum: CGFloat = 1
static let freeTextAnnotationFontSizeMaximum: CGFloat = 200
static let freeTextAnnotationFontSizeIncrement: CGFloat = 0.5
static func roundFreeTextAnnotationFontSize(_ fontSize: CGFloat) -> CGFloat {
round(fontSize * 2) / 2
}
// Size of note annotation in PDF document.
static let noteAnnotationSize: CGSize = CGSize(width: 22, height: 22)
static let positionSizeLimit = 65000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ protocol AnnotationPopoverAnnotationCoordinatorDelegate: AnyObject {
func createShareAnnotationMenu(sender: UIButton) -> UIMenu?
func showEdit(state: AnnotationPopoverState, saveAction: @escaping AnnotationEditSaveAction, deleteAction: @escaping AnnotationEditDeleteAction)
func showTagPicker(libraryId: LibraryIdentifier, selected: Set<String>, picked: @escaping ([Tag]) -> Void)
func showFontSizePicker(picked: @escaping (UInt) -> Void)
func showFontSizePicker(picked: @escaping (CGFloat) -> Void)
func didFinish()
}

protocol AnnotationEditCoordinatorDelegate: AnyObject {
func showPageLabelEditor(label: String, updateSubsequentPages: Bool, saveAction: @escaping AnnotationPageLabelSaveAction)
func showFontSizePicker(picked: @escaping (UInt) -> Void)
func showFontSizePicker(picked: @escaping (CGFloat) -> Void)
}

final class AnnotationPopoverCoordinator: NSObject, Coordinator {
Expand Down Expand Up @@ -64,7 +64,7 @@ final class AnnotationPopoverCoordinator: NSObject, Coordinator {
}

extension AnnotationPopoverCoordinator: AnnotationPopoverAnnotationCoordinatorDelegate {
func showFontSizePicker(picked: @escaping (UInt) -> Void) {
func showFontSizePicker(picked: @escaping (CGFloat) -> Void) {
let controller = FontSizePickerViewController(pickAction: picked)
self.navigationController?.pushViewController(controller, animated: true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ enum AnnotationEditAction {
case setLineWidth(CGFloat)
case setPageLabel(String, Bool)
case setHighlight(NSAttributedString)
case setFontSize(UInt)
case setFontSize(CGFloat)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct AnnotationEditState: ViewModelState {
let pageLabel: String
let highlightText: NSAttributedString
let highlightFont: UIFont
let fontSize: UInt?
let fontSize: CGFloat?
}

struct Changes: OptionSet {
Expand All @@ -35,7 +35,7 @@ struct AnnotationEditState: ViewModelState {
var color: String
var lineWidth: CGFloat
var pageLabel: String
var fontSize: UInt
var fontSize: CGFloat
var highlightText: NSAttributedString
var highlightFont: UIFont
var updateSubsequentLabels: Bool
Expand Down
22 changes: 11 additions & 11 deletions Zotero/Scenes/Detail/Annotation Popover/Views/FontSizeCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,35 @@ import RxSwift

class FontSizeCell: RxTableViewCell {
private weak var fontSizeView: FontSizeView!
var tapObservable: PublishSubject<()> { return self.fontSizeView.tapObservable }
var valueObservable: PublishSubject<UInt> { return self.fontSizeView.valueObservable }
var tapObservable: PublishSubject<()> { return fontSizeView.tapObservable }
var valueObservable: PublishSubject<CGFloat> { return fontSizeView.valueObservable }

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.setup()
setup()
}

required init?(coder: NSCoder) {
super.init(coder: coder)
self.setup()
setup()
}

func set(value: UInt) {
self.fontSizeView.value = value
func set(value: CGFloat) {
fontSizeView.value = value
}

private func setup() {
let fontSizeView = FontSizeView(contentInsets: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16), stepperEnabled: true)
fontSizeView.translatesAutoresizingMaskIntoConstraints = false
fontSizeView.button.isUserInteractionEnabled = false
self.fontSizeView = fontSizeView
self.contentView.addSubview(fontSizeView)
contentView.addSubview(fontSizeView)

NSLayoutConstraint.activate([
self.contentView.topAnchor.constraint(equalTo: fontSizeView.topAnchor),
self.contentView.bottomAnchor.constraint(equalTo: fontSizeView.bottomAnchor),
self.contentView.leadingAnchor.constraint(equalTo: fontSizeView.leadingAnchor),
self.contentView.trailingAnchor.constraint(equalTo: fontSizeView.trailingAnchor)
contentView.topAnchor.constraint(equalTo: fontSizeView.topAnchor),
contentView.bottomAnchor.constraint(equalTo: fontSizeView.bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: fontSizeView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: fontSizeView.trailingAnchor)
])
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import UIKit
import RxSwift

class FontSizePickerViewController: UIViewController {
private static let sizes: [UInt] = [
private static let sizes: [CGFloat] = [
10,
12,
14,
Expand All @@ -26,15 +26,15 @@ class FontSizePickerViewController: UIViewController {
192
]

private let pickAction: (UInt) -> Void
private let pickAction: (CGFloat) -> Void
private let disposeBag: DisposeBag

private weak var tableView: UITableView!
private var dataSource: UITableViewDiffableDataSource<Int, UInt>!
private var dataSource: UITableViewDiffableDataSource<Int, CGFloat>!

init(pickAction: @escaping (UInt) -> Void) {
init(pickAction: @escaping (CGFloat) -> Void) {
self.pickAction = pickAction
self.disposeBag = DisposeBag()
disposeBag = DisposeBag()
super.init(nibName: nil, bundle: nil)
}

Expand All @@ -50,7 +50,7 @@ class FontSizePickerViewController: UIViewController {
setupSizes()

func setupSizes() {
var snapshot = NSDiffableDataSourceSnapshot<Int, UInt>()
var snapshot = NSDiffableDataSourceSnapshot<Int, CGFloat>()
snapshot.appendSections([0])
snapshot.appendItems(FontSizePickerViewController.sizes)
dataSource.apply(snapshot, animatingDifferences: false)
Expand All @@ -66,7 +66,7 @@ class FontSizePickerViewController: UIViewController {
cell.contentConfiguration = configuration
return cell
})
tableView.dataSource = self.dataSource
tableView.dataSource = dataSource
tableView.delegate = self
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
Expand All @@ -87,32 +87,32 @@ class FontSizePickerViewController: UIViewController {
cancel
.rx
.tap
.subscribe(with: self, onNext: { `self`, _ in
self.navigationController?.presentingViewController?.dismiss(animated: true)
.subscribe(onNext: { [weak self] _ in
self?.navigationController?.presentingViewController?.dismiss(animated: true)
})
.disposed(by: disposeBag)
self.navigationItem.leftBarButtonItem = cancel
navigationItem.leftBarButtonItem = cancel
}
}

override func loadView() {
self.view = UIView()
view = UIView()
}
}

extension FontSizePickerViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard let size = dataSource.itemIdentifier(for: indexPath) else { return }
self.pickAction(size)
pickAction(size)
if let controller = navigationController {
if controller.viewControllers.count == 1 {
controller.presentingViewController?.dismiss(animated: true)
} else {
controller.popViewController(animated: true)
}
} else {
self.presentingViewController?.dismiss(animated: true)
presentingViewController?.dismiss(animated: true)
}
}
}
68 changes: 34 additions & 34 deletions Zotero/Scenes/Detail/Annotation Popover/Views/FontSizeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,84 +15,84 @@ final class FontSizeView: UIView {
private let contentInsets: UIEdgeInsets
private let disposeBag: DisposeBag
let tapObservable: PublishSubject<()>
let valueObservable: PublishSubject<UInt>
let valueObservable: PublishSubject<CGFloat>

var stepperEnabled: Bool {
didSet {
self.stepper.isHidden = !self.stepperEnabled
stepper.isHidden = !stepperEnabled
}
}
private(set) weak var button: UIButton!
private weak var stepper: UIStepper!

var value: UInt {
var value: CGFloat {
get {
return UInt(self.stepper.value)
return CGFloat(stepper.value)
}

set {
self.stepper.value = Double(newValue)
self.updateLabel(with: newValue)
stepper.value = Double(newValue)
updateLabel(with: newValue)
}
}

init(contentInsets: UIEdgeInsets, stepperEnabled: Bool) {
self.contentInsets = contentInsets
self.stepperEnabled = stepperEnabled
self.disposeBag = DisposeBag()
self.tapObservable = PublishSubject()
self.valueObservable = PublishSubject()
disposeBag = DisposeBag()
tapObservable = PublishSubject()
valueObservable = PublishSubject()
super.init(frame: CGRect())
self.setup()
setup()
}

required init?(coder: NSCoder) {
self.contentInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
self.stepperEnabled = true
self.disposeBag = DisposeBag()
self.tapObservable = PublishSubject()
self.valueObservable = PublishSubject()
contentInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
stepperEnabled = true
disposeBag = DisposeBag()
tapObservable = PublishSubject()
valueObservable = PublishSubject()
super.init(coder: coder)
self.setup()
setup()
}

// MARK: - Actions

private func stepChanged() {
let value = UInt(self.stepper.value)
self.updateLabel(with: value)
self.valueObservable.on(.next(value))
let value = CGFloat(stepper.value)
updateLabel(with: value)
valueObservable.on(.next(value))
}

private func updateLabel(with value: UInt) {
private func updateLabel(with value: CGFloat) {
let valueString = "\(value)"
let ptString = "pt"
let attributedString = NSMutableAttributedString(string: valueString + ptString)
attributedString.addAttributes([.font: UIFont.preferredFont(forTextStyle: .body), .foregroundColor: UIColor.label], range: NSRange(location: 0, length: valueString.count))
attributedString.addAttributes([.font: UIFont.preferredFont(forTextStyle: .callout), .foregroundColor: UIColor.darkGray], range: NSRange(location: valueString.count, length: ptString.count))
self.button.setAttributedTitle(attributedString, for: .normal)
button.setAttributedTitle(attributedString, for: .normal)
}

// MARK: - Setups

private func setup() {
let stepper = UIStepper()
stepper.isHidden = !self.stepperEnabled
stepper.stepValue = 1
stepper.minimumValue = 1
stepper.maximumValue = 200
stepper.isHidden = !stepperEnabled
stepper.stepValue = AnnotationsConfig.freeTextAnnotationFontSizeIncrement
stepper.minimumValue = AnnotationsConfig.freeTextAnnotationFontSizeMinimum
stepper.maximumValue = AnnotationsConfig.freeTextAnnotationFontSizeMaximum
stepper.rx.controlEvent(.valueChanged)
.observe(on: MainScheduler.instance)
.subscribe(with: self, onNext: { `self`, _ in
self.stepChanged()
.subscribe(onNext: { [weak self] _ in
self?.stepChanged()
})
.disposed(by: self.disposeBag)
.disposed(by: disposeBag)
self.stepper = stepper

let button = UIButton()
button.contentHorizontalAlignment = .leading
button.titleLabel?.adjustsFontForContentSizeCategory = true
button.rx.tap.bind(to: self.tapObservable).disposed(by: self.disposeBag)
button.rx.tap.bind(to: tapObservable).disposed(by: disposeBag)
self.button = button

let container = UIStackView(arrangedSubviews: [button, stepper])
Expand All @@ -101,13 +101,13 @@ final class FontSizeView: UIView {
container.spacing = 12
container.translatesAutoresizingMaskIntoConstraints = false

self.addSubview(container)
addSubview(container)

NSLayoutConstraint.activate([
container.topAnchor.constraint(equalTo: self.topAnchor, constant: self.contentInsets.top),
self.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: self.contentInsets.bottom),
container.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: self.contentInsets.left),
self.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: self.contentInsets.right)
container.topAnchor.constraint(equalTo: topAnchor, constant: contentInsets.top),
bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: contentInsets.bottom),
container.leadingAnchor.constraint(equalTo: leadingAnchor, constant: contentInsets.left),
trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: contentInsets.right)
])
}
}
2 changes: 1 addition & 1 deletion Zotero/Scenes/Detail/PDF/AnnotationEditCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ final class AnnotationEditCoordinator: Coordinator {
}

extension AnnotationEditCoordinator: AnnotationEditCoordinatorDelegate {
func showFontSizePicker(picked: @escaping (UInt) -> Void) {
func showFontSizePicker(picked: @escaping (CGFloat) -> Void) {
let controller = FontSizePickerViewController(pickAction: picked)
self.navigationController?.pushViewController(controller, animated: true)
}
Expand Down
2 changes: 1 addition & 1 deletion Zotero/Scenes/Detail/PDF/Models/PDFAnnotation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protocol PDFAnnotation {
var color: String { get }
var comment: String { get }
var text: String? { get }
var fontSize: UInt? { get }
var fontSize: CGFloat? { get }
var rotation: UInt? { get }
var sortIndex: String { get }
var dateModified: Date { get }
Expand Down
4 changes: 2 additions & 2 deletions Zotero/Scenes/Detail/PDF/Models/PDFDatabaseAnnotation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ struct PDFDatabaseAnnotation {
return item.fields.filter(.key(FieldKeys.Item.Annotation.text)).first?.value
}

var fontSize: UInt? {
return (item.fields.filter(.key(FieldKeys.Item.Annotation.Position.fontSize)).first?.value).flatMap(UInt.init)
var fontSize: CGFloat? {
return (item.fields.filter(.key(FieldKeys.Item.Annotation.Position.fontSize)).first?.value).flatMap(Double.init).flatMap(CGFloat.init)
}

var rotation: UInt? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct PDFDocumentAnnotation {
let color: String
let comment: String
let text: String?
var fontSize: UInt?
var fontSize: CGFloat?
var rotation: UInt?
let sortIndex: String
let dateModified: Date
Expand Down
Loading

0 comments on commit 1d39208

Please sign in to comment.