diff --git a/README.md b/README.md index 11c5504..ab94738 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ My plan is to: ## Versions + +### 1.2 +Updated Watch app and added functioning WatchTips. Watch app can now be used to calculate Bill split and tips. + ### 1.1 After using XCode to define a simulator with an attached Watch Emulator the standard Vanilla app (from 1.0) was updated as follows diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e8c18e9..56e4086 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 2D020CB721FEF3D200DC71C2 /* SplitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D020CB621FEF3D200DC71C2 /* SplitController.swift */; }; + 2D020CB921FEF5A100DC71C2 /* BillController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D020CB821FEF5A100DC71C2 /* BillController.swift */; }; 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 2D69490521FDFD9600B94252 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2D69490321FDFD9600B94252 /* Interface.storyboard */; }; 2D69490721FDFD9700B94252 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2D69490621FDFD9700B94252 /* Assets.xcassets */; }; @@ -16,6 +18,7 @@ 2D69491521FDFD9700B94252 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69491421FDFD9700B94252 /* ExtensionDelegate.swift */; }; 2D69491721FDFD9700B94252 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2D69491621FDFD9700B94252 /* Assets.xcassets */; }; 2D69491B21FDFD9700B94252 /* WatchTips.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 2D69490121FDFD9600B94252 /* WatchTips.app */; }; + 2D69492921FE165500B94252 /* TipController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69492821FE165500B94252 /* TipController.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -86,6 +89,8 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2D020CB621FEF3D200DC71C2 /* SplitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitController.swift; sourceTree = ""; }; + 2D020CB821FEF5A100DC71C2 /* BillController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BillController.swift; sourceTree = ""; }; 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 2D69490121FDFD9600B94252 /* WatchTips.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WatchTips.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2D69490421FDFD9600B94252 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; @@ -96,6 +101,7 @@ 2D69491421FDFD9700B94252 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; 2D69491621FDFD9700B94252 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2D69491821FDFD9700B94252 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2D69492821FE165500B94252 /* TipController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipController.swift; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -147,8 +153,11 @@ children = ( 2D69491221FDFD9700B94252 /* InterfaceController.swift */, 2D69491421FDFD9700B94252 /* ExtensionDelegate.swift */, + 2D69492821FE165500B94252 /* TipController.swift */, 2D69491621FDFD9700B94252 /* Assets.xcassets */, 2D69491821FDFD9700B94252 /* Info.plist */, + 2D020CB621FEF3D200DC71C2 /* SplitController.swift */, + 2D020CB821FEF5A100DC71C2 /* BillController.swift */, ); path = "WatchTips Extension"; sourceTree = ""; @@ -385,8 +394,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2D020CB721FEF3D200DC71C2 /* SplitController.swift in Sources */, + 2D020CB921FEF5A100DC71C2 /* BillController.swift in Sources */, 2D69491521FDFD9700B94252 /* ExtensionDelegate.swift in Sources */, 2D69491321FDFD9700B94252 /* InterfaceController.swift in Sources */, + 2D69492921FE165500B94252 /* TipController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/WatchTips Extension/BillController.swift b/ios/WatchTips Extension/BillController.swift new file mode 100644 index 0000000..fcc0c5c --- /dev/null +++ b/ios/WatchTips Extension/BillController.swift @@ -0,0 +1,147 @@ +// +// BillController.swift +// WatchTips Extension +// +// Created by Stephen Rogers on 28/01/2019. +// Copyright © 2019 The Chromium Authors. All rights reserved. +// + +import WatchKit +import Foundation + + +class BillController: WKInterfaceController { + + + var billValue = "0" + var decimalAdded = false + var sourceController: InterfaceController! + @IBOutlet weak var totalAmount: WKInterfaceLabel! + + + + override func awake(withContext context: Any?) { + super.awake(withContext: context) + + // Configure interface objects here. + sourceController = context as? InterfaceController + if sourceController.billTotal != 0.0 { + billValue = "\(sourceController.billTotal)" + } else { + billValue = "0" + } + displayBillValue() + + } + + override func willActivate() { + // This method is called when watch view controller is about to be visible to user + super.willActivate() + } + + override func didDeactivate() { + // This method is called when watch view controller is no longer visible + super.didDeactivate() + } + + + // Clear + @IBAction func clearBtn() { + billValue.remove(at: billValue.index(before: billValue.endIndex)) + if billValue.count == 0 { + billValue = "0" + } + displayBillValue() + } + + + @IBAction func decimalBtn() { + appendDecimal() + } + + + @IBAction func zeroBtn() { + appendValue(value: 0) + } + + + @IBAction func oneBtn() { + appendValue(value: 1) + } + + + @IBAction func twoBtn() { + appendValue(value: 2) + } + + @IBAction func threeBtn() { + appendValue(value: 3) + } + + + @IBAction func fourBtn() { + appendValue(value: 4) + } + + + @IBAction func fiveBtn() { + appendValue(value: 5) + } + + + @IBAction func sixBtn() { + appendValue(value: 6) + } + + + @IBAction func sevenBtn() { + appendValue(value: 7) + } + + + @IBAction func eightBtn() { + appendValue(value: 8) + } + + @IBAction func nineBtn() { + appendValue(value: 9) + } + + // display the bill value and update amount in source controller + func displayBillValue(){ + if let _ = billValue.index(of: (".")) { + decimalAdded = true + } else { + decimalAdded = false + } + totalAmount.setText(billValue) + sourceController.billTotal = Double(billValue)! + } + + // Append an amount to the displayed bill + func appendValue(value: Int){ + + let stringValue = "\(value)" + if(billValue == "0"){ + billValue = stringValue + } else { + billValue = billValue + stringValue + } + displayBillValue() + } + + // only add decimal if not already added + func appendDecimal(){ + + // did we have a decimal? + if !decimalAdded { + billValue = billValue + "." + } + + // display total + displayBillValue() + + + } + +} diff --git a/ios/WatchTips Extension/InterfaceController.swift b/ios/WatchTips Extension/InterfaceController.swift index 0d3f425..1281caf 100644 --- a/ios/WatchTips Extension/InterfaceController.swift +++ b/ios/WatchTips Extension/InterfaceController.swift @@ -10,22 +10,98 @@ import WatchKit import Foundation -class InterfaceController: WKInterfaceController { +class InterfaceController: WKInterfaceController, WKCrownDelegate { + + + var tipAmount: Int = 10 + var splitBetween: Int = 1 + var billTotal = Double(0) + var focusButton: Int = 0 + var accumulatedCrownDelta = 0.0 + @IBOutlet weak var currentSplit: WKInterfaceButton! + @IBOutlet weak var currentTip: WKInterfaceButton! + @IBOutlet weak var billButton: WKInterfaceButton! + @IBOutlet weak var currentTotal: WKInterfaceLabel! + @IBOutlet weak var costEach: WKInterfaceLabel! + @IBOutlet weak var withTip: WKInterfaceLabel! + + + func crownDidBecomeIdle(_ crownSequencer: WKCrownSequencer?) { + accumulatedCrownDelta = 0.0 + } + + func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) { + accumulatedCrownDelta += rotationalDelta + //let threshoold = 0.5 + + + } + + override func awake(withContext context: Any?) { super.awake(withContext: context) // Configure interface objects here. + crownSequencer.delegate = self + updateCalc() } override func willActivate() { // This method is called when watch view controller is about to be visible to user super.willActivate() + + crownSequencer.focus() + updateCalc() } override func didDeactivate() { // This method is called when watch view controller is no longer visible super.didDeactivate() } + + + // chnage how many the bill is split between + @IBAction func showSplitController() { + presentController(withName: "SplitController", context: self) + } + + + @IBAction func showTipController() { + presentController(withName: "TipController", context: self) + } + + + @IBAction func showBillController() { + presentController(withName: "BillController", context: self) + } + + // Update the actual calculations + func updateCalc(){ + + // do bill calculations + let tip = (billTotal/100) * Double(tipAmount) + let billWithTip = billTotal + tip + let perPerson = billWithTip / Double(splitBetween) + + // update display + currentTip.setTitle("\(tipAmount)%") + currentSplit.setTitle("\(splitBetween)") + currentTotal.setText(String(format: "%.2f", billTotal)) + withTip.setText(String(format: "%.2f", billWithTip)) + costEach.setText(String(format: "%.2f", perPerson)) + + // now see if we can sent the calc data back to the app + //if WCSession.isSupported() { + // let session = WCSession.default() + // let calcInfo = [ + // "tip":"\(tipAmount)", + // "split": "\(splitBetween)", + // "bill": "\(billTotal)" + // ] as [String : Any]; + // session.transferUserInfo(calcInfo) + //} + } + } diff --git a/ios/WatchTips Extension/SplitController.swift b/ios/WatchTips Extension/SplitController.swift new file mode 100644 index 0000000..f1b4fdc --- /dev/null +++ b/ios/WatchTips Extension/SplitController.swift @@ -0,0 +1,62 @@ +// +// SplitController.swift +// WatchTips Extension +// +// Created by Stephen Rogers on 28/01/2019. +// Copyright © 2019 The Chromium Authors. All rights reserved. +// + +import WatchKit +import Foundation + + +class SplitController: WKInterfaceController { + + + @IBOutlet weak var splitBetween: WKInterfaceLabel! + var split: Int = 1 + var sourceController: InterfaceController! + + + override func awake(withContext context: Any?) { + super.awake(withContext: context) + + // Configure interface objects here. + sourceController = context as? InterfaceController + split = sourceController.splitBetween + updateSplit() + } + + override func willActivate() { + // This method is called when watch view controller is about to be visible to user + super.willActivate() + } + + override func didDeactivate() { + // This method is called when watch view controller is no longer visible + super.didDeactivate() + } + + // update the slit display and the bill split + func updateSplit(){ + sourceController.splitBetween = split + splitBetween.setText("\(split)") + } + + @IBAction func increaseSplit() { + if split < 50 { + split += 1 + updateSplit() + } + } + + + @IBAction func decreaseSplit() { + if split > 1 { + split -= 1 + updateSplit() + } + } + + +} diff --git a/ios/WatchTips Extension/TipController.swift b/ios/WatchTips Extension/TipController.swift new file mode 100644 index 0000000..90f8c9a --- /dev/null +++ b/ios/WatchTips Extension/TipController.swift @@ -0,0 +1,58 @@ +// +// TipController.swift +// WatchTips Extension +// +// Created by Stephen Rogers on 27/01/2019. +// Copyright © 2019 The Chromium Authors. All rights reserved. +// + +import WatchKit +import Foundation + + +class TipController: WKInterfaceController { + + var sourceController: InterfaceController! + var tip: Int=0 + @IBOutlet weak var tipPercent: WKInterfaceLabel! + + override func awake(withContext context: Any?) { + super.awake(withContext: context) + + // Configure interface objects here. + sourceController = context as? InterfaceController + tip = sourceController.tipAmount + displayTip() + } + + // display the current tip value and reset the actual value + func displayTip(){ + sourceController.tipAmount = tip + tipPercent.setText("\(tip)%") + } + + @IBAction func increaseTip() { + if tip < 100 { + tip += 1 + } + displayTip(); + } + + @IBAction func decreaseTip() { + if tip != 0 { + tip -= 1 + } + displayTip(); + } + + override func willActivate() { + // This method is called when watch view controller is about to be visible to user + super.willActivate() + } + + override func didDeactivate() { + // This method is called when watch view controller is no longer visible + super.didDeactivate() + } + +} diff --git a/ios/WatchTips/Base.lproj/Interface.storyboard b/ios/WatchTips/Base.lproj/Interface.storyboard index 9c7696b..18f0a5f 100644 --- a/ios/WatchTips/Base.lproj/Interface.storyboard +++ b/ios/WatchTips/Base.lproj/Interface.storyboard @@ -1,6 +1,6 @@ - + @@ -14,11 +14,240 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +