diff --git a/OctoPod.xcodeproj/project.pbxproj b/OctoPod.xcodeproj/project.pbxproj index f4a3fe30..d51b1568 100644 --- a/OctoPod.xcodeproj/project.pbxproj +++ b/OctoPod.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 3D01E29220F3DE850020DE41 /* JobInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D01E29120F3DE850020DE41 /* JobInfoViewController.swift */; }; 3D0E1C9D20E819B00036B5FE /* CameraEmbeddedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D0E1C9C20E819B00036B5FE /* CameraEmbeddedViewController.swift */; }; 3D0E1C9F20E85EDF0036B5FE /* SetTargetTempViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D0E1C9E20E85EDF0036B5FE /* SetTargetTempViewController.swift */; }; + 3D0E3B1121097E7A0087F7E4 /* ThemeUIUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D0E3B1021097E7A0087F7E4 /* ThemeUIUtils.swift */; }; 3D0FA48321047AFA0084FF52 /* FilesTreeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D0FA48221047AFA0084FF52 /* FilesTreeViewController.swift */; }; 3D36DD7A210300C500884BD6 /* TerminalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D36DD79210300C500884BD6 /* TerminalViewController.swift */; }; 3D4508A320F956AD00AC0EC8 /* OctoPrintClientDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D4508A220F956AD00AC0EC8 /* OctoPrintClientDelegate.swift */; }; @@ -18,12 +19,18 @@ 3D45280A20E15A370094CCB7 /* OctoPod.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3D45280820E15A370094CCB7 /* OctoPod.xcdatamodeld */; }; 3D45280C20E15A380094CCB7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3D45280B20E15A380094CCB7 /* Assets.xcassets */; }; 3D45280F20E15A380094CCB7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3D45280D20E15A380094CCB7 /* LaunchScreen.storyboard */; }; + 3D6350EA21080AD3001C10F7 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D6350E921080AD3001C10F7 /* Theme.swift */; }; + 3D6350F121082E07001C10F7 /* AppearanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D6350F021082E07001C10F7 /* AppearanceViewController.swift */; }; + 3D6350F321083BE0001C10F7 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D6350F221083BE0001C10F7 /* TabBarController.swift */; }; + 3D6350F721084334001C10F7 /* ThemedDynamicUITableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D6350F621084334001C10F7 /* ThemedDynamicUITableViewController.swift */; }; 3D78BA9F21039D770090D79A /* Terminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D78BA9E21039D770090D79A /* Terminal.swift */; }; 3D78BAA12103C7CA0090D79A /* MoveViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D78BAA02103C7CA0090D79A /* MoveViewController.swift */; }; 3D82873720E3EBC80035AE0B /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D82873620E3EBC80035AE0B /* Printer.swift */; }; 3D82873920E3EC3B0035AE0B /* PrinterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D82873820E3EC3B0035AE0B /* PrinterManager.swift */; }; 3D82873B20E407370035AE0B /* PrintersTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D82873A20E407370035AE0B /* PrintersTableViewController.swift */; }; 3D82874120E421610035AE0B /* MjpegStreamingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D82873F20E421610035AE0B /* MjpegStreamingController.swift */; }; + 3D831E53210850E60004B7A5 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D831E52210850E60004B7A5 /* SettingsViewController.swift */; }; + 3D831E552108540E0004B7A5 /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D831E542108540E0004B7A5 /* NavigationController.swift */; }; 3D8873F820F534C400DCE987 /* PrintFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D8873F720F534C400DCE987 /* PrintFile.swift */; }; 3D8873FA20F5BD2700DCE987 /* FileDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D8873F920F5BD2700DCE987 /* FileDetailsViewController.swift */; }; 3D8B292A20E54F7300296D9D /* PanelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D8B292920E54F7300296D9D /* PanelViewController.swift */; }; @@ -38,6 +45,8 @@ 3DBAE49F20E6821900D2137D /* SelectDefaultPrinterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBAE49E20E6821900D2137D /* SelectDefaultPrinterViewController.swift */; }; 3DBAE4A120E69D4900D2137D /* CurrentStateEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBAE4A020E69D4900D2137D /* CurrentStateEvent.swift */; }; 3DBAE4A320E6A02A00D2137D /* WebSocketClientDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBAE4A220E6A02A00D2137D /* WebSocketClientDelegate.swift */; }; + 3DD9E9572108479000726DFD /* ThemedStaticUITableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DD9E9562108479000726DFD /* ThemedStaticUITableViewController.swift */; }; + 3DD9E95921084BFD00726DFD /* ThemedUITableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DD9E95821084BFD00726DFD /* ThemedUITableViewController.swift */; }; 3DF232E020F150CC00550652 /* MoveSubViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF232DF20F150CC00550652 /* MoveSubViewController.swift */; }; 8267C0CF229350E955F7AF71 /* Pods_OctoPod.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BDF04586ED8A4BC29EF06604 /* Pods_OctoPod.framework */; }; /* End PBXBuildFile section */ @@ -46,6 +55,7 @@ 3D01E29120F3DE850020DE41 /* JobInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JobInfoViewController.swift; sourceTree = ""; }; 3D0E1C9C20E819B00036B5FE /* CameraEmbeddedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraEmbeddedViewController.swift; sourceTree = ""; }; 3D0E1C9E20E85EDF0036B5FE /* SetTargetTempViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetTargetTempViewController.swift; sourceTree = ""; }; + 3D0E3B1021097E7A0087F7E4 /* ThemeUIUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeUIUtils.swift; sourceTree = ""; }; 3D0FA48221047AFA0084FF52 /* FilesTreeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilesTreeViewController.swift; sourceTree = ""; }; 3D36DD79210300C500884BD6 /* TerminalViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalViewController.swift; sourceTree = ""; }; 3D4508A220F956AD00AC0EC8 /* OctoPrintClientDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OctoPrintClientDelegate.swift; sourceTree = ""; }; @@ -56,6 +66,10 @@ 3D45280B20E15A380094CCB7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 3D45280E20E15A380094CCB7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 3D45281020E15A380094CCB7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3D6350E921080AD3001C10F7 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; + 3D6350F021082E07001C10F7 /* AppearanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceViewController.swift; sourceTree = ""; }; + 3D6350F221083BE0001C10F7 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + 3D6350F621084334001C10F7 /* ThemedDynamicUITableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemedDynamicUITableViewController.swift; sourceTree = ""; }; 3D78BA9E21039D770090D79A /* Terminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Terminal.swift; sourceTree = ""; }; 3D78BAA02103C7CA0090D79A /* MoveViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveViewController.swift; sourceTree = ""; }; 3D82873620E3EBC80035AE0B /* Printer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Printer.swift; sourceTree = ""; }; @@ -63,6 +77,8 @@ 3D82873A20E407370035AE0B /* PrintersTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrintersTableViewController.swift; sourceTree = ""; }; 3D82873F20E421610035AE0B /* MjpegStreamingController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MjpegStreamingController.swift; sourceTree = ""; }; 3D82874020E421610035AE0B /* MjpegStreamingKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MjpegStreamingKit.h; sourceTree = ""; }; + 3D831E52210850E60004B7A5 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; + 3D831E542108540E0004B7A5 /* NavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = ""; }; 3D8873F720F534C400DCE987 /* PrintFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrintFile.swift; sourceTree = ""; }; 3D8873F920F5BD2700DCE987 /* FileDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileDetailsViewController.swift; sourceTree = ""; }; 3D8B292920E54F7300296D9D /* PanelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelViewController.swift; sourceTree = ""; }; @@ -77,6 +93,8 @@ 3DBAE49E20E6821900D2137D /* SelectDefaultPrinterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectDefaultPrinterViewController.swift; sourceTree = ""; }; 3DBAE4A020E69D4900D2137D /* CurrentStateEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentStateEvent.swift; sourceTree = ""; }; 3DBAE4A220E6A02A00D2137D /* WebSocketClientDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSocketClientDelegate.swift; sourceTree = ""; }; + 3DD9E9562108479000726DFD /* ThemedStaticUITableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemedStaticUITableViewController.swift; sourceTree = ""; }; + 3DD9E95821084BFD00726DFD /* ThemedUITableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemedUITableViewController.swift; sourceTree = ""; }; 3DF232DF20F150CC00550652 /* MoveSubViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveSubViewController.swift; sourceTree = ""; }; A9F913620E58D596BED0BDF3 /* Pods_OctoPod.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OctoPod.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BDF04586ED8A4BC29EF06604 /* Pods_OctoPod.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OctoPod.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -105,14 +123,16 @@ name = Frameworks; sourceTree = ""; }; - 3D0E1CA020E8670C0036B5FE /* Setup UI */ = { + 3D0E1CA020E8670C0036B5FE /* Settings UI */ = { isa = PBXGroup; children = ( + 3D831E52210850E60004B7A5 /* SettingsViewController.swift */, 3D82873A20E407370035AE0B /* PrintersTableViewController.swift */, 3D968DE020E34612006774A5 /* PrinterDetailsViewController.swift */, 3D968DDC20E337C7006774A5 /* ScannerViewController.swift */, + 3D6350F021082E07001C10F7 /* AppearanceViewController.swift */, ); - path = "Setup UI"; + path = "Settings UI"; sourceTree = ""; }; 3D0E1CA120E8674D0036B5FE /* Panel UI */ = { @@ -123,6 +143,7 @@ 3D0E1C9C20E819B00036B5FE /* CameraEmbeddedViewController.swift */, 3D0E1C9E20E85EDF0036B5FE /* SetTargetTempViewController.swift */, 3D01E29120F3DE850020DE41 /* JobInfoViewController.swift */, + 3DBAE49E20E6821900D2137D /* SelectDefaultPrinterViewController.swift */, ); path = "Panel UI"; sourceTree = ""; @@ -160,13 +181,15 @@ 3D82873E20E421480035AE0B /* MJPEG Streaming */, 3D8B292E20E5542800296D9D /* OctoPrint */, 3D82873520E3EB730035AE0B /* Model */, - 3D45280120E15A370094CCB7 /* AppDelegate.swift */, + 3D6350EB210822C0001C10F7 /* Themes */, 3D0E1CA120E8674D0036B5FE /* Panel UI */, 3DF232DE20F150A900550652 /* Move UI */, 3DC57D5B20F4190B0061A87E /* File UI */, 3D36DD782103008F00884BD6 /* Terminal UI */, - 3D0E1CA020E8670C0036B5FE /* Setup UI */, - 3DBAE49E20E6821900D2137D /* SelectDefaultPrinterViewController.swift */, + 3D0E1CA020E8670C0036B5FE /* Settings UI */, + 3D831E542108540E0004B7A5 /* NavigationController.swift */, + 3D6350F221083BE0001C10F7 /* TabBarController.swift */, + 3D45280120E15A370094CCB7 /* AppDelegate.swift */, 3D45280520E15A370094CCB7 /* Main.storyboard */, 3D45280B20E15A380094CCB7 /* Assets.xcassets */, 3D45280D20E15A380094CCB7 /* LaunchScreen.storyboard */, @@ -176,6 +199,18 @@ path = OctoPod; sourceTree = ""; }; + 3D6350EB210822C0001C10F7 /* Themes */ = { + isa = PBXGroup; + children = ( + 3D6350E921080AD3001C10F7 /* Theme.swift */, + 3DD9E95821084BFD00726DFD /* ThemedUITableViewController.swift */, + 3D6350F621084334001C10F7 /* ThemedDynamicUITableViewController.swift */, + 3DD9E9562108479000726DFD /* ThemedStaticUITableViewController.swift */, + 3D0E3B1021097E7A0087F7E4 /* ThemeUIUtils.swift */, + ); + path = Themes; + sourceTree = ""; + }; 3D82873520E3EB730035AE0B /* Model */ = { isa = PBXGroup; children = ( @@ -350,16 +385,22 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3D0E3B1121097E7A0087F7E4 /* ThemeUIUtils.swift in Sources */, 3D36DD7A210300C500884BD6 /* TerminalViewController.swift in Sources */, 3D4508A320F956AD00AC0EC8 /* OctoPrintClientDelegate.swift in Sources */, 3D8B293220E556D400296D9D /* OctoPrintClient.swift in Sources */, 3DBAE49F20E6821900D2137D /* SelectDefaultPrinterViewController.swift in Sources */, 3D82874120E421610035AE0B /* MjpegStreamingController.swift in Sources */, + 3D831E53210850E60004B7A5 /* SettingsViewController.swift in Sources */, 3D98C1DA20E5D096007BB13F /* WebSocketClient.swift in Sources */, 3D82873720E3EBC80035AE0B /* Printer.swift in Sources */, + 3D6350F121082E07001C10F7 /* AppearanceViewController.swift in Sources */, 3D8873F820F534C400DCE987 /* PrintFile.swift in Sources */, + 3DD9E9572108479000726DFD /* ThemedStaticUITableViewController.swift in Sources */, 3D8B293020E5549B00296D9D /* HTTPClient.swift in Sources */, 3D8B292D20E5514A00296D9D /* PrinterSubpanelViewController.swift in Sources */, + 3D831E552108540E0004B7A5 /* NavigationController.swift in Sources */, + 3DD9E95921084BFD00726DFD /* ThemedUITableViewController.swift in Sources */, 3D82873920E3EC3B0035AE0B /* PrinterManager.swift in Sources */, 3DBAE4A120E69D4900D2137D /* CurrentStateEvent.swift in Sources */, 3D78BA9F21039D770090D79A /* Terminal.swift in Sources */, @@ -368,10 +409,13 @@ 3D968DE120E34612006774A5 /* PrinterDetailsViewController.swift in Sources */, 3D82873B20E407370035AE0B /* PrintersTableViewController.swift in Sources */, 3DA252442105028300B60E31 /* FolderViewController.swift in Sources */, + 3D6350F721084334001C10F7 /* ThemedDynamicUITableViewController.swift in Sources */, 3DF232E020F150CC00550652 /* MoveSubViewController.swift in Sources */, 3D01E29220F3DE850020DE41 /* JobInfoViewController.swift in Sources */, 3D0E1C9D20E819B00036B5FE /* CameraEmbeddedViewController.swift in Sources */, + 3D6350F321083BE0001C10F7 /* TabBarController.swift in Sources */, 3D968DDD20E337C7006774A5 /* ScannerViewController.swift in Sources */, + 3D6350EA21080AD3001C10F7 /* Theme.swift in Sources */, 3D0FA48321047AFA0084FF52 /* FilesTreeViewController.swift in Sources */, 3DBAE4A320E6A02A00D2137D /* WebSocketClientDelegate.swift in Sources */, 3D8B292A20E54F7300296D9D /* PanelViewController.swift in Sources */, diff --git a/OctoPod/Assets.xcassets/Settings UI/Appearance.imageset/Contents.json b/OctoPod/Assets.xcassets/Settings UI/Appearance.imageset/Contents.json new file mode 100644 index 00000000..373faa02 --- /dev/null +++ b/OctoPod/Assets.xcassets/Settings UI/Appearance.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emblem-art.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OctoPod/Assets.xcassets/Settings UI/Appearance.imageset/emblem-art.png b/OctoPod/Assets.xcassets/Settings UI/Appearance.imageset/emblem-art.png new file mode 100644 index 00000000..37dc2741 Binary files /dev/null and b/OctoPod/Assets.xcassets/Settings UI/Appearance.imageset/emblem-art.png differ diff --git a/OctoPod/Assets.xcassets/Settings UI/Contents.json b/OctoPod/Assets.xcassets/Settings UI/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/OctoPod/Assets.xcassets/Settings UI/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OctoPod/Assets.xcassets/Settings UI/Printers.imageset/3d-printer (1).png b/OctoPod/Assets.xcassets/Settings UI/Printers.imageset/3d-printer (1).png new file mode 100644 index 00000000..9d45c359 Binary files /dev/null and b/OctoPod/Assets.xcassets/Settings UI/Printers.imageset/3d-printer (1).png differ diff --git a/OctoPod/Assets.xcassets/Settings UI/Printers.imageset/Contents.json b/OctoPod/Assets.xcassets/Settings UI/Printers.imageset/Contents.json new file mode 100644 index 00000000..b7d3a48e --- /dev/null +++ b/OctoPod/Assets.xcassets/Settings UI/Printers.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "3d-printer (1).png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OctoPod/Assets.xcassets/Toolbar icons/Setup.imageset/Contents.json b/OctoPod/Assets.xcassets/Toolbar icons/Settings.imageset/Contents.json similarity index 100% rename from OctoPod/Assets.xcassets/Toolbar icons/Setup.imageset/Contents.json rename to OctoPod/Assets.xcassets/Toolbar icons/Settings.imageset/Contents.json diff --git a/OctoPod/Assets.xcassets/Toolbar icons/Setup.imageset/configure-1.png b/OctoPod/Assets.xcassets/Toolbar icons/Settings.imageset/configure-1.png similarity index 100% rename from OctoPod/Assets.xcassets/Toolbar icons/Setup.imageset/configure-1.png rename to OctoPod/Assets.xcassets/Toolbar icons/Settings.imageset/configure-1.png diff --git a/OctoPod/Assets.xcassets/Toolbar icons/Setup.imageset/configure.png b/OctoPod/Assets.xcassets/Toolbar icons/Settings.imageset/configure.png similarity index 100% rename from OctoPod/Assets.xcassets/Toolbar icons/Setup.imageset/configure.png rename to OctoPod/Assets.xcassets/Toolbar icons/Settings.imageset/configure.png diff --git a/OctoPod/Base.lproj/Main.storyboard b/OctoPod/Base.lproj/Main.storyboard index 7007a7f4..1f248d61 100644 --- a/OctoPod/Base.lproj/Main.storyboard +++ b/OctoPod/Base.lproj/Main.storyboard @@ -422,21 +422,28 @@ + + + + + + + @@ -761,7 +768,7 @@ - + @@ -827,24 +834,165 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - + @@ -920,6 +1068,8 @@ + + @@ -980,43 +1130,52 @@ - - - + - + - - - + + @@ -1126,10 +1285,15 @@ + + + + + @@ -1251,7 +1415,9 @@ + + @@ -1555,7 +1721,7 @@ - + @@ -1574,12 +1740,12 @@ - + - + @@ -1912,11 +2078,14 @@ + + + @@ -1933,7 +2102,7 @@ - + @@ -2037,7 +2206,7 @@ - + @@ -2056,7 +2225,7 @@ - + @@ -2074,13 +2243,15 @@ + - + + @@ -2090,9 +2261,9 @@ - + - + diff --git a/OctoPod/File UI/FileDetailsViewController.swift b/OctoPod/File UI/FileDetailsViewController.swift index a9030ede..a776570b 100644 --- a/OctoPod/File UI/FileDetailsViewController.swift +++ b/OctoPod/File UI/FileDetailsViewController.swift @@ -1,9 +1,15 @@ import UIKit -class FileDetailsViewController: UITableViewController { +class FileDetailsViewController: ThemedStaticUITableViewController { var printFile: PrintFile? + @IBOutlet weak var fileTextLabel: UILabel! + @IBOutlet weak var sizeTextLabel: UILabel! + @IBOutlet weak var originTextLabel: UILabel! + @IBOutlet weak var printTimeTextLabel: UILabel! + @IBOutlet weak var uploadedTextLabel: UILabel! + @IBOutlet weak var fileNameLabel: UILabel! @IBOutlet weak var sizeLabel: UILabel! @IBOutlet weak var originLabel: UILabel! @@ -21,6 +27,7 @@ class FileDetailsViewController: UITableViewController { } override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) fileNameLabel.text = printFile?.display sizeLabel.text = printFile?.displaySize() originLabel.text = printFile?.displayOrigin() @@ -29,6 +36,8 @@ class FileDetailsViewController: UITableViewController { printButton.isEnabled = printFile != nil && printFile!.canBePrinted() deleteButton.isEnabled = printFile != nil && printFile!.canBeDeleted() + + themeLabels() } @IBAction func printClicked(_ sender: Any) { @@ -75,4 +84,22 @@ class FileDetailsViewController: UITableViewController { } return "" } + + fileprivate func themeLabels() { + let theme = Theme.currentTheme() + let textLabelColor = theme.labelColor() + let textColor = theme.textColor() + + fileTextLabel.textColor = textLabelColor + sizeTextLabel.textColor = textLabelColor + originTextLabel.textColor = textLabelColor + printTimeTextLabel.textColor = textLabelColor + uploadedTextLabel.textColor = textLabelColor + + fileNameLabel.textColor = textColor + sizeLabel.textColor = textColor + originLabel.textColor = textColor + estimatedPrintTimeLabel.textColor = textColor + uploadedDateLabel.textColor = textColor + } } diff --git a/OctoPod/File UI/FilesTreeViewController.swift b/OctoPod/File UI/FilesTreeViewController.swift index be2fb134..71796596 100644 --- a/OctoPod/File UI/FilesTreeViewController.swift +++ b/OctoPod/File UI/FilesTreeViewController.swift @@ -2,17 +2,24 @@ import UIKit class FilesTreeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { + private var currentTheme: Theme.ThemeChoice! + let printerManager: PrinterManager = { return (UIApplication.shared.delegate as! AppDelegate).printerManager! }() let octoprintClient: OctoPrintClient = { return (UIApplication.shared.delegate as! AppDelegate).octoprintClient }() @IBOutlet weak var tableView: UITableView! + @IBOutlet weak var sortByTextLabel: UILabel! @IBOutlet weak var sortByControl: UISegmentedControl! + @IBOutlet weak var refreshSDButton: UIButton! var refreshControl: UIRefreshControl? var files: Array = Array() override func viewDidLoad() { super.viewDidLoad() + + // Remember current theme so we know when to repaint + currentTheme = Theme.currentTheme() // Create, configure and add UIRefreshControl to table view refreshControl = UIRefreshControl() @@ -26,12 +33,23 @@ class FilesTreeViewController: UIViewController, UITableViewDataSource, UITableV } override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + if currentTheme != Theme.currentTheme() { + // Theme changed so repaint table now (to prevent quick flash in the UI with the old theme) + tableView.reloadData() + currentTheme = Theme.currentTheme() + } + if let printer = printerManager.getDefaultPrinter() { // Update window title to Camera name navigationItem.title = printer.name loadFiles(done: nil) } + + ThemeUIUtils.applyTheme(table: tableView, staticCells: false) + applyTheme() } override func didReceiveMemoryWarning() { @@ -80,6 +98,10 @@ class FilesTreeViewController: UIViewController, UITableViewDataSource, UITableV } } + func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + ThemeUIUtils.themeCell(cell: cell) + } + // MARK: - Unwind operations @IBAction func backFromDelete(_ sender: UIStoryboardSegue) { @@ -165,8 +187,23 @@ class FilesTreeViewController: UIViewController, UITableViewDataSource, UITableV }) } - // MARK: - Private functions + // MARK: - Theme functions + fileprivate func applyTheme() { + let theme = Theme.currentTheme() + let tintColor = theme.tintColor() + + // Set background color to the view + view.backgroundColor = theme.backgroundColor() + // Set background color to the refresh SD button + refreshSDButton.tintColor = tintColor + // Set background color to the sort control + sortByTextLabel.textColor = theme.labelColor() + sortByControl.tintColor = tintColor + } + + // MARK: - Private functions + fileprivate func loadFiles(delay seconds: Double) { // Wait requested seconds before loading files (so SD card has time to be read) DispatchQueue.main.asyncAfter(deadline: .now() + seconds) { diff --git a/OctoPod/File UI/FolderViewController.swift b/OctoPod/File UI/FolderViewController.swift index d6cf27da..5e709b8e 100644 --- a/OctoPod/File UI/FolderViewController.swift +++ b/OctoPod/File UI/FolderViewController.swift @@ -2,7 +2,7 @@ import UIKit // VC that renders content of a folder // Files were already fetched by FilesTreeViewController -class FolderViewController: UITableViewController { +class FolderViewController: ThemedDynamicUITableViewController { let octoprintClient: OctoPrintClient = { return (UIApplication.shared.delegate as! AppDelegate).octoprintClient }() @@ -11,19 +11,25 @@ class FolderViewController: UITableViewController { var files: Array = Array() // Track files of the folder override func viewDidLoad() { - super.viewDidLoad() + super.viewDidLoad() } - + override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) // Update window title to folder we are browsing navigationItem.title = folder.display files = folder.children! + + // Clear selected row when going back to this VC + if let selectionIndexPath = self.tableView.indexPathForSelectedRow { + tableView.deselectRow(at: selectionIndexPath, animated: animated) + } } // MARK: - Table view data source diff --git a/OctoPod/Model/PrintFile.swift b/OctoPod/Model/PrintFile.swift index dc69ae41..130f6538 100644 --- a/OctoPod/Model/PrintFile.swift +++ b/OctoPod/Model/PrintFile.swift @@ -1,7 +1,7 @@ import Foundation class PrintFile { - static let SORT_BY_PREFERENCE = "filesSortBy" + private static let SORT_BY_PREFERENCE = "filesSortBy" enum SortBy: Int { case uploadDate = 0 diff --git a/OctoPod/Move UI/MoveSubViewController.swift b/OctoPod/Move UI/MoveSubViewController.swift index eed4aefa..7ee7dcf1 100644 --- a/OctoPod/Move UI/MoveSubViewController.swift +++ b/OctoPod/Move UI/MoveSubViewController.swift @@ -3,11 +3,15 @@ import UIKit // OctoPrint does not report current fan speed or extruder flow rate so we // initially assume 100% and then just leave last value set by user. Display // value will go back to 100% if app is terminated -class MoveSubViewController: UITableViewController { +class MoveSubViewController: ThemedStaticUITableViewController { let printerManager: PrinterManager = { return (UIApplication.shared.delegate as! AppDelegate).printerManager! }() let octoprintClient: OctoPrintClient = { return (UIApplication.shared.delegate as! AppDelegate).octoprintClient }() + @IBOutlet weak var flowRateTextLabel: UILabel! + @IBOutlet weak var fanTextLabel: UILabel! + @IBOutlet weak var disableMotorLabel: UILabel! + @IBOutlet weak var xyStepSegmentedControl: UISegmentedControl! @IBOutlet weak var zStepSegmentedControl: UISegmentedControl! @IBOutlet weak var eStepSegmentedControl: UISegmentedControl! @@ -31,11 +35,13 @@ class MoveSubViewController: UITableViewController { } override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) if let _ = printerManager.getDefaultPrinter() { enableButtons(enable: true) } else { enableButtons(enable: false) } + themeLabels() } override func didReceiveMemoryWarning() { @@ -240,6 +246,19 @@ class MoveSubViewController: UITableViewController { }) } + fileprivate func themeLabels() { + let theme = Theme.currentTheme() + let textLabelColor = theme.labelColor() + let textColor = theme.textColor() + + flowRateTextLabel.textColor = textLabelColor + fanTextLabel.textColor = textLabelColor + disableMotorLabel.textColor = textLabelColor + + flowRateLabel.textColor = textColor + fanSpeedLabel.textColor = textColor + } + fileprivate func showAlert(_ title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: { (UIAlertAction) -> Void in diff --git a/OctoPod/NavigationController.swift b/OctoPod/NavigationController.swift new file mode 100644 index 00000000..acfeab9d --- /dev/null +++ b/OctoPod/NavigationController.swift @@ -0,0 +1,22 @@ +import UIKit + +class NavigationController: UINavigationController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + let theme = Theme.currentTheme() + + navigationBar.barTintColor = theme.navigationTopColor() + } +} diff --git a/OctoPod/Panel UI/PrinterSubpanelViewController.swift b/OctoPod/Panel UI/PrinterSubpanelViewController.swift index d86339a9..08e5d2d8 100644 --- a/OctoPod/Panel UI/PrinterSubpanelViewController.swift +++ b/OctoPod/Panel UI/PrinterSubpanelViewController.swift @@ -1,12 +1,20 @@ import UIKit -class PrinterSubpanelViewController: UITableViewController, UIPopoverPresentationControllerDelegate { +class PrinterSubpanelViewController: ThemedStaticUITableViewController, UIPopoverPresentationControllerDelegate { enum buttonsScope { case all case all_except_connect } + @IBOutlet weak var printedTextLabel: UILabel! + @IBOutlet weak var printTimeTextLabel: UILabel! + @IBOutlet weak var printTimeLeftTextLabel: UILabel! + @IBOutlet weak var printerStatusTextLabel: UILabel! + @IBOutlet weak var tool0TextLabel: UILabel! + @IBOutlet weak var bedTextLabel: UILabel! + @IBOutlet weak var tool1TextLabel: UILabel! + @IBOutlet weak var printerStatusLabel: UILabel! @IBOutlet weak var progressView: UIProgressView! @@ -43,6 +51,11 @@ class PrinterSubpanelViewController: UITableViewController, UIPopoverPresentatio clearValues() } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + themeLabels() + } + override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. @@ -94,7 +107,7 @@ class PrinterSubpanelViewController: UITableViewController, UIPopoverPresentatio if let state = event.state { self.printerStatusLabel.text = state } - + if let progress = event.progressCompletion { let progressText = String(format: "%.1f", progress) self.progressLabel.text = "\(progressText)%" @@ -208,4 +221,32 @@ class PrinterSubpanelViewController: UITableViewController, UIPopoverPresentatio self.tool1SetTempButton.isEnabled = false } } + + fileprivate func themeLabels() { + let theme = Theme.currentTheme() + let textLabelColor = theme.labelColor() + let textColor = theme.textColor() + + printedTextLabel.textColor = textLabelColor + printTimeTextLabel.textColor = textLabelColor + printTimeLeftTextLabel.textColor = textLabelColor + printerStatusTextLabel.textColor = textLabelColor + tool0TextLabel.textColor = textLabelColor + bedTextLabel.textColor = textLabelColor + tool1TextLabel.textColor = textLabelColor + tool0SplitLabel.textColor = textLabelColor + tool1SplitLabel.textColor = textLabelColor + bedSplitLabel.textColor = textLabelColor + + printerStatusLabel.textColor = textColor + progressLabel.textColor = textColor + printTimeLabel.textColor = textColor + printTimeLeftLabel.textColor = textColor + tool0ActualLabel.textColor = textColor + tool0TargetLabel.textColor = textColor + tool1ActualLabel.textColor = textColor + tool1TargetLabel.textColor = textColor + bedActualLabel.textColor = textColor + bedTargetLabel.textColor = textColor + } } diff --git a/OctoPod/SelectDefaultPrinterViewController.swift b/OctoPod/Panel UI/SelectDefaultPrinterViewController.swift similarity index 100% rename from OctoPod/SelectDefaultPrinterViewController.swift rename to OctoPod/Panel UI/SelectDefaultPrinterViewController.swift diff --git a/OctoPod/Settings UI/AppearanceViewController.swift b/OctoPod/Settings UI/AppearanceViewController.swift new file mode 100644 index 00000000..1fae1987 --- /dev/null +++ b/OctoPod/Settings UI/AppearanceViewController.swift @@ -0,0 +1,51 @@ +import UIKit + +class AppearanceViewController: ThemedStaticUITableViewController { + + @IBOutlet weak var lightCell: UITableViewCell! + @IBOutlet weak var darkCell: UITableViewCell! + + @IBOutlet weak var lightLabel: UILabel! + @IBOutlet weak var darkLabel: UILabel! + + override func viewDidLoad() { + super.viewDidLoad() + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + let theme = Theme.currentTheme() + lightLabel.textColor = theme.textColor() + darkLabel.textColor = theme.textColor() + refreshSelectedTheme(theme: theme) + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.row == 0 { + Theme.switchTheme(choice: Theme.ThemeChoice.Light) + } else { + Theme.switchTheme(choice: Theme.ThemeChoice.Dark) + } + // Update navigation bar + let theme = Theme.currentTheme() + navigationController?.navigationBar.barTintColor = theme.navigationTopColor() + tabBarController?.tabBar.barTintColor = theme.tabBarColor() + // Refresh table + viewWillAppear(true) +// applyTheme(table: tableView) +// tableView.reloadData() +// refreshSelectedTheme() + } + + fileprivate func refreshSelectedTheme(theme: Theme.ThemeChoice) { + let lightSelected = theme == Theme.ThemeChoice.Light + + lightCell.accessoryType = lightSelected ? .checkmark : .none + darkCell.accessoryType = lightSelected ? .none : .checkmark + } +} diff --git a/OctoPod/Setup UI/PrinterDetailsViewController.swift b/OctoPod/Settings UI/PrinterDetailsViewController.swift similarity index 98% rename from OctoPod/Setup UI/PrinterDetailsViewController.swift rename to OctoPod/Settings UI/PrinterDetailsViewController.swift index 252d1ad2..8325d7e9 100644 --- a/OctoPod/Setup UI/PrinterDetailsViewController.swift +++ b/OctoPod/Settings UI/PrinterDetailsViewController.swift @@ -1,6 +1,6 @@ import UIKit -class PrinterDetailsViewController: UITableViewController { +class PrinterDetailsViewController: ThemedStaticUITableViewController { let printerManager: PrinterManager = { return (UIApplication.shared.delegate as! AppDelegate).printerManager! }() @@ -22,6 +22,7 @@ class PrinterDetailsViewController: UITableViewController { } override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) if let selectedPrinter = updatePrinter { printerNameField.text = selectedPrinter.name hostnameField.text = selectedPrinter.hostname diff --git a/OctoPod/Setup UI/PrintersTableViewController.swift b/OctoPod/Settings UI/PrintersTableViewController.swift similarity index 97% rename from OctoPod/Setup UI/PrintersTableViewController.swift rename to OctoPod/Settings UI/PrintersTableViewController.swift index c1f20cfc..9e82b2ec 100644 --- a/OctoPod/Setup UI/PrintersTableViewController.swift +++ b/OctoPod/Settings UI/PrintersTableViewController.swift @@ -1,6 +1,6 @@ import UIKit -class PrintersTableViewController: UITableViewController { +class PrintersTableViewController: ThemedDynamicUITableViewController { let printerManager: PrinterManager = { return (UIApplication.shared.delegate as! AppDelegate).printerManager! }() diff --git a/OctoPod/Setup UI/ScannerViewController.swift b/OctoPod/Settings UI/ScannerViewController.swift similarity index 100% rename from OctoPod/Setup UI/ScannerViewController.swift rename to OctoPod/Settings UI/ScannerViewController.swift diff --git a/OctoPod/Settings UI/SettingsViewController.swift b/OctoPod/Settings UI/SettingsViewController.swift new file mode 100644 index 00000000..edb43a33 --- /dev/null +++ b/OctoPod/Settings UI/SettingsViewController.swift @@ -0,0 +1,14 @@ +import UIKit + +class SettingsViewController: ThemedStaticUITableViewController { + + @IBOutlet weak var printersLabel: UILabel! + @IBOutlet weak var appearanceLabel: UILabel! + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + let theme = Theme.currentTheme() + printersLabel.textColor = theme.textColor() + appearanceLabel.textColor = theme.textColor() + } +} diff --git a/OctoPod/TabBarController.swift b/OctoPod/TabBarController.swift new file mode 100644 index 00000000..19fcafd3 --- /dev/null +++ b/OctoPod/TabBarController.swift @@ -0,0 +1,22 @@ +import UIKit + +class TabBarController: UITabBarController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + let theme = Theme.currentTheme() + tabBar.barTintColor = theme.tabBarColor() + } +} diff --git a/OctoPod/Terminal UI/TerminalViewController.swift b/OctoPod/Terminal UI/TerminalViewController.swift index 8d271176..1d7edcb6 100644 --- a/OctoPod/Terminal UI/TerminalViewController.swift +++ b/OctoPod/Terminal UI/TerminalViewController.swift @@ -5,6 +5,9 @@ class TerminalViewController: UIViewController, OctoPrintClientDelegate { let printerManager: PrinterManager = { return (UIApplication.shared.delegate as! AppDelegate).printerManager! }() let octoprintClient: OctoPrintClient = { return (UIApplication.shared.delegate as! AppDelegate).octoprintClient }() + @IBOutlet weak var refreshEnabledTextLabel: UILabel! + @IBOutlet weak var gcodeTextLabel: UILabel! + @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var terminalTextView: UITextView! @IBOutlet weak var refreshSwitch: UISwitch! @@ -21,6 +24,7 @@ class TerminalViewController: UIViewController, OctoPrintClientDelegate { override func viewWillAppear(_ animated: Bool) { terminalTextView.layer.borderWidth = 1 terminalTextView.layer.borderColor = UIColor.black.cgColor + themeLabels() if let printer = printerManager.getDefaultPrinter() { // Update window title to Camera name @@ -122,6 +126,20 @@ class TerminalViewController: UIViewController, OctoPrintClientDelegate { } } + fileprivate func themeLabels() { + let theme = Theme.currentTheme() + let textLabelColor = theme.labelColor() + let textColor = theme.textColor() + + view.backgroundColor = theme.backgroundColor() + + refreshEnabledTextLabel.textColor = textLabelColor + gcodeTextLabel.textColor = textLabelColor + + terminalTextView.backgroundColor = theme.cellBackgroundColor() + terminalTextView.textColor = textColor + } + fileprivate func showAlert(_ title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: { (UIAlertAction) -> Void in diff --git a/OctoPod/Themes/Theme.swift b/OctoPod/Themes/Theme.swift new file mode 100644 index 00000000..fa32d2a7 --- /dev/null +++ b/OctoPod/Themes/Theme.swift @@ -0,0 +1,106 @@ +import Foundation +import UIKit + +// Users can select different themes as a way to control the colors that the UI should use +class Theme { + private static let DEFAULT_THEME = "DEFAULT_THEME" + + private static var current: ThemeChoice? + + enum ThemeChoice: Int { + case Light = 1 + case Dark = 2 + + func navigationTopColor() -> UIColor { + switch self { + case .Light: + return UIColor(red: 247/255, green: 247/255, blue: 248/255, alpha: 1.0) // CONFIRMED + case .Dark: + return UIColor(red: 53/255, green: 57/255, blue: 62/255, alpha: 1.0) + } + } + + func tabBarColor() -> UIColor { + switch self { + case .Light: + return UIColor(red: 246/255, green: 246/255, blue: 248/255, alpha: 1.0) // CONFIRMED + case .Dark: + return UIColor(red: 53/255, green: 57/255, blue: 62/255, alpha: 1.0) + } + } + + func backgroundColor() -> UIColor { + switch self { + case .Light: + return UIColor(red: 239/255, green: 239/255, blue: 244/255, alpha: 1.0) // CONFIRMED + case .Dark: + return UIColor(red: 53/255, green: 57/255, blue: 62/255, alpha: 1.0) + } + } + + func cellBackgroundColor() -> UIColor { + switch self { + case .Light: + return UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0) // CONFIRMED + case .Dark: + return UIColor(red: 47/255, green: 49/255, blue: 53/255, alpha: 1.0) + } + } + + func separatorColor() -> UIColor { + switch self { + case .Light: + return UIColor(red: 235/255, green: 234/255, blue: 236/255, alpha: 1.0) // CONFIRMED + case .Dark: + return UIColor(red: 40/255, green: 42/255, blue: 46/255, alpha: 1.0) + } + } + + func labelColor() -> UIColor { + switch self { + case .Light: + return UIColor.black // CONFIRMED + case .Dark: + return UIColor.white + } + } + + func textColor() -> UIColor { + switch self { + case .Light: + return UIColor.darkGray // CONFIRMED + case .Dark: + return UIColor(red: 134/255, green: 137/255, blue: 142/255, alpha: 1.0) + } + } + + func tintColor() -> UIColor { + switch self { + case .Light: + return UIColor(red: 0/255, green: 122.4/255, blue: 255/255, alpha: 1.0) // CONFIRMED + case .Dark: + return UIColor(red: 0/255, green: 122.4/255, blue: 255/255, alpha: 1.0) + } + } + } + + class func currentTheme() -> ThemeChoice { + if let currentTheme = current { + // Use cached value to prevent extra work + return currentTheme + } + + if let stored = UserDefaults.standard.object(forKey: DEFAULT_THEME) as? Int { + current = ThemeChoice(rawValue: stored)! + } else { + current = ThemeChoice.Dark + } + return current! + } + + class func switchTheme(choice: ThemeChoice) { + current = choice + UserDefaults.standard.set(choice.rawValue, forKey: DEFAULT_THEME) + } +} + diff --git a/OctoPod/Themes/ThemeUIUtils.swift b/OctoPod/Themes/ThemeUIUtils.swift new file mode 100644 index 00000000..d29f7780 --- /dev/null +++ b/OctoPod/Themes/ThemeUIUtils.swift @@ -0,0 +1,22 @@ +import Foundation +import UIKit + +class ThemeUIUtils { + + class func themeCell(cell: UITableViewCell) { + let theme = Theme.currentTheme() + let textColor = theme.textColor() + + cell.backgroundColor = theme.cellBackgroundColor() + cell.textLabel?.textColor = textColor + cell.detailTextLabel?.textColor = textColor + } + + class func applyTheme(table: UITableView, staticCells: Bool) { + let theme = Theme.currentTheme() + table.separatorColor = theme.separatorColor() + table.sectionIndexBackgroundColor = theme.backgroundColor() + table.backgroundColor = staticCells ? theme.backgroundColor() : theme.cellBackgroundColor() + } + +} diff --git a/OctoPod/Themes/ThemedDynamicUITableViewController.swift b/OctoPod/Themes/ThemedDynamicUITableViewController.swift new file mode 100644 index 00000000..fd85a249 --- /dev/null +++ b/OctoPod/Themes/ThemedDynamicUITableViewController.swift @@ -0,0 +1,8 @@ +import UIKit + +class ThemedDynamicUITableViewController: ThemedUITableViewController { + + override func staticCells() -> Bool { + return false + } +} diff --git a/OctoPod/Themes/ThemedStaticUITableViewController.swift b/OctoPod/Themes/ThemedStaticUITableViewController.swift new file mode 100644 index 00000000..cee641dc --- /dev/null +++ b/OctoPod/Themes/ThemedStaticUITableViewController.swift @@ -0,0 +1,8 @@ +import UIKit + +class ThemedStaticUITableViewController: ThemedUITableViewController { + + override func staticCells() -> Bool { + return true + } +} diff --git a/OctoPod/Themes/ThemedUITableViewController.swift b/OctoPod/Themes/ThemedUITableViewController.swift new file mode 100644 index 00000000..c198f0d8 --- /dev/null +++ b/OctoPod/Themes/ThemedUITableViewController.swift @@ -0,0 +1,35 @@ +import UIKit + +class ThemedUITableViewController: UITableViewController { + + var currentTheme: Theme.ThemeChoice! + + override func viewDidLoad() { + super.viewDidLoad() + // Remember current theme so we know when to repaint + currentTheme = Theme.currentTheme() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + ThemeUIUtils.applyTheme(table: tableView, staticCells: staticCells()) + + if currentTheme != Theme.currentTheme() { + tableView.reloadData() + currentTheme = Theme.currentTheme() + } + } + + // MARK: - Table operations + + override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + ThemeUIUtils.themeCell(cell: cell) + } + + // MARK: - Abstract methods + + func staticCells() -> Bool { + return false + } +} +