diff --git a/KegBoard/board/kegboard.sch b/KegBoard/board/kegboard.sch index 79768bd..a697fd3 100644 Binary files a/KegBoard/board/kegboard.sch and b/KegBoard/board/kegboard.sch differ diff --git a/KegPad/Classes/Controllers/KBDisplayViewController.h b/KegPad/Classes/Controllers/KBDisplayViewController.h index dfc5241..4f40fa4 100644 --- a/KegPad/Classes/Controllers/KBDisplayViewController.h +++ b/KegPad/Classes/Controllers/KBDisplayViewController.h @@ -28,7 +28,6 @@ #import "KBUserView.h" #import "KBChalkLabel.h" - @class KBApplicationDelegate; /*! diff --git a/KegPad/Classes/Controllers/KBStatusViewController.h b/KegPad/Classes/Controllers/KBStatusViewController.h index 771dffd..c0a8faf 100644 --- a/KegPad/Classes/Controllers/KBStatusViewController.h +++ b/KegPad/Classes/Controllers/KBStatusViewController.h @@ -24,6 +24,7 @@ #import "KBKegTemperature.h" #import "KBChartView.h" #import "KBLeaderboardView.h" +#import "KBFlowIndicator.h" @class KBApplicationDelegate; @@ -45,6 +46,8 @@ KBChartView *chartView_; KBLeaderboardView *leaderboardView_; + + KBFlowIndicator *flowIndicator_; KBApplicationDelegate *delegate_; // weak } @@ -60,6 +63,7 @@ @property (nonatomic, retain) IBOutlet UILabel *totalPouredAmountLabel; @property (nonatomic, retain) IBOutlet KBChartView *chartView; @property (nonatomic, retain) IBOutlet KBLeaderboardView *leaderboardView; +@property (nonatomic, retain) IBOutlet KBFlowIndicator *flowIndicator; @property (nonatomic, assign) KBApplicationDelegate *delegate; diff --git a/KegPad/Classes/Controllers/KBStatusViewController.m b/KegPad/Classes/Controllers/KBStatusViewController.m index ceef0d9..86bdd16 100644 --- a/KegPad/Classes/Controllers/KBStatusViewController.m +++ b/KegPad/Classes/Controllers/KBStatusViewController.m @@ -34,10 +34,20 @@ @implementation KBStatusViewController lastPourAmountLabel=lastPourAmountLabel_, lastPourAmountUnitsLabel=lastPourAmountUnitsLabel_, percentRemaingLabel=percentRemaingLabel_, totalPouredAmountLabel=totalPouredAmountLabel_, temperatureLabel=temperatureLabel_, temperatureDescriptionLabel=temperatureDescriptionLabel_, -chartView=chartView_, leaderboardView=leaderboardView_, delegate=delegate_; +chartView=chartView_, leaderboardView=leaderboardView_, delegate=delegate_, flowIndicator=flowIndicator_; - (id)init { - if ((self = [super initWithNibName:nil bundle:nil])) { } + if ((self = [super initWithNibName:nil bundle:nil])) { + NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"KBFlowIndicator" owner:nil options:nil]; + for (id currentObject in topLevelObjects) { + if ([currentObject isKindOfClass:[KBFlowIndicator class]]) { + self.flowIndicator = currentObject; + break; + } + } + self.flowIndicator.frame = CGRectMake(20, 331, 402, 350); + [self.view addSubview:self.flowIndicator]; + } return self; } @@ -54,6 +64,7 @@ - (void)dealloc { [temperatureDescriptionLabel_ release]; [chartView_ release]; [leaderboardView_ release]; + [flowIndicator_ release]; [super dealloc]; } @@ -86,7 +97,7 @@ - (void)updateKeg:(KBKeg *)keg { percentRemaingLabel_.text = @""; totalPouredAmountLabel_.text = @"-"; } -} +} - (void)setLastKegPour:(KBKegPour *)kegPour { self.view; diff --git a/KegPad/Classes/Data/KBKegManager.m b/KegPad/Classes/Data/KBKegManager.m index a97a363..fbaf7e4 100644 --- a/KegPad/Classes/Data/KBKegManager.m +++ b/KegPad/Classes/Data/KBKegManager.m @@ -155,4 +155,8 @@ - (void)kegProcessing:(KBKegProcessing *)kegProcessing didReceiveRFIDTagId:(NSSt } } +- (void)kegProcessing:(KBKegProcessing *)kegProcessing didUpdatePourWithAmount:(double)amount flowRate:(double)flowRate { + [[NSNotificationCenter defaultCenter] postNotificationName:KBUpdatePourNotification object:kegProcessing]; +} + @end diff --git a/KegPad/Classes/KBNotifications.h b/KegPad/Classes/KBNotifications.h index 285f8c6..0f587eb 100644 --- a/KegPad/Classes/KBNotifications.h +++ b/KegPad/Classes/KBNotifications.h @@ -38,4 +38,6 @@ extern NSString *const KBUnknownTagIdNotification; // With tag id (NSString), if extern NSString *const KBDidSelectUserNotification; // With user (KBUser) -extern NSString *const KBActivityNotification; // If there is an user activity \ No newline at end of file +extern NSString *const KBActivityNotification; // If there is an user activity + +extern NSString *const KBUpdatePourNotification; // For when an active pour is updated \ No newline at end of file diff --git a/KegPad/Classes/KBNotifications.m b/KegPad/Classes/KBNotifications.m index 8ea6b06..def3369 100644 --- a/KegPad/Classes/KBNotifications.m +++ b/KegPad/Classes/KBNotifications.m @@ -39,4 +39,6 @@ NSString *const KBUnknownTagIdNotification = @"KBUnknownTagIdNotification"; NSString *const KBDidSelectUserNotification = @"KBDidSelectUserNotification"; -NSString *const KBActivityNotification = @"KBActivityNotification"; \ No newline at end of file +NSString *const KBActivityNotification = @"KBActivityNotification"; + +NSString *const KBUpdatePourNotification = @"KBUpdatePourNotification"; \ No newline at end of file diff --git a/KegPad/Classes/Processing/KBKegProcessing.h b/KegPad/Classes/Processing/KBKegProcessing.h index 35e4400..8704dc2 100644 --- a/KegPad/Classes/Processing/KBKegProcessing.h +++ b/KegPad/Classes/Processing/KBKegProcessing.h @@ -21,7 +21,6 @@ #import "KBKegboard.h" -#define KB_TEMPERATURE_DIFFERENCE_THRESHOLD 0.1 #define KB_VOLUME_DIFFERENCE_THRESHOLD 0.001 // Adjust this value based on the flow meter properties #define KB_VOLUME_PER_TICK 0.0001639344262 @@ -35,16 +34,14 @@ - (void)kegProcessing:(KBKegProcessing *)kegProcessing didChangeTemperature:(double)temperature; - (void)kegProcessing:(KBKegProcessing *)kegProcessing didReceiveRFIDTagId:(NSString *)tagID; //- (void)kegProcessing:(KBKegProcessing *)kegProcessing didError:(KBError *)error; +- (void)kegProcessing:(KBKegProcessing *)kegProcessing didUpdatePourWithAmount:(double)amount flowRate:(double)flowRate; @end - @interface KBKegProcessing : NSObject { id _delegate; KBKegboard *_kegboard; - - double _temperatureDifference; - + double _flowRate; // in litres / second double _lastVolume; @@ -58,5 +55,6 @@ @property (assign, nonatomic) id delegate; @property (readonly, nonatomic) double flowRate; +@property (readonly, nonatomic) double pourVolume; @end diff --git a/KegPad/Classes/Processing/KBKegProcessing.m b/KegPad/Classes/Processing/KBKegProcessing.m index f7ce1dd..10f6b6e 100644 --- a/KegPad/Classes/Processing/KBKegProcessing.m +++ b/KegPad/Classes/Processing/KBKegProcessing.m @@ -48,6 +48,10 @@ - (void)endPour { } } +- (double)pourVolume { + return _lastVolume - _pourStartVolume; +} + #pragma mark Delegates (KBKegboard) - (void)kegboard:(KBKegboard *)kegboard didReceiveHello:(KBKegboardMessageHello *)message { @@ -83,15 +87,11 @@ - (void)kegboard:(KBKegboard *)kegboard didReceiveMeterStatus:(KBKegboardMessage } } _lastVolume = volume; + [self.delegate kegProcessing:self didUpdatePourWithAmount:(volume - _pourStartVolume) flowRate:_flowRate]; } - (void)kegboard:(KBKegboard *)kegboard didReceiveTemperatureReading:(KBKegboardMessageTemperatureReading *)message { - // If difference since last message send is significant, notify delegate - double temperature = [message sensorReading]; - if (abs(temperature - _temperatureDifference) > KB_TEMPERATURE_DIFFERENCE_THRESHOLD) { - [self.delegate kegProcessing:self didChangeTemperature:temperature]; - _temperatureDifference = temperature; - } + [self.delegate kegProcessing:self didChangeTemperature:[message sensorReading]]; } - (void)kegboard:(KBKegboard *)kegboard didReceiveOutputStatus:(KBKegboardMessageOutputStatus *)message { } diff --git a/KegPad/Classes/Processing/KBKegboard.m b/KegPad/Classes/Processing/KBKegboard.m index 6aa3b36..d8b0902 100644 --- a/KegPad/Classes/Processing/KBKegboard.m +++ b/KegPad/Classes/Processing/KBKegboard.m @@ -106,7 +106,7 @@ - (void)readLoop { while (headerPosition < KBSP_PREFIX_LENGTH) { char byte; sleeperRead(gFileDescriptor, &byte, 1); - calculatedCRC = crc_update(calculatedCRC, &byte, 1); + calculatedCRC = crc_update(calculatedCRC, (unsigned char *)&byte, 1); // Byte was expected if (byte == KBSP_PREFIX[headerPosition]) { headerPosition += 1; @@ -127,7 +127,7 @@ - (void)readLoop { // Read message type and message length sleeperRead(gFileDescriptor, headerBytes, 4); - calculatedCRC = crc_update(calculatedCRC, headerBytes, 4); + calculatedCRC = crc_update(calculatedCRC, (unsigned char *)headerBytes, 4); NSInteger messageId = [KBKegboardMessage parseUInt16:headerBytes]; NSInteger messageLength = [KBKegboardMessage parseUInt16:&headerBytes[2]]; if (messageLength > KBSP_PAYLOAD_MAXLEN) { @@ -137,7 +137,7 @@ - (void)readLoop { // Read payload and trailer sleeperRead(gFileDescriptor, payload, messageLength); - calculatedCRC = crc_update(calculatedCRC, payload, messageLength); + calculatedCRC = crc_update(calculatedCRC, (unsigned char *)payload, messageLength); sleeperRead(gFileDescriptor, crc, 2); sleeperRead(gFileDescriptor, trailer, 2); diff --git a/KegPad/Classes/Views/KBFlowIndicator.h b/KegPad/Classes/Views/KBFlowIndicator.h new file mode 100644 index 0000000..29bd074 --- /dev/null +++ b/KegPad/Classes/Views/KBFlowIndicator.h @@ -0,0 +1,52 @@ +// +// KBFlowIndicator.h +// +// Created by John Boiles on 10/13/10. +// Copyright 2010 Yelp. 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +@interface KBFlowIndicator : UIView { + UIImageView *needleView_; + UIImageView *fillView_; + UILabel *volumeLabel_; + UILabel *flowLabel_; + + double _minimumFlowRate; + double _maximumFlowRate; + double _minimumAngle; + double _maximumAngle; + double _flowRate; + + double _minimumVolume; + double _maximumVolume; + double _minimumTopY; + double _maximumTopY; + double _volume; + + NSTimer *_simulationTimer; + BOOL _simulatedValueIncreasing; +} + +@property (nonatomic, retain) IBOutlet UIImageView *needleView; +@property (nonatomic, retain) IBOutlet UIImageView *fillView; +@property (nonatomic, retain) IBOutlet UILabel *volumeLabel; +@property (nonatomic, retain) IBOutlet UILabel *flowLabel; + +- (void)setFlowRate:(double)flowRate animated:(BOOL)animated; + +- (void)setVolume:(double)volume animated:(BOOL)animated; + +@end diff --git a/KegPad/Classes/Views/KBFlowIndicator.m b/KegPad/Classes/Views/KBFlowIndicator.m new file mode 100644 index 0000000..d15b8db --- /dev/null +++ b/KegPad/Classes/Views/KBFlowIndicator.m @@ -0,0 +1,131 @@ +// +// KBFlowIndicator.m +// +// Created by John Boiles on 10/13/10. +// Copyright 2010 Yelp. 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#import "KBFlowIndicator.h" +#import "KBKegProcessing.h" +#import "KBNotifications.h" +#import "KBTypes.h" + +@implementation KBFlowIndicator + +@synthesize needleView=needleView_, fillView=fillView_, volumeLabel=volumeLabel_, flowLabel=flowLabel_; + +- (void)awakeFromNib { + _minimumFlowRate = 0; + _maximumFlowRate = 1; + _minimumAngle = -0.41 * M_PI; + _maximumAngle = 0.41 * M_PI; + _flowRate = 0; + + _minimumVolume = 0; + _maximumVolume = 16; + _minimumTopY = 306; + _maximumTopY = 210; + _volume = 0; + + [self setFlowRate:0 animated:NO]; + [self setVolume:0 animated:NO]; + //[self simulateValues]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_onUpdatePourNotification:) name:KBUpdatePourNotification object:nil]; +} + +- (void)setRotationRadians:(CGFloat)radians animated:(BOOL)animated { + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationCurve:UIViewAnimationCurveLinear]; + [UIView setAnimationDuration:0.1]; + [UIView setAnimationBeginsFromCurrentState:YES]; + CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, radians); + needleView_.transform = CGAffineTransformTranslate(transform, 0, -71); + [UIView commitAnimations]; + } else { + CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, radians); + needleView_.transform = CGAffineTransformTranslate(transform, 0, -71); + [needleView_ setNeedsDisplay]; + } +} + +- (void)setFlowRate:(double)flowRate animated:(BOOL)animated { + [flowLabel_ setText:[NSString stringWithFormat:@"%0.1f", flowRate]]; + if (flowRate > _maximumFlowRate) flowRate = _maximumFlowRate; + if (flowRate < _minimumFlowRate) flowRate = _minimumFlowRate; + _flowRate = flowRate; + double fraction = (flowRate - _minimumFlowRate) / (_maximumFlowRate - _minimumFlowRate); + double angle = fraction * (_maximumAngle - _minimumAngle) + _minimumAngle; + [[self gh_proxyOnMainThread] setRotationRadians:angle animated:animated]; +} + +- (void)setTopY:(CGFloat)topY animated:(BOOL)animated { + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationCurve:UIViewAnimationCurveLinear]; + [UIView setAnimationDuration:0.1]; + [UIView setAnimationBeginsFromCurrentState:YES]; + fillView_.frame = CGRectMake(fillView_.frame.origin.x, topY, fillView_.frame.size.width, fillView_.frame.size.height); + [UIView commitAnimations]; + } else { + fillView_.frame = CGRectMake(fillView_.frame.origin.x, topY, fillView_.frame.size.width, fillView_.frame.size.height); + [fillView_ setNeedsDisplay]; + } +} + +- (void)setVolume:(double)volume animated:(BOOL)animated { + [volumeLabel_ setText:[NSString stringWithFormat:@"%0.1f", volume]]; + if (volume > _maximumVolume) volume = _maximumVolume; + if (volume < _minimumVolume) volume = _minimumVolume; + _volume = volume; + double fraction = (volume - _minimumVolume) / (_maximumVolume - _minimumVolume); + CGFloat topY = fraction * (_maximumTopY - _minimumTopY) + _minimumTopY; + [[self gh_proxyOnMainThread] setTopY:topY animated:animated]; +} + +- (void)simulateValues { + _simulationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(setSimulatedValue) userInfo:nil repeats:YES] retain]; + _simulatedValueIncreasing = YES; +} + +- (void)setSimulatedValue { + double interval = (_maximumFlowRate - _minimumFlowRate) / 20; + double interval2 = (_maximumVolume - _minimumVolume) / 20; + if (_simulatedValueIncreasing) { + _flowRate += interval; + _volume += interval2; + if (_flowRate > _maximumFlowRate) { + _simulatedValueIncreasing = NO; + } + } else { + _flowRate -= interval; + _volume -= interval2; + if (_flowRate < _minimumFlowRate) { + _simulatedValueIncreasing = YES; + } + } + [self setVolume:_volume animated:YES]; + [self setFlowRate:_flowRate animated:YES]; +} + +- (void)_onUpdatePourNotification:(NSNotification *)notification { + KBKegProcessing *kegProcessing = (KBKegProcessing *)[notification object]; + [self setVolume:kegProcessing.pourVolume * kLitersToOunces animated:YES]; + [self setFlowRate:kegProcessing.flowRate * kLitersToOunces animated:YES]; +} + +@end diff --git a/KegPad/KegPad.xcodeproj/project.pbxproj b/KegPad/KegPad.xcodeproj/project.pbxproj index ab735a0..95ac0c1 100755 --- a/KegPad/KegPad.xcodeproj/project.pbxproj +++ b/KegPad/KegPad.xcodeproj/project.pbxproj @@ -113,6 +113,14 @@ 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 28D801B40F44B63D00FB423F /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D801B30F44B63D00FB423F /* CoreData.framework */; }; + 427AC48C126585C50063CE3C /* flow_at_symbol.png in Resources */ = {isa = PBXBuildFile; fileRef = 427AC486126585C50063CE3C /* flow_at_symbol.png */; }; + 427AC48D126585C50063CE3C /* flow_background.png in Resources */ = {isa = PBXBuildFile; fileRef = 427AC487126585C50063CE3C /* flow_background.png */; }; + 427AC48E126585C50063CE3C /* flow_fill.png in Resources */ = {isa = PBXBuildFile; fileRef = 427AC488126585C50063CE3C /* flow_fill.png */; }; + 427AC48F126585C50063CE3C /* flow_foreground.png in Resources */ = {isa = PBXBuildFile; fileRef = 427AC489126585C50063CE3C /* flow_foreground.png */; }; + 427AC490126585C50063CE3C /* flow_needle.png in Resources */ = {isa = PBXBuildFile; fileRef = 427AC48A126585C50063CE3C /* flow_needle.png */; }; + 427AC491126585C50063CE3C /* flow_shadow.png in Resources */ = {isa = PBXBuildFile; fileRef = 427AC48B126585C50063CE3C /* flow_shadow.png */; }; + 427AC71D1266A5640063CE3C /* KBFlowIndicator.xib in Resources */ = {isa = PBXBuildFile; fileRef = 427AC71C1266A5640063CE3C /* KBFlowIndicator.xib */; }; + 427AC7241266A9C90063CE3C /* KBFlowIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 427AC7221266A9C90063CE3C /* KBFlowIndicator.m */; }; 429B08EB1202FEF600C36F76 /* Glass.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 429B08EA1202FEF600C36F76 /* Glass.aiff */; }; 429B08EE1202FF5300C36F76 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 429B08ED1202FF5300C36F76 /* AudioToolbox.framework */; }; 429B094D1203371700C36F76 /* KBRatingPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 429B094C1203371700C36F76 /* KBRatingPicker.m */; }; @@ -285,6 +293,15 @@ 28D801B30F44B63D00FB423F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* KegPad_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KegPad_Prefix.pch; sourceTree = ""; }; + 427AC486126585C50063CE3C /* flow_at_symbol.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flow_at_symbol.png; sourceTree = ""; }; + 427AC487126585C50063CE3C /* flow_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flow_background.png; sourceTree = ""; }; + 427AC488126585C50063CE3C /* flow_fill.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flow_fill.png; sourceTree = ""; }; + 427AC489126585C50063CE3C /* flow_foreground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flow_foreground.png; sourceTree = ""; }; + 427AC48A126585C50063CE3C /* flow_needle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flow_needle.png; sourceTree = ""; }; + 427AC48B126585C50063CE3C /* flow_shadow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flow_shadow.png; sourceTree = ""; }; + 427AC71C1266A5640063CE3C /* KBFlowIndicator.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KBFlowIndicator.xib; sourceTree = ""; }; + 427AC7221266A9C90063CE3C /* KBFlowIndicator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KBFlowIndicator.m; sourceTree = ""; }; + 427AC7231266A9C90063CE3C /* KBFlowIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KBFlowIndicator.h; sourceTree = ""; }; 429B08EA1202FEF600C36F76 /* Glass.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; path = Glass.aiff; sourceTree = ""; }; 429B08ED1202FF5300C36F76 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 429B094B1203371700C36F76 /* KBRatingPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KBRatingPicker.h; sourceTree = ""; }; @@ -340,6 +357,7 @@ 00D3534D1266ABB5005FF0B6 /* graph_background.png */, 00D353431266AA59005FF0B6 /* beer_button_icon.png */, 00D353441266AA59005FF0B6 /* status_button_icon.png */, + 427AC485126585C50063CE3C /* FlowMeter */, 00D35181126556A0005FF0B6 /* Stars */, 00D35188126556A0005FF0B6 /* StarsChalk */, 004E1B0B12655172004B0AC0 /* admin_button.png */, @@ -444,6 +462,8 @@ 00568FAE1251A493004AF3D1 /* KBUserView.m */, 00983D8C125EE8520031006C /* KBUIWindow.h */, 00983D8D125EE8520031006C /* KBUIWindow.m */, + 427AC7231266A9C90063CE3C /* KBFlowIndicator.h */, + 427AC7221266A9C90063CE3C /* KBFlowIndicator.m */, ); path = Views; sourceTree = ""; @@ -691,6 +711,7 @@ 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 00D54CC81202BBEB00F76724 /* KBStatusViewController.xib */, 0017B7C612021B1A00269CDA /* KBDisplayViewController.xib */, + 427AC71C1266A5640063CE3C /* KBFlowIndicator.xib */, ); path = Resources; sourceTree = ""; @@ -710,6 +731,19 @@ name = Frameworks; sourceTree = ""; }; + 427AC485126585C50063CE3C /* FlowMeter */ = { + isa = PBXGroup; + children = ( + 427AC486126585C50063CE3C /* flow_at_symbol.png */, + 427AC487126585C50063CE3C /* flow_background.png */, + 427AC488126585C50063CE3C /* flow_fill.png */, + 427AC489126585C50063CE3C /* flow_foreground.png */, + 427AC48A126585C50063CE3C /* flow_needle.png */, + 427AC48B126585C50063CE3C /* flow_shadow.png */, + ); + path = FlowMeter; + sourceTree = ""; + }; 429B08E91202FEF600C36F76 /* Sounds */ = { isa = PBXGroup; children = ( @@ -816,6 +850,13 @@ 00D353461266AA59005FF0B6 /* status_button_icon.png in Resources */, 00D3534E1266ABB5005FF0B6 /* graph_background.png in Resources */, 00D353581266AF4A005FF0B6 /* literboard_background.png in Resources */, + 427AC48C126585C50063CE3C /* flow_at_symbol.png in Resources */, + 427AC48D126585C50063CE3C /* flow_background.png in Resources */, + 427AC48E126585C50063CE3C /* flow_fill.png in Resources */, + 427AC48F126585C50063CE3C /* flow_foreground.png in Resources */, + 427AC490126585C50063CE3C /* flow_needle.png in Resources */, + 427AC491126585C50063CE3C /* flow_shadow.png in Resources */, + 427AC71D1266A5640063CE3C /* KBFlowIndicator.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -881,6 +922,7 @@ 009840151262D63A0031006C /* KBUIFormSwitchCell.m in Sources */, 0098401A1262D76F0031006C /* KBUIFormSwitch.m in Sources */, 00D353A21266B5B3005FF0B6 /* KBCGUtils.m in Sources */, + 427AC7241266A9C90063CE3C /* KBFlowIndicator.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/KegPad/Resources/Images/FlowMeter/flow_at_symbol.png b/KegPad/Resources/Images/FlowMeter/flow_at_symbol.png new file mode 100644 index 0000000..f39e652 Binary files /dev/null and b/KegPad/Resources/Images/FlowMeter/flow_at_symbol.png differ diff --git a/KegPad/Resources/Images/FlowMeter/flow_background.png b/KegPad/Resources/Images/FlowMeter/flow_background.png new file mode 100644 index 0000000..73f1f63 Binary files /dev/null and b/KegPad/Resources/Images/FlowMeter/flow_background.png differ diff --git a/KegPad/Resources/Images/FlowMeter/flow_fill.png b/KegPad/Resources/Images/FlowMeter/flow_fill.png new file mode 100644 index 0000000..03cac43 Binary files /dev/null and b/KegPad/Resources/Images/FlowMeter/flow_fill.png differ diff --git a/KegPad/Resources/Images/FlowMeter/flow_foreground.png b/KegPad/Resources/Images/FlowMeter/flow_foreground.png new file mode 100644 index 0000000..5c642be Binary files /dev/null and b/KegPad/Resources/Images/FlowMeter/flow_foreground.png differ diff --git a/KegPad/Resources/Images/FlowMeter/flow_needle.png b/KegPad/Resources/Images/FlowMeter/flow_needle.png new file mode 100644 index 0000000..d6024b8 Binary files /dev/null and b/KegPad/Resources/Images/FlowMeter/flow_needle.png differ diff --git a/KegPad/Resources/Images/FlowMeter/flow_shadow.png b/KegPad/Resources/Images/FlowMeter/flow_shadow.png new file mode 100644 index 0000000..a75d04d Binary files /dev/null and b/KegPad/Resources/Images/FlowMeter/flow_shadow.png differ diff --git a/KegPad/Resources/KBFlowIndicator.xib b/KegPad/Resources/KBFlowIndicator.xib new file mode 100644 index 0000000..2a85a98 --- /dev/null +++ b/KegPad/Resources/KBFlowIndicator.xib @@ -0,0 +1,752 @@ + + + + 800 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 301 + + YES + + + 256 + {{55, 33}, {285, 285}} + + NO + IBCocoaTouchFramework + + NSImage + flow_background.png + + + + + 292 + + YES + + + 292 + {{49, 304}, {303, 115}} + + NO + IBCocoaTouchFramework + + NSImage + flow_fill.png + + + + {402, 349} + + + 3 + MSAwAA + + 2 + + + YES + IBCocoaTouchFramework + + + + 292 + {{57, 34}, {282, 282}} + + NO + IBCocoaTouchFramework + + NSImage + flow_shadow.png + + + + + 292 + {402, 350} + + NO + IBCocoaTouchFramework + + NSImage + flow_foreground.png + + + + + 292 + {{195, 105}, {11, 142}} + + NO + IBCocoaTouchFramework + + NSImage + flow_needle.png + + + + + 292 + {{181, 159}, {40, 40}} + + NO + IBCocoaTouchFramework + + NSImage + flow_at_symbol.png + + + + + 292 + {{67, 162}, {77, 34}} + + NO + YES + 7 + NO + IBCocoaTouchFramework + 00.0 + + Helvetica + 32 + 16 + + + 1 + MCAwIDAAA + + + 3 + MQA + + 1 + 32 + 2 + + + + 292 + {{145, 160}, {26, 21}} + + NO + YES + 7 + NO + IBCocoaTouchFramework + oz + + + 1 + 10 + + + + 292 + {{229, 162}, {63, 34}} + + NO + YES + 7 + NO + IBCocoaTouchFramework + 0.0 + + Helvetica + 34 + 16 + + + + 1 + 32 + 2 + + + + 292 + {{293, 160}, {42, 21}} + + NO + YES + 7 + NO + IBCocoaTouchFramework + oz/s + + + 1 + 10 + + + {402, 350} + + + 3 + MSAwAA + + + YES + IBCocoaTouchFramework + + + + + YES + + + needleView + + + + 23 + + + + flowLabel + + + + 25 + + + + fillView + + + + 28 + + + + volumeLabel + + + + 29 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + + + + + + + + + + 3 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + Volume + + + 10 + + + Volume Units + + + 11 + + + Flow + + + 12 + + + Flow Units + + + 30 + + + YES + + + + + + 4 + + + + + + + YES + + YES + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 11.IBViewBoundsToFrameTransform + 12.IBPluginDependency + 12.IBViewBoundsToFrameTransform + 2.CustomClassName + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.IBPluginDependency + 3.IBViewBoundsToFrameTransform + 30.IBPluginDependency + 30.IBViewBoundsToFrameTransform + 4.IBPluginDependency + 4.IBViewBoundsToFrameTransform + 5.IBPluginDependency + 6.IBPluginDependency + 6.IBViewBoundsToFrameTransform + 7.IBPluginDependency + 8.IBPluginDependency + 8.IBViewBoundsToFrameTransform + 9.IBPluginDependency + 9.IBViewBoundsToFrameTransform + + + YES + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUNvAABDIgAAA + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAABDNAAAwzgAAA + + KBFlowIndicator + {{1236, 614}, {402, 350}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAABCqAAAw6eAAA + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AULyAABCcAAAA + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUJEAABDmQAAA + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAAAAAAAAw64AAA + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAABC0gAAw0kAAA + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + P4AAAL+AAABDNAAAwzgAAA + + + + + YES + + + YES + + + + + YES + + + YES + + + + 30 + + + + YES + + KBFlowIndicator + UIView + + YES + + YES + fillView + flowLabel + needleView + volumeLabel + + + YES + UIImageView + UILabel + UIImageView + UILabel + + + + YES + + YES + fillView + flowLabel + needleView + volumeLabel + + + YES + + fillView + UIImageView + + + flowLabel + UILabel + + + needleView + UIImageView + + + volumeLabel + UILabel + + + + + IBProjectSource + Classes/Views/KBFlowIndicator.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + GHKitIOS.framework/Headers/GHNSObject+Invocation.h + + + + NSObject + + IBFrameworkSource + GHKitIOS.framework/Headers/GHNSObject+Swizzle.h + + + + NSObject + + IBFrameworkSource + GHKitIOS.framework/Headers/GHNSObject+Utils.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CAAnimation.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CALayer.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + NSObject + + IBFrameworkSource + YAJLIOS.framework/Headers/NSObject+YAJL.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../KegPad.xcodeproj + 3 + + YES + + YES + flow_at_symbol.png + flow_background.png + flow_fill.png + flow_foreground.png + flow_needle.png + flow_shadow.png + + + YES + {40, 40} + {285, 285} + {303, 115} + {402, 350} + {11, 142} + {282, 282} + + + 123 + +