Make already selected option in dropdown greyed out, and fixes for settings/defaults. #33
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user