Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / darwin / CHIPTool / CHIPTool / View Controllers / OnOffCluster / OnOffViewController.m
1 /**
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 #import "OnOffViewController.h"
19 #import "CHIPUIViewUtils.h"
20 #import "DefaultsUtils.h"
21 #import "DeviceSelector.h"
22 #import <CHIP/CHIP.h>
23
24 NSString * const kCHIPNumLightOnOffCluster = @"OnOffViewController_NumLights";
25
26 @interface OnOffViewController ()
27 @property (nonatomic, strong) UITextField * numLightsTextField;
28
29 @property (nonatomic, strong) UILabel * resultLabel;
30 @property (nonatomic, strong) UILabel * titleLabel;
31 @property (nonatomic, strong) UIStackView * stackView;
32
33 @property (nonatomic, strong) DeviceSelector * deviceSelector;
34
35 @end
36
37 @implementation OnOffViewController {
38     dispatch_queue_t _callbackQueue;
39     NSArray * _numLightsOptions;
40 }
41
42 // MARK: UIViewController methods
43
44 - (void)viewDidLoad
45 {
46     [super viewDidLoad];
47
48     UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
49     [self.view addGestureRecognizer:tap];
50
51     [self setupUIElements];
52 }
53
54 - (void)dismissKeyboard
55 {
56     [_numLightsTextField resignFirstResponder];
57     [_deviceSelector resignFirstResponder];
58 }
59
60 // MARK: UI Setup
61
62 - (void)setupUIElements
63 {
64     self.view.backgroundColor = UIColor.whiteColor;
65
66     // Title
67     _titleLabel = [CHIPUIViewUtils addTitle:@"On Off Cluster" toView:self.view];
68     [self setupStackView];
69 }
70
71 - (void)setupStackView
72 {
73     // stack view
74     UIStackView * stackView = [UIStackView new];
75     stackView.axis = UILayoutConstraintAxisVertical;
76     stackView.distribution = UIStackViewDistributionEqualSpacing;
77     stackView.alignment = UIStackViewAlignmentLeading;
78     stackView.spacing = 30;
79     [_stackView removeFromSuperview];
80     _stackView = stackView;
81     [self.view addSubview:stackView];
82
83     stackView.translatesAutoresizingMaskIntoConstraints = false;
84     [stackView.topAnchor constraintEqualToAnchor:_titleLabel.bottomAnchor constant:30].active = YES;
85     [stackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:30].active = YES;
86     [stackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-30].active = YES;
87
88     // Device List and picker
89     _deviceSelector = [DeviceSelector new];
90
91     UILabel * deviceIDLabel = [UILabel new];
92     deviceIDLabel.text = @"Device ID:";
93     UIView * deviceIDView = [CHIPUIViewUtils viewWithLabel:deviceIDLabel textField:_deviceSelector];
94     [stackView addArrangedSubview:deviceIDView];
95
96     deviceIDView.translatesAutoresizingMaskIntoConstraints = false;
97     [deviceIDView.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = true;
98
99     // Num lights to show
100     UILabel * numLightsLabel = [UILabel new];
101     numLightsLabel.text = @"# of light endpoints:";
102     _numLightsTextField = [UITextField new];
103     _numLightsOptions = @[ @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10" ];
104     _numLightsTextField.text
105         = CHIPGetDomainValueForKey(kCHIPToolDefaultsDomain, kCHIPNumLightOnOffCluster) ?: [_numLightsOptions objectAtIndex:0];
106     UIPickerView * numLightsPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, 0, 0)];
107     _numLightsTextField.inputView = numLightsPicker;
108     [numLightsPicker setDataSource:self];
109     [numLightsPicker setDelegate:self];
110     _numLightsTextField.delegate = self;
111     UIView * numLightsView = [CHIPUIViewUtils viewWithLabel:numLightsLabel textField:_numLightsTextField];
112     numLightsLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightSemibold];
113
114     UIToolbar * keyboardDoneButtonView = [[UIToolbar alloc] init];
115     [keyboardDoneButtonView sizeToFit];
116     UIBarButtonItem * doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
117                                                                     style:UIBarButtonItemStylePlain
118                                                                    target:self
119                                                                    action:@selector(pickerDoneClicked:)];
120     UIBarButtonItem * flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
121                                                                                target:self
122                                                                                action:nil];
123     [keyboardDoneButtonView setItems:[NSArray arrayWithObjects:flexible, doneButton, nil]];
124     _numLightsTextField.inputAccessoryView = keyboardDoneButtonView;
125
126     [stackView addArrangedSubview:numLightsView];
127     numLightsView.translatesAutoresizingMaskIntoConstraints = false;
128     [numLightsView.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = true;
129
130     // Create buttons
131     [self addButtons:[self numLightClustersToShow] toStackView:stackView];
132
133     // Result message
134     _resultLabel = [UILabel new];
135     _resultLabel.hidden = YES;
136     _resultLabel.font = [UIFont systemFontOfSize:17];
137     _resultLabel.textColor = UIColor.systemBlueColor;
138     _resultLabel.lineBreakMode = NSLineBreakByWordWrapping;
139     _resultLabel.numberOfLines = 0;
140     [stackView addArrangedSubview:_resultLabel];
141
142     _resultLabel.translatesAutoresizingMaskIntoConstraints = false;
143     [_resultLabel.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = YES;
144     _resultLabel.adjustsFontSizeToFitWidth = YES;
145 }
146
147 - (void)addButtons:(NSInteger)numButtons toStackView:(UIStackView *)stackView
148 {
149     for (int i = 1; i <= numButtons; i++) {
150         // Create buttons
151         UILabel * labelLight = [UILabel new];
152         labelLight.text = [NSString stringWithFormat:@"Light (endpoint %@): ", @(i)];
153         UIButton * onButton = [UIButton new];
154         onButton.tag = i;
155         [onButton setTitle:@"On" forState:UIControlStateNormal];
156         [onButton addTarget:self action:@selector(onButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
157         UIButton * offButton = [UIButton new];
158         offButton.tag = i;
159         [offButton setTitle:@"Off" forState:UIControlStateNormal];
160         [offButton addTarget:self action:@selector(offButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
161         UIButton * toggleButton = [UIButton new];
162         toggleButton.tag = i;
163         [toggleButton setTitle:@"Toggle" forState:UIControlStateNormal];
164         [toggleButton addTarget:self action:@selector(toggleButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
165
166         UIStackView * stackViewButtons = [CHIPUIViewUtils stackViewWithLabel:labelLight
167                                                                      buttons:@[ onButton, offButton, toggleButton ]];
168         stackViewButtons.axis = UILayoutConstraintAxisHorizontal;
169         stackViewButtons.distribution = UIStackViewDistributionEqualSpacing;
170         stackViewButtons.alignment = UIStackViewAlignmentLeading;
171         stackViewButtons.spacing = 10;
172         [stackView addArrangedSubview:stackViewButtons];
173     }
174 }
175
176 - (void)updateResult:(NSString *)result
177 {
178     _resultLabel.hidden = NO;
179     _resultLabel.text = result;
180 }
181
182 // MARK: UIPickerView
183
184 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
185 {
186     NSLog(@"%@", [_numLightsOptions objectAtIndex:row]);
187     _numLightsTextField.text = [NSString stringWithFormat:@"%@", [_numLightsOptions objectAtIndex:row]];
188 }
189
190 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
191 {
192     return [_numLightsOptions count];
193 }
194
195 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
196 {
197     return 1;
198 }
199
200 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
201 {
202     return [_numLightsOptions objectAtIndex:row];
203 }
204
205 // tell the picker the width of each row for a given component
206 - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
207 {
208     return 200;
209 }
210
211 - (IBAction)pickerDoneClicked:(id)sender
212 {
213     CHIPSetDomainValueForKey(kCHIPToolDefaultsDomain, kCHIPNumLightOnOffCluster, _numLightsTextField.text);
214     [_numLightsTextField resignFirstResponder];
215     [self setupStackView];
216 }
217
218 // MARK: Cluster Setup
219
220 - (int)numLightClustersToShow
221 {
222     NSString * numClusters = CHIPGetDomainValueForKey(kCHIPToolDefaultsDomain, kCHIPNumLightOnOffCluster);
223     int numberOfLights = 1;
224
225     if (numClusters) {
226         numberOfLights = [numClusters intValue];
227     }
228     return numberOfLights;
229 }
230
231 // MARK: UIButton actions
232
233 - (IBAction)onButtonTapped:(id)sender
234 {
235     UIButton * button = (UIButton *) sender;
236     NSInteger endpoint = button.tag;
237     [self updateResult:[NSString stringWithFormat:@"On command sent on endpoint %@", @(endpoint)]];
238
239     [_deviceSelector forSelectedDevices:^(uint64_t deviceId) {
240         CHIPDevice * chipDevice = CHIPGetPairedDeviceWithID(deviceId);
241         if (chipDevice != nil) {
242             CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()];
243             [onOff on:^(NSError * error, NSDictionary * values) {
244                 NSString * resultString
245                     = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] : @"On command success";
246                 [self updateResult:resultString];
247             }];
248         } else {
249             [self updateResult:[NSString stringWithFormat:@"Device not found"]];
250         }
251     }];
252 }
253
254 - (IBAction)offButtonTapped:(id)sender
255 {
256     UIButton * button = (UIButton *) sender;
257     NSInteger endpoint = button.tag;
258     [self updateResult:[NSString stringWithFormat:@"Off command sent on endpoint %@", @(endpoint)]];
259
260     [_deviceSelector forSelectedDevices:^(uint64_t deviceId) {
261         CHIPDevice * chipDevice = CHIPGetPairedDeviceWithID(deviceId);
262         if (chipDevice != nil) {
263             CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()];
264             [onOff off:^(NSError * error, NSDictionary * values) {
265                 NSString * resultString = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]
266                                                          : @"Off command success";
267                 [self updateResult:resultString];
268             }];
269         } else {
270             [self updateResult:[NSString stringWithFormat:@"Device not found"]];
271         }
272     }];
273 }
274
275 - (IBAction)toggleButtonTapped:(id)sender
276 {
277     UIButton * button = (UIButton *) sender;
278     NSInteger endpoint = button.tag;
279     [self updateResult:[NSString stringWithFormat:@"Toggle command sent on endpoint %@", @(endpoint)]];
280
281     [_deviceSelector forSelectedDevices:^(uint64_t deviceId) {
282         CHIPDevice * chipDevice = CHIPGetPairedDeviceWithID(deviceId);
283         if (chipDevice != nil) {
284             CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()];
285             [onOff toggle:^(NSError * error, NSDictionary * values) {
286                 NSString * resultString = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]
287                                                          : @"Toggle command success";
288                 [self updateResult:resultString];
289             }];
290         } else {
291             [self updateResult:[NSString stringWithFormat:@"Device not found"]];
292         }
293     }];
294 }
295
296 @end