From 0f14638aa81a3c485f2604204c458a50968fb37d Mon Sep 17 00:00:00 2001 From: Vegard Bieker Matthey Date: Thu, 30 Jul 2026 22:45:21 +0200 Subject: [PATCH] mark selected, and fix defaults --- ImageViewer/ViewController.swift | 177 +++++++++++++++++++++---------- 1 file changed, 120 insertions(+), 57 deletions(-) diff --git a/ImageViewer/ViewController.swift b/ImageViewer/ViewController.swift index 65a8fa4..a0d17a4 100644 --- a/ImageViewer/ViewController.swift +++ b/ImageViewer/ViewController.swift @@ -48,6 +48,7 @@ struct GlobalState: Codable { struct LocalState: Codable { var progress: ReadProgress var backgroundColor: String? + var useDefaultPageTurnMode: Bool } struct Settings: Codable { @@ -73,9 +74,10 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { var imageView = UIImageView() var mode = PageTurnMode.leftToRight + var useDefaultPageTurnMode = true + var useDefaultBackgroundColor = true var metadataList: [URL: Metadata] = [:] var metadata: Metadata! - var currentPage: Int! var progress = ProgressIndices(v: 0, c: 0, i: 0) var currentPath: URL! var lastLayoutSize: CGSize = .zero @@ -331,29 +333,25 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { } func convertColorToString(_ color: UIColor) -> String { - let r: String! switch color { - case .white: r = "White" - case .gray: r = "Gray" - case .black: r = "Black" - case .red: r = "Red" - case .blue: r = "Blue" - default: r = "Black" + case .white: return "White" + case .gray: return "Gray" + case .black: return "Black" + case .red: return "Red" + case .blue: return "Blue" + default: return "Black" } - return r } func convertStringToColor(_ str: String) -> UIColor { - let r: UIColor! switch str.lowercased() { - case "white": r = .white - case "gray": r = .gray - case "black": r = .black - case "red": r = .red - case "blue": r = .blue - default: r = .black + case "white": return .white + case "gray": return .gray + case "black": return .black + case "red": return .red + case "blue": return .blue + default: return .black } - return r } func imageSize(at url: URL) -> CGSize? { @@ -786,7 +784,8 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { do { try JSONEncoder().encode( LocalState( - progress: newProgress, backgroundColor: self.convertColorToString(color) + progress: newProgress, backgroundColor: self.convertColorToString(color), + useDefaultPageTurnMode: self.useDefaultPageTurnMode ) ).write( to: self.currentPath.appendingPathComponent("state.json") @@ -802,22 +801,23 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { let path = currentPath.appendingPathComponent("state.json").path if !fileManager.fileExists(atPath: path) { progress = ProgressIndices(v: 0, c: 0, i: 0) - mode = .leftToRight + mode = settings.defaultPageTurnMode return } let json = try Data(String(contentsOfFile: path).utf8) let local = try JSONDecoder().decode(LocalState.self, from: json) + useDefaultPageTurnMode = local.useDefaultPageTurnMode switch local.progress { case let .leftToRight(volumeIndex, chapterIndex, imageIndex): progress.v = volumeIndex progress.c = chapterIndex progress.i = imageIndex - mode = .leftToRight + mode = useDefaultPageTurnMode ? settings.defaultPageTurnMode : .leftToRight case let .rightToLeft(volumeIndex, chapterIndex, imageIndex): progress.v = volumeIndex progress.c = chapterIndex progress.i = imageIndex - mode = .rightToLeft + mode = useDefaultPageTurnMode ? settings.defaultPageTurnMode : .rightToLeft case let .scroll(point): if scrollPos == nil { scrollPos = point @@ -836,12 +836,14 @@ final class ViewController: UIViewController, UIGestureRecognizerDelegate { progress = theProgress } } - mode = .scroll + mode = useDefaultPageTurnMode ? settings.defaultPageTurnMode : .scroll } if let color = local.backgroundColor { readerView.backgroundColor = convertStringToColor(color) + useDefaultBackgroundColor = false } else { readerView.backgroundColor = convertStringToColor(settings.defaultReadingBackgroundColor) + useDefaultBackgroundColor = true } } catch let decodingError as DecodingError { print(decodingError.errorDescription!) @@ -2046,6 +2048,7 @@ struct SettingsMenuItem { let title: String let children: [SettingsMenuItem]? // non-nil = pushes another menu let action: (() -> Void)? // non-nil = leaf, performs an action + let selected: (() -> Bool)? } class SettingsMenuViewController: UITableViewController { @@ -2065,7 +2068,12 @@ class SettingsMenuViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") - preferredContentSize = CGSize(width: 220, height: items.count * 44) + preferredContentSize = CGSize(width: 330, height: items.count * 44) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + tableView.reloadData() } override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { @@ -2078,9 +2086,25 @@ class SettingsMenuViewController: UITableViewController { cell.textLabel?.text = item.title cell.accessoryType = item.children != nil ? .disclosureIndicator : .none + let isCurrent = item.selected?() ?? false + + if isCurrent { + cell.textLabel?.textColor = .gray + cell.accessoryType = .checkmark + cell.selectionStyle = .none + } else { + cell.accessoryType = item.children != nil ? .disclosureIndicator : .none + cell.selectionStyle = .default + } + return cell } + override func tableView(_: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { + let item = items[indexPath.row] + return (item.selected?() == true) ? nil : indexPath + } + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let item = items[indexPath.row] if let children = item.children { @@ -2093,52 +2117,88 @@ class SettingsMenuViewController: UITableViewController { } } +func convertPageTurnModeToString(_ pageTurnMode: PageTurnMode) -> String { + switch pageTurnMode { + case .leftToRight: return "Left to Right" + case .rightToLeft: return "Right to Left" + case .scroll: return "Scroll" + } +} + extension ViewController { private func colorItems(applyTo colorHandler: @escaping (UIColor) -> Void) -> [SettingsMenuItem] { - let items: [(String, UIColor)] = [("Black", .black), ("White", .white), ("Red", .red), ("Blue", .blue)] - return items.map { name, color in - SettingsMenuItem(title: name, children: nil, action: { [weak self] in + let items: [UIColor] = [.black, .white, .red, .blue] + return items.map { color in + SettingsMenuItem(title: convertColorToString(color), children: nil, action: { [weak self] in colorHandler(color) self?.dismiss(animated: false) - }) + }, + selected: { [weak self] in self?.readerView.backgroundColor == color }) } } private func colorDefaultItems(applyTo colorHandler: @escaping (UIColor) -> Void) -> [SettingsMenuItem] { - let items: [(String, UIColor)] = [ - ("Black", .black), ("White", .white), ("Red", .red), ("Blue", .blue), - ("Default", convertStringToColor(settings.defaultReadingBackgroundColor)), - ] - return items.map { name, color in - SettingsMenuItem(title: name, children: nil, action: { [weak self] in - colorHandler(color) - self?.dismiss(animated: false) - }) + let items: [UIColor?] = [.black, .white, .red, .blue, nil] + return items.map { color in + var title = "" + if let color = color { + title = convertColorToString(color) + } else { + title = "Default (\(settings.defaultReadingBackgroundColor))" + } + return SettingsMenuItem( + title: title, + children: nil, action: { [self] in + self.useDefaultBackgroundColor = color == nil + colorHandler(color ?? self.convertStringToColor(settings.defaultReadingBackgroundColor)) + self.dismiss(animated: false) + }, selected: { [self] in + if self.useDefaultBackgroundColor { return color == nil } + return color == self.readerView.backgroundColor && color != nil + } + ) } } private func pageTurnItems(applyTo pageTurnHandler: @escaping (PageTurnMode) -> Void) -> [SettingsMenuItem] { - let items: [(String, PageTurnMode)] = [ - ("Left to right", .leftToRight), ("Right to left", .rightToLeft), ("Scroll", .scroll), - ] - return items.map { name, pageTurnMode in - SettingsMenuItem(title: name, children: nil, action: { [weak self] in - pageTurnHandler(pageTurnMode) - self?.dismiss(animated: false) - }) + let items: [PageTurnMode] = [.leftToRight, .rightToLeft, .scroll] + return items.map { pageTurnMode in + SettingsMenuItem( + title: convertPageTurnModeToString(pageTurnMode), + children: nil, + action: { [self] in + pageTurnHandler(pageTurnMode) + self.dismiss(animated: false) + }, + selected: { [self] in + return self.mode == pageTurnMode + } + ) } } private func pageTurnDefaultItems(applyTo pageTurnHandler: @escaping (PageTurnMode) -> Void) -> [SettingsMenuItem] { - let items: [(String, PageTurnMode)] = [ - ("Left to right", .leftToRight), ("Right to left", .rightToLeft), ("Scroll", .scroll), - ("Default", settings.defaultPageTurnMode), - ] - return items.map { name, pageTurnMode in - SettingsMenuItem(title: name, children: nil, action: { [weak self] in - pageTurnHandler(pageTurnMode) - self?.dismiss(animated: false) - }) + let items: [PageTurnMode?] = [.leftToRight, .rightToLeft, .scroll, nil] + return items.map { pageTurnMode in + var title = "" + if let mode = pageTurnMode { + title = convertPageTurnModeToString(mode) + } else { + title = "Default (\(convertPageTurnModeToString(settings.defaultPageTurnMode)))" + } + return SettingsMenuItem( + title: title, + children: nil, action: { [self] in + self.useDefaultPageTurnMode = pageTurnMode == nil + let mode = pageTurnMode ?? self.settings.defaultPageTurnMode + pageTurnHandler(mode) + self.dismiss(animated: false) + }, + selected: { [self] in + if self.useDefaultPageTurnMode { return pageTurnMode == nil } + return self.mode == pageTurnMode && pageTurnMode != nil + } + ) } } @@ -2161,12 +2221,14 @@ extension ViewController { SettingsMenuItem( title: "Background Reading", children: defaultReadingBackgroundColor, - action: nil + action: nil, + selected: nil ), - SettingsMenuItem(title: "Background Home", children: backgroundColors, action: nil), - ], action: nil) + SettingsMenuItem(title: "Background Home", children: backgroundColors, action: nil, selected: nil), + ], action: nil, selected: nil) - let pageTurnMenu = SettingsMenuItem(title: "Page Turn Mode", children: defaultPageTurnMode, action: nil) + let pageTurnMenu = SettingsMenuItem(title: "Page Turn Mode", + children: defaultPageTurnMode, action: nil, selected: nil) return [colorsMenu, pageTurnMenu] } @@ -2201,6 +2263,7 @@ extension ViewController { private func makeBackgroundColorTree() -> [SettingsMenuItem] { return colorDefaultItems { [weak self] color in self?.readerView.backgroundColor = color + self?.saveLocalState() } } } -- 2.54.0