Skip to content

Commit

Permalink
Add go to object
Browse files Browse the repository at this point in the history
  • Loading branch information
levinli303 committed Apr 29, 2021
1 parent cc0df89 commit 52f32ea
Show file tree
Hide file tree
Showing 10 changed files with 329 additions and 7 deletions.
16 changes: 16 additions & 0 deletions MobileCelestia.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
EA1BC6E724A0E94900F3F51B /* EventFinderResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1BC6E624A0E94900F3F51B /* EventFinderResultViewController.swift */; };
EA28CA4E24A25FE7004B011E /* BottomControlViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA28CA4D24A25FE7004B011E /* BottomControlViewController.swift */; };
EA28CA5324A2F399004B011E /* Fonts in Resources */ = {isa = PBXBuildFile; fileRef = EA28CA5124A2F399004B011E /* Fonts */; };
EA374CD2263A8B320069589C /* GoToContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA374CD1263A8B320069589C /* GoToContainerViewController.swift */; };
EA374CDA263A8B770069589C /* GoToInputViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA374CD9263A8B770069589C /* GoToInputViewController.swift */; };
EA544E5F2566BC50003F351D /* DestinationDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA544E5E2566BC50003F351D /* DestinationDetailViewController.swift */; };
EA5E185D2477C78E00F5374B /* Toast.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E185B2477C78E00F5374B /* Toast.swift */; };
EA934C90251D90C500DD284C /* MainSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA934C8F251D90C500DD284C /* MainSceneDelegate.swift */; };
Expand Down Expand Up @@ -211,6 +213,8 @@
EA1EF056249393BE0039F493 /* Celestia.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Celestia.entitlements; sourceTree = "<group>"; };
EA28CA4D24A25FE7004B011E /* BottomControlViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomControlViewController.swift; sourceTree = "<group>"; };
EA28CA5124A2F399004B011E /* Fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Fonts; path = ../../../CelestiaCore/Fonts; sourceTree = "<group>"; };
EA374CD1263A8B320069589C /* GoToContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoToContainerViewController.swift; sourceTree = "<group>"; };
EA374CD9263A8B770069589C /* GoToInputViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoToInputViewController.swift; sourceTree = "<group>"; };
EA544E5E2566BC50003F351D /* DestinationDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestinationDetailViewController.swift; sourceTree = "<group>"; };
EA5E185B2477C78E00F5374B /* Toast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Toast.swift; sourceTree = "<group>"; };
EA934C8F251D90C500DD284C /* MainSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSceneDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -437,6 +441,7 @@
979D2F7C23FEB1A6005D2592 /* MobileCelestia */ = {
isa = PBXGroup;
children = (
EA374CCF263A8B1E0069589C /* GoTo */,
EABF790E253895DD00F2460C /* Resource */,
EAF4851D249B5C0F00E5B817 /* Common */,
97C3A9EF2445FAA100EB365A /* Celestia */,
Expand Down Expand Up @@ -531,6 +536,15 @@
path = Event;
sourceTree = "<group>";
};
EA374CCF263A8B1E0069589C /* GoTo */ = {
isa = PBXGroup;
children = (
EA374CD1263A8B320069589C /* GoToContainerViewController.swift */,
EA374CD9263A8B770069589C /* GoToInputViewController.swift */,
);
path = GoTo;
sourceTree = "<group>";
};
EABF790E253895DD00F2460C /* Resource */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -828,6 +842,7 @@
972477D52404A63800729B45 /* BrowserCommonViewController.swift in Sources */,
974F86E22403BD3C00356795 /* InfoViewController.swift in Sources */,
978406DF24029D9100876FD1 /* LoadingFailureViewController.swift in Sources */,
EA374CD2263A8B320069589C /* GoToContainerViewController.swift in Sources */,
EA1BC6E524A0E93D00F3F51B /* EventFinderInputViewController.swift in Sources */,
977394AC2403F07C00E38B82 /* SettingsCoordinatorController.swift in Sources */,
974F86E02403BD3C00356795 /* BodyDescriptionCell.swift in Sources */,
Expand All @@ -846,6 +861,7 @@
EABF791E2538986400F2460C /* AsyncListViewController.swift in Sources */,
97FF95AA240A3F0900E9F44F /* Data.swift in Sources */,
974F86DF2403BD3C00356795 /* BodyActionCell.swift in Sources */,
EA374CDA263A8B770069589C /* GoToInputViewController.swift in Sources */,
EA934C9A251D92AD00DD284C /* PanelSceneDelegate.swift in Sources */,
97EB41C62408F20700E6D441 /* CameraControlViewController.swift in Sources */,
977394B52403FD4400E38B82 /* SettingCheckViewController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import UIKit
import CelestiaCore

class EventFinderCoordinatorViewController: UIViewController {

private var main: SettingsMainViewController!
private var navigation: UINavigationController!

private let eventHandler: ((CelestiaEclipse) -> Void)
Expand All @@ -39,7 +37,6 @@ class EventFinderCoordinatorViewController: UIViewController {

setup()
}

}

private extension EventFinderCoordinatorViewController {
Expand Down
5 changes: 3 additions & 2 deletions MobileCelestia/Event/EventFinderInputViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class EventFinderInputViewController: BaseTableViewController {
[ProceedItem()]
]

private let selectableObjects = ["Earth", "Jupiter"]
private let selectableObjects = [LocalizedString("Earth", "celestia"), LocalizedString("Jupiter", "celestia")]

private let defaultSearchingInterval: TimeInterval = 365 * 24 * 60 * 60
private lazy var startTime = endTime.addingTimeInterval(-defaultSearchingInterval)
Expand Down Expand Up @@ -99,9 +99,10 @@ extension EventFinderInputViewController {
#else
cell.titleColor = UIColor.themeLabel
#endif
cell.detail = nil
} else if item is ObjectItem {
cell.titleColor = UIColor.darkLabel
cell.detail = LocalizedString(objectName, "celestia")
cell.detail = objectName
} else if let it = item as? DateItem {
cell.titleColor = UIColor.darkLabel
cell.detail = displayDateFormatter.string(from: it.isStartTime ? startTime : endTime)
Expand Down
54 changes: 54 additions & 0 deletions MobileCelestia/GoTo/GoToContainerViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// GoToContainerViewController.swift
//
// Copyright © 2021 Celestia Development Team. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//

import CelestiaCore
import UIKit

class GoToContainerViewController: UIViewController {
private var navigation: UINavigationController!

private let locationHandler: ((CelestiaGoToLocation) -> Void)

init(locationHandler: @escaping ((CelestiaGoToLocation) -> Void)) {
self.locationHandler = locationHandler
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func loadView() {
view = UIView()
view.backgroundColor = .darkBackground
}

override func viewDidLoad() {
super.viewDidLoad()

setup()
}
}

private extension GoToContainerViewController {
func setup() {
navigation = UINavigationController(rootViewController: GoToInputViewController { [weak self] location in
guard let self = self else { return }
self.locationHandler(location)
})

install(navigation)

navigation.navigationBar.barStyle = .black
navigation.navigationBar.barTintColor = .black
navigation.navigationBar.titleTextAttributes?[.foregroundColor] = UIColor.darkLabel
}
}
219 changes: 219 additions & 0 deletions MobileCelestia/GoTo/GoToInputViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
//
// GoToInputViewController.swift
//
// Copyright © 2021 Celestia Development Team. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//

import CelestiaCore
import UIKit

protocol GoToInputItem {
var title: String { get }
var detail: String { get }
}

private extension SimulationDistanceUnit {
var name: String {
switch self {
case .AU:
return "au"
case .KM:
return "km"
case .radii:
return "radii"
@unknown default:
fatalError()
}
}
}

class GoToInputViewController: BaseTableViewController {
struct FloatValueItem: GoToInputItem {
enum ValueType {
case longitude
case latitude
}
let title: String
let value: Float
let type: ValueType

var detail: String { return String(format: "%.2f", value) }
}

struct DoubleValueItem: GoToInputItem {
enum ValueType {
case distance
}
let title: String
let value: Double
let type: ValueType

var detail: String { return String(format: "%.2f", value) }
}

struct UnitItem: GoToInputItem {
var title: String { "" }

var detail: String { CelestiaString(unit.name, comment: "") }

let unit: SimulationDistanceUnit
}

struct ProcceedItem: GoToInputItem {
var title: String { CelestiaString("Go", comment: "") }

var detail: String { "" }
}

struct ObjectNameItem: GoToInputItem {
var title: String { CelestiaString("Object", comment: "") }

var detail: String { name }

let name: String
}

private let locationHandler: ((CelestiaGoToLocation) -> Void)

private var objectName: String = LocalizedString("Earth", "celestia")
private var longitude: Float = 0
private var latitude: Float = 0

private var distance: Double = 8
private var unit: SimulationDistanceUnit = .radii

private let core = CelestiaAppCore.shared

private static let availableUnits: [SimulationDistanceUnit] = [.radii, .KM, .AU]

private var allSections: [[GoToInputItem]] = []

init(locationHandler: @escaping ((CelestiaGoToLocation) -> Void)) {
self.locationHandler = locationHandler
super.init(style: .defaultGrouped)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}


override func viewDidLoad() {
super.viewDidLoad()

setUp()
}
}

private extension GoToInputViewController {
func setUp() {
title = CelestiaString("Go to Object", comment: "")
tableView.register(SettingTextCell.self, forCellReuseIdentifier: "Text")

reload()
}

private func reload() {
allSections = [
[ObjectNameItem(name: objectName)],
[
FloatValueItem(title: CelestiaString("Longitude", comment: ""), value: longitude, type: .longitude),
FloatValueItem(title: CelestiaString("Latitude", comment: ""), value: latitude, type: .latitude)
],
[
DoubleValueItem(title: CelestiaString("Distance", comment: ""), value: distance, type: .distance),
UnitItem(unit: unit)
],
[ProcceedItem()]
]
tableView.reloadData()
}
}

extension GoToInputViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return allSections.count
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allSections[section].count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = allSections[indexPath.section][indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Text", for: indexPath) as! SettingTextCell
cell.title = item.title
cell.detail = item.detail

if item is ProcceedItem {
#if targetEnvironment(macCatalyst)
cell.titleColor = cell.tintColor
#else
cell.titleColor = UIColor.themeLabel
#endif
} else {
cell.titleColor = UIColor.darkLabel
}

return cell
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let item = allSections[indexPath.section][indexPath.row]
if let objectItem = item as? ObjectNameItem {
showTextInput(CelestiaString("Please enter an object name.", comment: ""), text: objectItem.name) { [weak self] text in
guard let self = self else { return }
guard let objectName = text else { return }
self.objectName = objectName
self.reload()
}
} else if item is UnitItem {
guard let cell = tableView.cellForRow(at: indexPath) else { return }
showSelection(nil, options: Self.availableUnits.map({ CelestiaString($0.name, comment: "") }), sourceView: cell, sourceRect: cell.bounds) { [weak self] index in
guard let self = self else { return }
guard let newIndex = index else { return }
self.unit = Self.availableUnits[newIndex]
self.reload()
}
} else if let valueItem = item as? DoubleValueItem {
showTextInput("", text: item.detail) { [weak self] string in
guard let self = self else { return }
guard let newString = string, let value = Double(newString) else { return }
switch valueItem.type {
case .distance:
self.distance = value
}
self.reload()
}
} else if let valueItem = item as? FloatValueItem {
showTextInput("", text: item.detail) { [weak self] string in
guard let self = self else { return }
guard let newString = string, let value = Float(newString) else { return }
switch valueItem.type {
case .longitude:
self.longitude = value
case .latitude:
self.latitude = value
}
self.reload()
}
} else if item is ProcceedItem {
let selection = core.simulation.findObject(from: objectName)
guard !selection.isEmpty else {
showError(CelestiaString("Object not found", comment: ""))
return
}
locationHandler(CelestiaGoToLocation(selection: selection, longitude: longitude, latitude: latitude, distance: distance, unit: unit))
}
}
}
Loading

0 comments on commit 52f32ea

Please sign in to comment.