FreeRDP
ScreenSelectionController.m
1 /*
2  controller for screen settings selection
3 
4  Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
5 
6  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
7  If a copy of the MPL was not distributed with this file, You can obtain one at
8  http://mozilla.org/MPL/2.0/.
9  */
10 
11 #import "ScreenSelectionController.h"
12 #import "Utils.h"
13 #import "OrderedDictionary.h"
14 #import "ConnectionParams.h"
15 
16 @interface ScreenSelectionController (Private)
17 - (NSString *)keyPathForKey:(NSString *)key;
18 @end
19 
20 @implementation ScreenSelectionController
21 
22 - (id)initWithConnectionParams:(ConnectionParams *)params
23 {
24  return [self initWithConnectionParams:params keyPath:nil];
25 }
26 
27 - (id)initWithConnectionParams:(ConnectionParams *)params keyPath:(NSString *)keyPath
28 {
29  self = [super initWithStyle:UITableViewStyleGrouped];
30  if (self)
31  {
32  _params = [params retain];
33  _keyPath = (keyPath != nil ? [keyPath retain] : nil);
34 
35  _color_options = (OrderedDictionary *)[SelectionForColorSetting() retain];
36  _resolution_modes = [ResolutionModes() retain];
37 
38  // init current selections
39  NSUInteger idx = [_color_options
40  indexForValue:[NSNumber
41  numberWithInt:[_params
42  intForKeyPath:[self keyPathForKey:@"colors"]]]];
43  _selection_color = (idx != NSNotFound) ? idx : 0;
44 
45  idx = [_resolution_modes
46  indexOfObject:ScreenResolutionDescription(
47  [_params
48  intForKeyPath:[self keyPathForKey:@"screen_resolution_type"]],
49  [_params intForKeyPath:[self keyPathForKey:@"width"]],
50  [_params intForKeyPath:[self keyPathForKey:@"height"]])];
51  _selection_resolution = (idx != NSNotFound) ? idx : 0;
52  }
53  return self;
54 }
55 
56 - (void)dealloc
57 {
58  [super dealloc];
59  [_params autorelease];
60  [_keyPath autorelease];
61  [_color_options autorelease];
62  [_resolution_modes autorelease];
63 }
64 
65 - (NSString *)keyPathForKey:(NSString *)key
66 {
67  if (_keyPath)
68  return [_keyPath stringByAppendingFormat:@".%@", key];
69  return key;
70 }
71 
72 #pragma mark - View lifecycle
73 
74 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
75 {
76  // Return YES for supported orientations
77  return YES;
78 }
79 
80 #pragma mark - Table view data source
81 
82 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
83 {
84  return 2;
85 }
86 
87 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
88 {
89  // Return the number of rows in the section.
90  if (section == 0)
91  return [_color_options count];
92  return [_resolution_modes count] + 2; // +2 for custom width/height input fields
93 }
94 
95 - (UITableViewCell *)tableView:(UITableView *)tableView
96  cellForRowAtIndexPath:(NSIndexPath *)indexPath
97 {
98  UITableViewCell *cell = nil;
99  switch ([indexPath section])
100  {
101  case 0:
102  cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];
103  [[cell textLabel] setText:[_color_options keyAtIndex:[indexPath row]]];
104  break;
105 
106  case 1:
107  if ([indexPath row] < [_resolution_modes count])
108  {
109  cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];
110  [[cell textLabel] setText:[_resolution_modes objectAtIndex:[indexPath row]]];
111  }
112  else
113  cell = [self tableViewCellFromIdentifier:TableCellIdentifierText];
114  break;
115 
116  default:
117  break;
118  }
119 
120  if ([indexPath section] == 1)
121  {
122  BOOL enabled = ([_params intForKeyPath:[self keyPathForKey:@"screen_resolution_type"]] ==
123  TSXScreenOptionCustom);
124  if ([indexPath row] == [_resolution_modes count])
125  {
126  int value = [_params intForKeyPath:[self keyPathForKey:@"width"]];
127  EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
128  [[textCell label] setText:NSLocalizedString(@"Width", @"Custom Screen Width")];
129  [[textCell textfield] setText:[NSString stringWithFormat:@"%d", value ? value : 800]];
130  [[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
131  [[textCell label] setEnabled:enabled];
132  [[textCell textfield] setEnabled:enabled];
133  [[textCell textfield] setTag:1];
134  }
135  else if ([indexPath row] == ([_resolution_modes count] + 1))
136  {
137  int value = [_params intForKeyPath:[self keyPathForKey:@"height"]];
138  EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
139  [[textCell label] setText:NSLocalizedString(@"Height", @"Custom Screen Height")];
140  [[textCell textfield] setText:[NSString stringWithFormat:@"%d", value ? value : 600]];
141  [[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
142  [[textCell label] setEnabled:enabled];
143  [[textCell textfield] setEnabled:enabled];
144  [[textCell textfield] setTag:2];
145  }
146  }
147 
148  // set default checkmark
149  if ([indexPath row] == ([indexPath section] == 0 ? _selection_color : _selection_resolution))
150  [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
151  else
152  [cell setAccessoryType:UITableViewCellAccessoryNone];
153 
154  return cell;
155 }
156 
157 #pragma mark - Table view delegate
158 
159 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
160 {
161  // custom widht/height cells are not selectable
162  if ([indexPath section] == 1 && [indexPath row] >= [_resolution_modes count])
163  return;
164 
165  // has selection change?
166  int cur_selection = ([indexPath section] == 0 ? _selection_color : _selection_resolution);
167  if ([indexPath row] != cur_selection)
168  {
169  [tableView deselectRowAtIndexPath:indexPath animated:NO];
170 
171  NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:cur_selection
172  inSection:[indexPath section]];
173 
174  // clear old checkmark
175  UITableViewCell *old_sel_cell = [tableView cellForRowAtIndexPath:oldIndexPath];
176  old_sel_cell.accessoryType = UITableViewCellAccessoryNone;
177 
178  // set new checkmark
179  UITableViewCell *new_sel_cell = [tableView cellForRowAtIndexPath:indexPath];
180  new_sel_cell.accessoryType = UITableViewCellAccessoryCheckmark;
181 
182  if ([indexPath section] == 0)
183  {
184  // get value from color dictionary
185  int sel_value =
186  [[_color_options valueForKey:[_color_options keyAtIndex:[indexPath row]]] intValue];
187 
188  // update selection index and params value
189  [_params setInt:sel_value forKeyPath:[self keyPathForKey:@"colors"]];
190  _selection_color = [indexPath row];
191  }
192  else
193  {
194  // update selection index and params value
195  int width, height;
196  TSXScreenOptions mode;
197  ScanScreenResolution([_resolution_modes objectAtIndex:[indexPath row]], &width, &height,
198  &mode);
199  [_params setInt:mode forKeyPath:[self keyPathForKey:@"screen_resolution_type"]];
200  if (mode != TSXScreenOptionCustom)
201  {
202  [_params setInt:width forKeyPath:[self keyPathForKey:@"width"]];
203  [_params setInt:height forKeyPath:[self keyPathForKey:@"height"]];
204  }
205  _selection_resolution = [indexPath row];
206 
207  // refresh width/height edit fields if custom selection changed
208  NSArray *indexPaths = [NSArray
209  arrayWithObjects:[NSIndexPath indexPathForRow:[_resolution_modes count]
210  inSection:1],
211  [NSIndexPath indexPathForRow:([_resolution_modes count] + 1)
212  inSection:1],
213  nil];
214  [[self tableView] reloadRowsAtIndexPaths:indexPaths
215  withRowAnimation:UITableViewRowAnimationNone];
216  }
217  }
218 }
219 
220 #pragma mark -
221 #pragma mark Text Field delegate
222 
223 - (BOOL)textFieldShouldReturn:(UITextField *)textField
224 {
225  [textField resignFirstResponder];
226  return NO;
227 }
228 
229 - (BOOL)textFieldShouldEndEditing:(UITextField *)textField
230 {
231 
232  switch ([textField tag])
233  {
234  // update resolution settings (and check for invalid input)
235  case 1:
236  if ([[textField text] intValue] < 640)
237  [textField setText:@"640"];
238  [_params setInt:[[textField text] intValue] forKeyPath:[self keyPathForKey:@"width"]];
239  break;
240 
241  case 2:
242  if ([[textField text] intValue] < 480)
243  [textField setText:@"480"];
244  [_params setInt:[[textField text] intValue] forKeyPath:[self keyPathForKey:@"height"]];
245  break;
246 
247  default:
248  break;
249  }
250  return YES;
251 }
252 
253 @end