diff --git a/XIONControlPanel.xcodeproj/project.pbxproj b/XIONControlPanel.xcodeproj/project.pbxproj
index a8f8d64..41a92c9 100644
--- a/XIONControlPanel.xcodeproj/project.pbxproj
+++ b/XIONControlPanel.xcodeproj/project.pbxproj
@@ -109,8 +109,8 @@
0C20E2B61C33514100BA789B /* Controllers */ = {
isa = PBXGroup;
children = (
- 0C41EF491C34B51500AF847F /* SwitchesViewController.swift */,
0C20E2BA1C33529700BA789B /* MainViewController.swift */,
+ 0C41EF491C34B51500AF847F /* SwitchesViewController.swift */,
0C20E2BC1C33534F00BA789B /* VisualizationViewController.swift */,
0CAA32781C361A2400B353CF /* WemoServer.swift */,
);
@@ -427,7 +427,7 @@
PROVISIONING_PROFILE = "";
SWIFT_OBJC_BRIDGING_HEADER = "XIONControlPanel/SupportingFiles/XIONControlPanel-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- TARGETED_DEVICE_FAMILY = 2;
+ TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@@ -444,7 +444,7 @@
PRODUCT_NAME = XION;
PROVISIONING_PROFILE = "";
SWIFT_OBJC_BRIDGING_HEADER = "XIONControlPanel/SupportingFiles/XIONControlPanel-Bridging-Header.h";
- TARGETED_DEVICE_FAMILY = 2;
+ TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
diff --git a/XIONControlPanel/Application/AppDelegate.swift b/XIONControlPanel/Application/AppDelegate.swift
index 9fbe100..b53ee20 100644
--- a/XIONControlPanel/Application/AppDelegate.swift
+++ b/XIONControlPanel/Application/AppDelegate.swift
@@ -9,7 +9,8 @@
import UIKit
@UIApplicationMain
-class AppDelegate: UIResponder, UIApplicationDelegate {
+class AppDelegate: UIResponder, UIApplicationDelegate
+{
var window: UIWindow?
var mainViewController: MainViewController = MainViewController()
@@ -36,6 +37,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask
{
- return UIInterfaceOrientationMask.Landscape
+ var mask: UIInterfaceOrientationMask = .Portrait
+
+ if (UIDevice.currentDevice().userInterfaceIdiom == .Phone) {
+ mask = UIInterfaceOrientationMask.Portrait
+ } else {
+ mask = UIInterfaceOrientationMask.All
+ }
+
+ return mask
}
}
diff --git a/XIONControlPanel/Controllers/MainViewController.swift b/XIONControlPanel/Controllers/MainViewController.swift
index a46d529..7864b09 100644
--- a/XIONControlPanel/Controllers/MainViewController.swift
+++ b/XIONControlPanel/Controllers/MainViewController.swift
@@ -8,7 +8,8 @@
import UIKit
-class MainViewController: UIViewController, SwitchesViewControllerDelegate {
+class MainViewController: UIViewController, SwitchesViewControllerDelegate
+{
private var _server: WemoServer
private var _visualizationController: VisualizationViewController = VisualizationViewController()
private var _switchesController: SwitchesViewController = SwitchesViewController()
@@ -53,11 +54,13 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
super.viewDidLayoutSubviews()
let bounds = self.view.bounds
+ let horizontalSizeClass = self.traitCollection.horizontalSizeClass
+
let headerBounds = CGRect(
x: 0.0,
y: 0.0,
width: bounds.size.width,
- height: rint(bounds.size.height / 10.0)
+ height: rint(bounds.size.height / 8.0)
)
let bodyBounds = CGRect(
x: 0.0,
@@ -76,10 +79,20 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
)
_visualizationController.view.frame = visualizationFrame
+ var switchesOriginX: CGFloat = 0.0
+ var switchesWidth: CGFloat = 0.0
+ if (horizontalSizeClass == .Regular) {
+ switchesOriginX = CGRectGetMaxX(visualizationFrame)
+ switchesWidth = bodyBounds.size.width - visualizationFrame.size.width
+ } else {
+ switchesOriginX = 0.0
+ switchesWidth = bodyBounds.size.width
+ }
+
let switchesControllerFrame = CGRect(
- x: CGRectGetMaxX(visualizationFrame),
+ x: switchesOriginX,
y: bodyBounds.origin.y,
- width: bodyBounds.size.width - visualizationFrame.size.width,
+ width: switchesWidth,
height: bodyBounds.size.height
)
_switchesController.view.frame = switchesControllerFrame
@@ -104,6 +117,12 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
}
}
+ override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
+ {
+ super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
+ _updateSizeClassPresentation()
+ }
+
override func prefersStatusBarHidden() -> Bool
{
return true
@@ -133,6 +152,16 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
// MARK: Internal
+ internal func _updateSizeClassPresentation()
+ {
+ let horizontalSizeClass = self.traitCollection.horizontalSizeClass
+ if (horizontalSizeClass == .Regular) {
+ _visualizationController.view.hidden = false
+ } else {
+ _visualizationController.view.hidden = true
+ }
+ }
+
internal func _updateVisualization(animated: Bool)
{
var activatedDevicesCount = 0
@@ -152,6 +181,7 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
{
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self._headerView.connectionStatusView.connectivityStatus = status
+ self._headerView.setNeedsLayout()
self._visualizationController.connectionStatus = status
}
}
diff --git a/XIONControlPanel/Controllers/SwitchesViewController.swift b/XIONControlPanel/Controllers/SwitchesViewController.swift
index d97e12a..af43596 100644
--- a/XIONControlPanel/Controllers/SwitchesViewController.swift
+++ b/XIONControlPanel/Controllers/SwitchesViewController.swift
@@ -10,11 +10,13 @@ import Darwin
import Foundation
import UIKit
-protocol SwitchesViewControllerDelegate: class {
+protocol SwitchesViewControllerDelegate: class
+{
func switchesViewControllerDidToggleDevices(controller: SwitchesViewController, devices: [WemoDevice])
}
-extension SwitchesViewControllerDelegate {
+extension SwitchesViewControllerDelegate
+{
func switchesViewControllerDidToggleDevices(controller: SwitchesViewController, devices: [WemoDevice]) {}
}
@@ -30,9 +32,9 @@ class SwitchesViewController: UIViewController,
static private let collectionViewDeviceSwitchCellReuseIdentifier = "DeviceSwitchReuseID"
static private let collectionViewActionCellReuseIdentifier = "ActionCellReuseID"
static private let collectionViewCellsSpacing: CGFloat = 5.0
- static private let collectionViewCellsPerRow = 3
- private enum ActionCell: Int {
+ private enum ActionCell: Int
+ {
case AllOn
case AllOff
@@ -181,9 +183,20 @@ class SwitchesViewController: UIViewController,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
let spacing = SwitchesViewController.collectionViewCellsSpacing
- let cellsPerRow = CGFloat(SwitchesViewController.collectionViewCellsPerRow)
- let dimensions = floor((collectionView.bounds.size.width / cellsPerRow) - ((spacing * (cellsPerRow - 1.0)) / cellsPerRow))
+ let bounds = collectionView.bounds
+ var cellsPerRow: CGFloat = 0.0
+ switch (self.traitCollection.horizontalSizeClass) {
+ case .Regular, .Compact where (bounds.size.width >= 400.0):
+ cellsPerRow = 3.0
+ break
+ case .Compact:
+ cellsPerRow = 2.0
+ default:
+ cellsPerRow = 2.0
+ }
+
+ let dimensions = floor((collectionView.bounds.size.width / cellsPerRow) - ((spacing * (cellsPerRow - 1.0)) / cellsPerRow))
if (indexPath.item < ActionCell.count) {
return CGSize(width: collectionView.bounds.size.width, height: rint(dimensions / 2.0))
} else {
diff --git a/XIONControlPanel/Controllers/VisualizationViewController.swift b/XIONControlPanel/Controllers/VisualizationViewController.swift
index a9a1c21..b16dfcd 100644
--- a/XIONControlPanel/Controllers/VisualizationViewController.swift
+++ b/XIONControlPanel/Controllers/VisualizationViewController.swift
@@ -14,7 +14,8 @@ import UIKit
let π = CGFloat(M_PI)
-class VisualizationViewController: UIViewController {
+class VisualizationViewController: UIViewController
+{
private var _scene: SCNScene = SCNScene()
private var _sceneView: SCNView?
private var _cameraNode: SCNNode = SCNNode()
diff --git a/XIONControlPanel/Controllers/WemoServer.swift b/XIONControlPanel/Controllers/WemoServer.swift
index edba070..0bdad5c 100644
--- a/XIONControlPanel/Controllers/WemoServer.swift
+++ b/XIONControlPanel/Controllers/WemoServer.swift
@@ -8,14 +8,16 @@
import Foundation
-enum ConnectionStatus {
+enum ConnectionStatus
+{
case Disconnected
case Connecting
case Connected
case Error
}
-class WemoServer {
+class WemoServer
+{
private(set) var baseURL: NSURL
private(set) var connected: Bool = false
@@ -108,7 +110,8 @@ class WemoServer {
}
}
-internal class WemoOperation : NSOperation {
+internal class WemoOperation : NSOperation
+{
var baseURL: NSURL
var session: NSURLSession
@@ -121,7 +124,8 @@ internal class WemoOperation : NSOperation {
}
}
-internal class ConnectOperation : WemoOperation {
+internal class ConnectOperation : WemoOperation
+{
override func main()
{
let semaphore = Semaphore(value: 0)
@@ -140,7 +144,8 @@ internal class ConnectOperation : WemoOperation {
}
}
-internal class FetchDevicesOperation : WemoOperation {
+internal class FetchDevicesOperation : WemoOperation
+{
internal(set) var devices: [WemoDevice] = []
override func main()
@@ -176,7 +181,8 @@ internal class FetchDevicesOperation : WemoOperation {
}
}
-internal class ToggleDeviceOperation : WemoOperation {
+internal class ToggleDeviceOperation : WemoOperation
+{
var device: WemoDevice
var state: WemoDevice.State
diff --git a/XIONControlPanel/Models/WemoDevice.swift b/XIONControlPanel/Models/WemoDevice.swift
index 5eed0b4..584b9f3 100644
--- a/XIONControlPanel/Models/WemoDevice.swift
+++ b/XIONControlPanel/Models/WemoDevice.swift
@@ -8,13 +8,16 @@
import Foundation
-class WemoDevice: Hashable {
- enum State {
+class WemoDevice: Hashable
+{
+ enum State
+ {
case Off
case On
}
- enum Type {
+ enum Type
+ {
case Switch
}
diff --git a/XIONControlPanel/SupportingFiles/Info.plist b/XIONControlPanel/SupportingFiles/Info.plist
index 3cf4046..6ce6140 100644
--- a/XIONControlPanel/SupportingFiles/Info.plist
+++ b/XIONControlPanel/SupportingFiles/Info.plist
@@ -45,6 +45,8 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
UISupportedInterfaceOrientations~ipad
diff --git a/XIONControlPanel/Utilities/NSErrorAdditions.swift b/XIONControlPanel/Utilities/NSErrorAdditions.swift
index dc06879..6c155c8 100644
--- a/XIONControlPanel/Utilities/NSErrorAdditions.swift
+++ b/XIONControlPanel/Utilities/NSErrorAdditions.swift
@@ -8,12 +8,14 @@
import Foundation
-enum XIONErrorCode: Int {
+enum XIONErrorCode: Int
+{
case Unknown
case ConnectionError
}
-extension NSError {
+extension NSError
+{
private static let XIONErrorDomain = "com.xionsf.controlpanel"
class func xionError(code: XIONErrorCode) -> NSError
diff --git a/XIONControlPanel/Utilities/NSURLAdditions.swift b/XIONControlPanel/Utilities/NSURLAdditions.swift
index 09cffe7..48d903b 100644
--- a/XIONControlPanel/Utilities/NSURLAdditions.swift
+++ b/XIONControlPanel/Utilities/NSURLAdditions.swift
@@ -7,8 +7,10 @@
import Foundation
-extension NSURL {
- var requestParameters: [String : String]? {
+extension NSURL
+{
+ var requestParameters: [String : String]?
+ {
get
{
let urlComponents = self.absoluteString.componentsSeparatedByString("/")
diff --git a/XIONControlPanel/Utilities/Semaphore.swift b/XIONControlPanel/Utilities/Semaphore.swift
index 6f8be57..578c626 100644
--- a/XIONControlPanel/Utilities/Semaphore.swift
+++ b/XIONControlPanel/Utilities/Semaphore.swift
@@ -8,7 +8,8 @@
import Foundation
-class Semaphore {
+class Semaphore
+{
private var _semaphore: dispatch_semaphore_t
init(value: Int)
diff --git a/XIONControlPanel/Utilities/StandardError.swift b/XIONControlPanel/Utilities/StandardError.swift
index 261741b..7a6f735 100644
--- a/XIONControlPanel/Utilities/StandardError.swift
+++ b/XIONControlPanel/Utilities/StandardError.swift
@@ -8,8 +8,10 @@
import Foundation
-class StandardErrorOutputStream: OutputStreamType {
- func write(string: String) {
+class StandardErrorOutputStream: OutputStreamType
+{
+ func write(string: String)
+ {
let stderr = NSFileHandle.fileHandleWithStandardError()
stderr.writeData(string.dataUsingEncoding(NSUTF8StringEncoding)!)
}
diff --git a/XIONControlPanel/Views/ConnectionStatusView.swift b/XIONControlPanel/Views/ConnectionStatusView.swift
index 16998d9..a2e0514 100644
--- a/XIONControlPanel/Views/ConnectionStatusView.swift
+++ b/XIONControlPanel/Views/ConnectionStatusView.swift
@@ -8,7 +8,8 @@
import UIKit
-class ConnectionStatusView: UIView {
+class ConnectionStatusView: UIView
+{
private var _connectivityStatus: ConnectionStatus = .Disconnected
private var _japaneseLabel: UILabel = UILabel()
private var _englishLabel: UILabel = UILabel()
diff --git a/XIONControlPanel/Views/HeaderView.swift b/XIONControlPanel/Views/HeaderView.swift
index 0efe50d..72faa11 100644
--- a/XIONControlPanel/Views/HeaderView.swift
+++ b/XIONControlPanel/Views/HeaderView.swift
@@ -10,7 +10,8 @@ import Darwin
import Foundation
import UIKit
-class HeaderView: UIView {
+class HeaderView: UIView
+{
var xionLogoView: XIONLogoView = XIONLogoView()
var connectionStatusView: ConnectionStatusView = ConnectionStatusView()
@@ -58,31 +59,39 @@ class HeaderView: UIView {
)
self.xionLogoView.frame = logoFrame
- let titleJPVerticalMargin: CGFloat = 5.0
- let titleLabelSize = _xionTitleLabel.sizeThatFits(bounds.size)
- let jpLabelSize = _xionJapaneseLabel.sizeThatFits(bounds.size)
- let totalLabelsHeight = titleLabelSize.height + titleJPVerticalMargin + jpLabelSize.height
+ if (self.traitCollection.horizontalSizeClass == .Compact) {
+ _xionTitleLabel.hidden = true
+ _xionJapaneseLabel.hidden = true
+ } else {
+ _xionTitleLabel.hidden = false
+ _xionJapaneseLabel.hidden = false
- let titleFrame = CGRect(
- x: CGRectGetMaxX(logoFrame) + hpadding * 2.0,
- y: rint(bounds.size.height / 2.0 - totalLabelsHeight / 2.0),
- width: titleLabelSize.width,
- height: titleLabelSize.height
- )
- _xionTitleLabel.frame = titleFrame
+ let titleJPVerticalMargin: CGFloat = 5.0
+ let titleLabelSize = _xionTitleLabel.sizeThatFits(bounds.size)
+ let jpLabelSize = _xionJapaneseLabel.sizeThatFits(bounds.size)
+ let totalLabelsHeight = titleLabelSize.height + titleJPVerticalMargin + jpLabelSize.height
+
+ let titleFrame = CGRect(
+ x: CGRectGetMaxX(logoFrame) + hpadding * 2.0,
+ y: rint(bounds.size.height / 2.0 - totalLabelsHeight / 2.0),
+ width: titleLabelSize.width,
+ height: titleLabelSize.height
+ )
+ _xionTitleLabel.frame = titleFrame
+
+ let jpTitleFrame = CGRect(
+ x: titleFrame.origin.x,
+ y: CGRectGetMaxY(titleFrame) + titleJPVerticalMargin,
+ width: jpLabelSize.width,
+ height: jpLabelSize.height + 2.0
+ )
+ _xionJapaneseLabel.frame = jpTitleFrame
+ }
- let jpTitleFrame = CGRect(
- x: titleFrame.origin.x,
- y: CGRectGetMaxY(titleFrame) + titleJPVerticalMargin,
- width: jpLabelSize.width,
- height: jpLabelSize.height + 2.0
- )
- _xionJapaneseLabel.frame = jpTitleFrame
-
- let connectionStatusDimensions = CGSize(width: rint((1.0 / 8.0) * bounds.size.width), height: bounds.size.height)
+ let connectionStatusDimensions = self.connectionStatusView.sizeThatFits(bounds.size)
let connectionStatusFrame = CGRect(
- x: bounds.size.width - connectionStatusDimensions.width,
- y: 0.0,
+ x: bounds.size.width - connectionStatusDimensions.width - hpadding,
+ y: rint(bounds.size.height / 2.0 - connectionStatusDimensions.height / 2.0),
width: connectionStatusDimensions.width,
height: connectionStatusDimensions.height
)
diff --git a/XIONControlPanel/Views/SwitchIndicatorView.swift b/XIONControlPanel/Views/SwitchIndicatorView.swift
index 726562e..426c72c 100644
--- a/XIONControlPanel/Views/SwitchIndicatorView.swift
+++ b/XIONControlPanel/Views/SwitchIndicatorView.swift
@@ -8,7 +8,8 @@
import UIKit
-class SwitchIndicatorView: UIView {
+class SwitchIndicatorView: UIView
+{
private var _status: Bool = false
private var _foregroundColor: UIColor = UIColor.whiteColor()
private var _outerCircleLayer: CAShapeLayer = CAShapeLayer()
diff --git a/XIONControlPanel/Views/WemoCellView.swift b/XIONControlPanel/Views/WemoCellView.swift
index a0cd377..537613e 100644
--- a/XIONControlPanel/Views/WemoCellView.swift
+++ b/XIONControlPanel/Views/WemoCellView.swift
@@ -8,7 +8,8 @@
import UIKit
-public class WemoCellView: UICollectionViewCell {
+public class WemoCellView: UICollectionViewCell
+{
private var _selectionOverlayView: UIView = UIView()
static private var disabledBackgroundColor = UIColor(white: 0.2, alpha: 1.0)
diff --git a/XIONControlPanel/Views/XIONLogoView.swift b/XIONControlPanel/Views/XIONLogoView.swift
index 7a5de99..6f9d108 100644
--- a/XIONControlPanel/Views/XIONLogoView.swift
+++ b/XIONControlPanel/Views/XIONLogoView.swift
@@ -8,7 +8,8 @@
import UIKit
-class XIONLogoView: UIView {
+class XIONLogoView: UIView
+{
private var _xionLogoImageView: UIImageView = UIImageView()
private var _logoInnerRingImageView: UIImageView = UIImageView()
private var _logoOuterRingImageView: UIImageView = UIImageView()