// // CommandClassControlDetailView.m // kneet // // Created by Jason Lee on 3/16/15. // Copyright (c) 2015 ntels. All rights reserved. // #import "JDObject.h" #import "RequestHandler.h" #import "JDJSONModel.h" #import "DeviceModel.h" #import "CustomLabel.h" #import "CommonUtil.h" #import "CustomButton.h" #import "CustomRadioGroup.h" #import "UIImageView+WebCache.h" #import "CommandClassControlDetailView.h" #import "CommandClassControlView.h" #import "CustomImageView.h" #define GRAPH_ANI_DUR 0.5f #define DEGREES(radians)((radians) * 180 / M_PI) #define RADIANS(degree)((degree) * M_PI / 180) typedef void(^NodeCommandCompletionBlock)(id result); typedef void(^NodeCommandFailureBlock)(id error); @implementation CommandClassControlDetailView + (CommandClassControlView *)viewForCommandClass:(CmdClsType)cmdClsType { CommandClassControlView *controlView = nil; for (UIView *view in [CommonUtil nibViews:@"CommandClassControlDetailView"]) { if (view.tag == cmdClsType) { controlView = (CommandClassControlView *)view; break; } } if (!controlView) {//상위 부모에서 가져옴. controlView = [CommandClassControlView viewForCommandClass:cmdClsType]; } return controlView; } @end @implementation CommandClassSwitchDetailView @end @interface CommandClassThermostatModeDetailView () { CustomRadioGroup *_rgroup; } @end @implementation CommandClassThermostatModeDetailView - (void)willMoveToSuperview:(UIView *)newSuperview { if (!newSuperview) return; [self initControl]; } - (void)initControl { _rgroup = [[CustomRadioGroup alloc] init]; _rgroup.delegate = self; [self setLayoutUI]; } - (CustomBgRadioButton *)getModeButton:(CmdClsValueModel *)mode { UIImage *nimage = [UIImage imageNamed:@"tp_01_img_control_bg_black"]; UIImage *himage = [UIImage imageNamed:@"tp_01_img_control_bg_active"]; CustomBgRadioButton *rdoMode = [[CustomBgRadioButton alloc] initWithFrame:CGRectMake(0, 0, kfControlDefaultWidth, kfControlDefaultHeight) bgNormalImage:nimage bgHighlightImage:himage rectForCapBg:CGRectMake(40, 0, 40, 0)]; rdoMode.value = mode; rdoMode.titleLabel.font = [UIFont boldSystemFontOfSize:kUIFontSize02]; [rdoMode setTitleColor:kUITextColor01 forState:UIControlStateNormal]; [rdoMode setTitle:mode.cmdclsValueMsg forState:UIControlStateNormal]; rdoMode.titleColorNormal = kUITextColor01; rdoMode.titleColorHighlight = kUITextColor04; return rdoMode; } - (void)setLayoutUI { _modeArray = [_node cmdclsValueList]; NSString *mode; NSUInteger highest = 0, i = 0; for (CmdClsValueModel *tmpCmdclsValue in _modeArray) { if (tmpCmdclsValue.cmdclsValueMsg.length > highest) { highest = tmpCmdclsValue.cmdclsValueMsg.length; mode = tmpCmdclsValue.cmdclsValueMsg; } } CGFloat width = [CommonUtil getSizeFromString:mode font:[UIFont boldSystemFontOfSize:kUIFontSize02] width:FLT_MAX].width + kfSwitchLabelPadding; CGFloat eWidth = width + kfCommandClassSwitchLeftPadding + kfCommandClassSwitchRightPadding; eWidth = eWidth < kfControlDefaultWidth ? kfControlDefaultWidth : eWidth; CustomBgRadioButton *_prevRadio, *_selectedRadio; for (CmdClsValueModel *tmpCmdclsValue in _modeArray) { CustomBgRadioButton *rdoMode = [self getModeButton:tmpCmdclsValue]; [self addSubview:rdoMode]; // rdoMode.checked = i == 0; [_rgroup addRadioButton:rdoMode]; [rdoMode mas_makeConstraints:^(MASConstraintMaker *make) { if (i == 0) { make.top.mas_equalTo(10); } else { make.top.equalTo(_prevRadio.mas_bottom).offset(5); //adjust padding 5px } make.left.equalTo(self); make.width.mas_equalTo(eWidth); make.height.mas_equalTo(kfControlDefaultHeight); }]; if ([_device.contentValue isEqualToString:tmpCmdclsValue.cmdclsValue]) { _selectedRadio = rdoMode; } _prevRadio = rdoMode; i++; } if (!_selectedRadio) { _selectedRadio = _rgroup.rdoBtns.firstObject; } [_rgroup someRadioButtonTouched:_selectedRadio]; //리스트에도 수정. CGRect sr = self.frame; sr.size.width = eWidth; sr.size.height = (kfControlDefaultHeight + 5.0f) * _modeArray.count; self.frame = sr; } - (CGSize)sizeForIntrinsic { CGFloat height = (kfControlDefaultHeight + 5.0f) * [_node cmdclsValueList].count; return CGSizeMake(kfControlMaxWidth, height); } - (CGSize)sizeForIntrinsicForItemCount:(NSInteger)count { CGFloat height = (kfControlDefaultHeight + 5.0f) * count; return CGSizeMake(kfControlMaxWidth, height); } - (void)didSomeRadioButtonTouched:(id)sender { if (_isConditionMode) //룰, 씬일 경우, 제어를 하지 않음 return; CustomBgRadioButton *rdoMode = (CustomBgRadioButton *)sender; CmdClsValueModel *cmdclsValue = rdoMode.value; [self updateThingsViewContoller]; NSString *requestValue = cmdclsValue.cmdclsValue; [CommandClassControlView requestNodeCommand:self.parameterForNodeCommand requestValue:requestValue completionHandler:nil failureHandler:nil]; } @end @implementation CommandClassThermostatFanModeDetailView @end @implementation CommandClassThermostatSetPointDetailView @end @implementation CommandClassLockDetailView @end @implementation CommandClassAVPlaybackDetailView @end #pragma mark - Sensors View @implementation CommandClassSensorBinaryDetailView @end @implementation CommandClassSensorMultiLevelDetailView @end @implementation CommandClassMeterCurrentOfDAWONView - (void)willMoveToSuperview:(UIView *)newSuperview { if (!newSuperview) return; [self initControl]; } - (void)initControl { [self setLayoutUI]; } - (void)setLayoutUI { _device = _device ? _device : _node; NSString *contentValue = (!_device.contentValue || [_device.contentValue isEmptyString] ||[_device.contentValue isEqualToString:@"none"]) ? @"-" : _device.contentValue; if ([contentValue isEqualToString:@"-"]) { contentValue = @"1000"; } NSString *unit = _device.unit && ![_device.unit isEmptyString] ? _device.unit : ksEmptyString; unit = [contentValue isEqualToString:@"-"] ? ksEmptyString : unit; if (_node) {//디바이스 상세일 경우, self.lblMeter.text = [NSString stringWithFormat:@"%@ %@", contentValue, unit]; self.lblMeter.font = [UIFont systemFontOfSize:kUIFontSize07]; } CGFloat percent = [contentValue floatValue] / [_node.controlMaxValue floatValue]; [self drawDonutChart:percent]; CGRect sr = self.frame; sr.size = CGSizeMake(200, 200); self.frame = sr; } - (CGSize)sizeForIntrinsic { return CGSizeMake(200, 200); } - (void)drawDonutChart:(CGFloat)percent { UIImage *gradientImage = [UIImage imageNamed:@"dawon_meter_graph_over"]; //draw chart CGRect bgGradient = (CGRect){.origin={10, 10}, .size = gradientImage.size}; _gradientLayer = [CAShapeLayer layer]; _gradientLayer.contents = (id)[gradientImage CGImage]; _gradientLayer.frame = bgGradient; [self.layer addSublayer:_gradientLayer]; CGFloat angle = percent * 360; [self drawMask:85 angle:angle]; //FIXME : constant //x = 10 / 360 //270 + atan2(x) // int value = -_currentAngle < 90 ? (-_currentAngle + 225) : (-_currentAngle - 134); // self.percent = @((value) / 270.0f); } - (void)drawMask:(CGFloat)radius angle:(CGFloat)angle { CGContextRef ctx = UIGraphicsGetCurrentContext(); //Make sure the remove the anti-alias effect from circle CGContextSetAllowsAntialiasing(ctx, true); CGContextSetShouldAntialias(ctx, true); UIColor *color = [UIColor redColor]; //10 : 360 = x : 100 //x : 100 = 10 : 360 //차트 생성 및 애니메이션 CGFloat start = RADIANS(270); CGFloat max = RADIANS(270 + angle); // CGFloat end = 1.0 * RADIANS(269);//percent * RADIANS(180); CGPoint center = CGPointMake(_gradientLayer.frame.size.width/2, _gradientLayer.frame.size.height/2); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:start endAngle:max clockwise:YES]; CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.path = [path CGPath]; maskLayer.strokeColor = [color CGColor]; maskLayer.fillColor = nil; maskLayer.lineWidth = 10; maskLayer.lineJoin = kCALineJoinRound; _gradientLayer.mask = maskLayer; CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; pathAnimation.duration = GRAPH_ANI_DUR; pathAnimation.fromValue = @(0.0f); pathAnimation.toValue = @(1.0f); // [pathAnimation animationDidStop:pathAnimation2 finished:NO]; [maskLayer addAnimation:pathAnimation forKey:@"strokeEnd"]; } @end @implementation CommandClassMeterTotalOfDAWONView - (void)willMoveToSuperview:(UIView *)newSuperview { if (!newSuperview) return; [self initControl]; } - (void)initControl { self.lblMeter.textColor = kUITextColor01; [self setLayoutUI]; } - (void)setLayoutUI { _device = _device ? _device : _node; NSString *contentValue = (!_device.contentValue || [_device.contentValue isEmptyString] ||[_device.contentValue isEqualToString:@"none"]) ? @"-" : _device.contentValue; NSString *unit = _device.unit && ![_device.unit isEmptyString] ? _device.unit : ksEmptyString; unit = [contentValue isEqualToString:@"-"] ? ksEmptyString : unit; if (_node) {//디바이스 상세일 경우, self.lblMeter.text = [NSString stringWithFormat:@"%@ %@", contentValue, unit]; self.lblMeter.font = [UIFont systemFontOfSize:kUIFontSize07]; if ([_node.nodeId isEqualToString:@"3"]) {//누적 전력량 [_imgvIcon setImage:[UIImage imageNamed:@"dawon_command_icon_total_power"]]; } else if ([_node.nodeId isEqualToString:@"4"]) {//CO2 발생량 [_imgvIcon setImage:[UIImage imageNamed:@"dawon_command_icon_co2"]]; } else if ([_node.nodeId isEqualToString:@"5"]) {//예상금액 아이콘 [_imgvIcon setImage:[UIImage imageNamed:@"dawon_command_icon_price"]]; } } CGRect sr = self.frame; sr.size = CGSizeMake(200, 50); self.frame = sr; } - (CGSize)sizeForIntrinsic { return CGSizeMake(200, 50); } @end @interface CommandClassSpeedControlDetailView () { CustomRadioGroup *_rgroup; } @end @implementation CommandClassSpeedControlDetailView - (void)willMoveToSuperview:(UIView *)newSuperview { if (!newSuperview) return; [self initControl]; } - (void)initControl { _rgroup = [[CustomRadioGroup alloc] init]; _rgroup.delegate = self; [self setLayoutUI]; } - (CustomBgRadioButton *)getModeButton:(CmdClsValueModel *)mode { UIImage *nimage = [UIImage imageNamed:@"tp_01_img_control_bg_black"]; UIImage *himage = [UIImage imageNamed:@"tp_01_img_control_bg_active"]; CustomBgRadioButton *rdoMode = [[CustomBgRadioButton alloc] initWithFrame:CGRectMake(0, 0, kfControlDefaultWidth, kfControlDefaultHeight) bgNormalImage:nimage bgHighlightImage:himage rectForCapBg:CGRectMake(40, 0, 40, 0)]; rdoMode.value = mode; rdoMode.titleLabel.font = [UIFont boldSystemFontOfSize:kUIFontSize02]; [rdoMode setTitleColor:kUITextColor01 forState:UIControlStateNormal]; [rdoMode setTitle:mode.cmdclsValueMsg forState:UIControlStateNormal]; rdoMode.titleColorNormal = kUITextColor01; rdoMode.titleColorHighlight = kUITextColor04; return rdoMode; } - (void)setLayoutUI { _modeArray = [_node cmdclsValueList]; NSString *mode; NSUInteger highest = 0, i = 0; for (CmdClsValueModel *tmpCmdclsValue in _modeArray) { if (tmpCmdclsValue.cmdclsValueMsg.length > highest) { highest = tmpCmdclsValue.cmdclsValueMsg.length; mode = tmpCmdclsValue.cmdclsValueMsg; } } CGFloat width = [CommonUtil getSizeFromString:mode font:[UIFont boldSystemFontOfSize:kUIFontSize02] width:FLT_MAX].width + kfSwitchLabelPadding; CGFloat eWidth = width + kfCommandClassSwitchLeftPadding + kfCommandClassSwitchRightPadding; eWidth = eWidth < kfControlDefaultWidth ? kfControlDefaultWidth : eWidth; CustomBgRadioButton *_prevRadio, *_selectedRadio; for (CmdClsValueModel *tmpCmdclsValue in _modeArray) { CustomBgRadioButton *rdoMode = [self getModeButton:tmpCmdclsValue]; [self addSubview:rdoMode]; // rdoMode.checked = i == 0; [_rgroup addRadioButton:rdoMode]; [rdoMode mas_makeConstraints:^(MASConstraintMaker *make) { if (i == 0) { make.top.mas_equalTo(0); } else { make.top.equalTo(_prevRadio.mas_bottom).offset(5); //adjust padding 5px } make.left.equalTo(self); make.width.mas_equalTo(eWidth); make.height.mas_equalTo(kfControlDefaultHeight); }]; if ([_device.contentValue isEqualToString:tmpCmdclsValue.cmdclsValue]) { _selectedRadio = rdoMode; } _prevRadio = rdoMode; i++; } if (!_selectedRadio) { _selectedRadio = _rgroup.rdoBtns.firstObject; } [_rgroup someRadioButtonTouched:_selectedRadio]; CGRect sr = self.frame; sr.size.width = eWidth; sr.size.height = (kfControlDefaultHeight + 5.0f) * _modeArray.count; self.frame = sr; } - (CGSize)sizeForIntrinsic { CGFloat height = (kfControlDefaultHeight + 5.0f) * [_node cmdclsValueList].count; return CGSizeMake(kfControlMaxWidth, height); } - (CGSize)sizeForIntrinsicForItemCount:(NSInteger)count { CGFloat height = (kfControlDefaultHeight + 5.0f) * count; return CGSizeMake(kfControlMaxWidth, height); } - (void)didSomeRadioButtonTouched:(id)sender { if (_isConditionMode) //룰, 씬일 경우, 제어를 하지 않음 return; CustomBgRadioButton *rdoMode = (CustomBgRadioButton *)sender; CmdClsValueModel *cmdclsValue = rdoMode.value; [self updateThingsViewContoller]; NSString *requestValue = cmdclsValue.cmdclsValue; [CommandClassControlView requestNodeCommand:self.parameterForNodeCommand requestValue:requestValue completionHandler:nil failureHandler:nil]; } @end