Blame client/iOS/Views/AdvancedKeyboardView.m

Packit Service fa4841
/*
Packit Service fa4841
 Advanced keyboard view interface
Packit Service b1ea74
Packit Service fa4841
 Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
Packit Service fa4841
Packit Service b1ea74
 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
Packit Service b1ea74
 If a copy of the MPL was not distributed with this file, You can obtain one at
Packit Service b1ea74
 http://mozilla.org/MPL/2.0/.
Packit Service b1ea74
 */
Packit Service bb5c11
Packit Service fa4841
#import "AdvancedKeyboardView.h"
Packit Service fa4841
#include <freerdp/locale/keyboard.h>
Packit Service fa4841
Packit Service fa4841
// helper struct to define button layouts/settings
Packit Service fa4841
struct ButtonItem
Packit Service fa4841
{
Packit Service b1ea74
	NSString *title;
Packit Service b1ea74
	int tag;
Packit Service fa4841
};
Packit Service fa4841
Packit Service fa4841
@interface AdvancedKeyboardView (Private)
Packit Service b1ea74
- (UIView *)keyboardViewForItems:(struct ButtonItem *)items columns:(int)columns rows:(int)rows;
Packit Service fa4841
@end
Packit Service fa4841
Packit Service fa4841
@implementation AdvancedKeyboardView
Packit Service fa4841
Packit Service fa4841
@synthesize delegate = _delegate;
Packit Service fa4841
Packit Service fa4841
// defines for the different views
Packit Service b1ea74
#define KEY_SHOW_FUNCVIEW 0x1000
Packit Service b1ea74
#define KEY_SHOW_CURSORVIEW 0x1001
Packit Service b1ea74
#define KEY_SHOW_NUMPADVIEW 0x1002
Packit Service b1ea74
#define KEY_SKIP 0x8000
Packit Service b1ea74
#define KEY_MERGE_COLUMN 0x8001
Packit Service b1ea74
Packit Service b1ea74
#define KEYCODE_UNICODE 0x80000000
Packit Service b1ea74
Packit Service b1ea74
struct ButtonItem functionKeysItems[24] = { { @"F1", VK_F1 },
Packit Service b1ea74
	                                        { @"F2", VK_F2 },
Packit Service b1ea74
	                                        { @"F3", VK_F3 },
Packit Service b1ea74
	                                        { @"F4", VK_F4 },
Packit Service b1ea74
	                                        { @"F5", VK_F5 },
Packit Service b1ea74
	                                        { @"F6", VK_F6 },
Packit Service b1ea74
	                                        { @"F7", VK_F7 },
Packit Service b1ea74
	                                        { @"F8", VK_F8 },
Packit Service b1ea74
	                                        { @"F9", VK_F9 },
Packit Service b1ea74
	                                        { @"F10", VK_F10 },
Packit Service b1ea74
	                                        { @"F11", VK_F11 },
Packit Service b1ea74
	                                        { @"F12", VK_F12 },
Packit Service b1ea74
Packit Service b1ea74
	                                        { @"img:icon_key_arrows", KEY_SHOW_CURSORVIEW },
Packit Service b1ea74
	                                        { @"Tab", VK_TAB },
Packit Service b1ea74
	                                        { @"Ins", VK_INSERT | KBDEXT },
Packit Service b1ea74
	                                        { @"Home", VK_HOME | KBDEXT },
Packit Service b1ea74
	                                        { @"PgUp", VK_PRIOR | KBDEXT },
Packit Service b1ea74
	                                        { @"img:icon_key_win", VK_LWIN | KBDEXT },
Packit Service b1ea74
Packit Service b1ea74
	                                        { @"123", KEY_SHOW_NUMPADVIEW },
Packit Service b1ea74
	                                        { @"Print", VK_PRINT },
Packit Service b1ea74
	                                        { @"Del", VK_DELETE | KBDEXT },
Packit Service b1ea74
	                                        { @"End", VK_END | KBDEXT },
Packit Service b1ea74
	                                        { @"PgDn", VK_NEXT | KBDEXT },
Packit Service b1ea74
	                                        { @"img:icon_key_menu", VK_APPS | KBDEXT } };
Packit Service b1ea74
Packit Service b1ea74
struct ButtonItem numPadKeysItems[24] = { { @"(", KEYCODE_UNICODE | 40 },
Packit Service b1ea74
	                                      { @")", KEYCODE_UNICODE | 41 },
Packit Service b1ea74
	                                      { @"7", VK_NUMPAD7 },
Packit Service b1ea74
	                                      { @"8", VK_NUMPAD8 },
Packit Service b1ea74
	                                      { @"9", VK_NUMPAD9 },
Packit Service b1ea74
	                                      { @"-", VK_SUBTRACT },
Packit Service b1ea74
Packit Service b1ea74
	                                      { @"/", VK_DIVIDE | KBDEXT },
Packit Service b1ea74
	                                      { @"*", VK_MULTIPLY },
Packit Service b1ea74
	                                      { @"4", VK_NUMPAD4 },
Packit Service b1ea74
	                                      { @"5", VK_NUMPAD5 },
Packit Service b1ea74
	                                      { @"6", VK_NUMPAD6 },
Packit Service b1ea74
	                                      { @"+", VK_ADD },
Packit Service b1ea74
Packit Service b1ea74
	                                      { @"Fn", KEY_SHOW_FUNCVIEW },
Packit Service b1ea74
	                                      { @"Num", VK_NUMLOCK },
Packit Service b1ea74
	                                      { @"1", VK_NUMPAD1 },
Packit Service b1ea74
	                                      { @"2", VK_NUMPAD2 },
Packit Service b1ea74
	                                      { @"3", VK_NUMPAD3 },
Packit Service b1ea74
	                                      { @"img:icon_key_backspace", VK_BACK },
Packit Service b1ea74
Packit Service b1ea74
	                                      { @"img:icon_key_arrows", KEY_SHOW_CURSORVIEW },
Packit Service b1ea74
	                                      { @"=", KEYCODE_UNICODE | 61 },
Packit Service b1ea74
	                                      { @"", KEY_MERGE_COLUMN },
Packit Service b1ea74
	                                      { @"0", VK_NUMPAD0 },
Packit Service b1ea74
	                                      { @".", VK_DECIMAL },
Packit Service b1ea74
	                                      { @"img:icon_key_return", VK_RETURN | KBDEXT } };
Packit Service b1ea74
Packit Service b1ea74
struct ButtonItem cursorKeysItems[24] = { { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"img:icon_key_arrow_up", VK_UP | KBDEXT },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
Packit Service b1ea74
	                                      { @"Fn", KEY_SHOW_FUNCVIEW },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"img:icon_key_arrow_left", VK_LEFT | KBDEXT },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"img:icon_key_arrow_right", VK_RIGHT | KBDEXT },
Packit Service b1ea74
	                                      { @"img:icon_key_backspace", VK_BACK },
Packit Service b1ea74
Packit Service b1ea74
	                                      { @"123", KEY_SHOW_NUMPADVIEW },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"img:icon_key_arrow_down", VK_DOWN | KBDEXT },
Packit Service b1ea74
	                                      { @"", KEY_SKIP },
Packit Service b1ea74
	                                      { @"img:icon_key_return", VK_RETURN | KBDEXT } };
Packit Service fa4841
Packit Service fa4841
- (void)initFunctionKeysView
Packit Service fa4841
{
Packit Service b1ea74
	_function_keys_view = [[self keyboardViewForItems:functionKeysItems columns:6 rows:4] retain];
Packit Service b1ea74
	[self addSubview:_function_keys_view];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (void)initNumPadKeysView
Packit Service fa4841
{
Packit Service b1ea74
	_numpad_keys_view = [[self keyboardViewForItems:numPadKeysItems columns:6 rows:4] retain];
Packit Service b1ea74
	[self addSubview:_numpad_keys_view];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (void)initCursorKeysView
Packit Service fa4841
{
Packit Service b1ea74
	_cursor_keys_view = [[self keyboardViewForItems:cursorKeysItems columns:6 rows:4] retain];
Packit Service b1ea74
	[self addSubview:_cursor_keys_view];
Packit Service fa4841
}
Packit Service fa4841
Packit Service b1ea74
- (id)initWithFrame:(CGRect)frame delegate:(NSObject<AdvancedKeyboardDelegate> *)delegate
Packit Service fa4841
{
Packit Service b1ea74
	self = [super initWithFrame:frame];
Packit Service b1ea74
	if (self)
Packit Service b1ea74
	{
Packit Service b1ea74
		_delegate = delegate;
Packit Service b1ea74
Packit Service b1ea74
		self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
Packit Service b1ea74
		self.backgroundColor = [UIColor blackColor];
Packit Service b1ea74
		// Initialization code
Packit Service b1ea74
Packit Service b1ea74
		[self initCursorKeysView];
Packit Service b1ea74
		[self initNumPadKeysView];
Packit Service b1ea74
		[self initFunctionKeysView];
Packit Service b1ea74
Packit Service b1ea74
		// set function keys view to the initial view and hide others
Packit Service b1ea74
		_cur_view = _function_keys_view;
Packit Service b1ea74
		[_numpad_keys_view setHidden:YES];
Packit Service b1ea74
		[_cursor_keys_view setHidden:YES];
Packit Service b1ea74
	}
Packit Service b1ea74
	return self;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
/*
Packit Service fa4841
// Only override drawRect: if you perform custom drawing.
Packit Service fa4841
// An empty implementation adversely affects performance during animation.
Packit Service fa4841
- (void)drawRect:(CGRect)rect
Packit Service fa4841
{
Packit Service fa4841
    // Drawing code
Packit Service fa4841
}
Packit Service fa4841
*/
Packit Service fa4841
Packit Service b1ea74
- (void)drawRect:(CGRect)rect
Packit Service fa4841
{
Packit Service b1ea74
	// draw a nice background gradient
Packit Service b1ea74
	CGContextRef currentContext = UIGraphicsGetCurrentContext();
Packit Service b1ea74
Packit Service b1ea74
	CGGradientRef glossGradient;
Packit Service b1ea74
	CGColorSpaceRef rgbColorspace;
Packit Service b1ea74
	size_t num_locations = 2;
Packit Service b1ea74
	CGFloat locations[2] = { 0.0, 1.0 };
Packit Service b1ea74
	CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35,   // Start color
Packit Service b1ea74
		                      1.0, 1.0, 1.0, 0.06 }; // End color
Packit Service b1ea74
Packit Service b1ea74
	rgbColorspace = CGColorSpaceCreateDeviceRGB();
Packit Service b1ea74
	glossGradient =
Packit Service b1ea74
	    CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
Packit Service b1ea74
Packit Service b1ea74
	CGRect currentBounds = self.bounds;
Packit Service b1ea74
	CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
Packit Service b1ea74
	CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), currentBounds.size.height);
Packit Service b1ea74
	CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
Packit Service b1ea74
Packit Service b1ea74
	CGGradientRelease(glossGradient);
Packit Service b1ea74
	CGColorSpaceRelease(rgbColorspace);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (void)dealloc
Packit Service fa4841
{
Packit Service b1ea74
	[_function_keys_view autorelease];
Packit Service b1ea74
	[_numpad_keys_view autorelease];
Packit Service b1ea74
	[_cursor_keys_view autorelease];
Packit Service b1ea74
	[super dealloc];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
#pragma mark -
Packit Service fa4841
#pragma mark button events
Packit Service fa4841
Packit Service b1ea74
- (IBAction)keyPressed:(id)sender
Packit Service fa4841
{
Packit Service b1ea74
	UIButton *btn = (UIButton *)sender;
Packit Service b1ea74
	switch ([btn tag])
Packit Service b1ea74
	{
Packit Service b1ea74
		case KEY_SHOW_CURSORVIEW:
Packit Service b1ea74
			// switch to cursor view
Packit Service b1ea74
			[_cur_view setHidden:YES];
Packit Service b1ea74
			[_cursor_keys_view setHidden:NO];
Packit Service b1ea74
			_cur_view = _cursor_keys_view;
Packit Service b1ea74
			break;
Packit Service b1ea74
Packit Service b1ea74
		case KEY_SHOW_NUMPADVIEW:
Packit Service b1ea74
			// switch to numpad view
Packit Service b1ea74
			[_cur_view setHidden:YES];
Packit Service b1ea74
			[_numpad_keys_view setHidden:NO];
Packit Service b1ea74
			_cur_view = _numpad_keys_view;
Packit Service b1ea74
			break;
Packit Service b1ea74
Packit Service b1ea74
		case KEY_SHOW_FUNCVIEW:
Packit Service b1ea74
			// switch to function keys view
Packit Service b1ea74
			[_cur_view setHidden:YES];
Packit Service b1ea74
			[_function_keys_view setHidden:NO];
Packit Service b1ea74
			_cur_view = _function_keys_view;
Packit Service b1ea74
			break;
Packit Service b1ea74
Packit Service b1ea74
		default:
Packit Service b1ea74
			if ([btn tag] & KEYCODE_UNICODE)
Packit Service b1ea74
			{
Packit Service b1ea74
				if ([[self delegate] respondsToSelector:@selector(advancedKeyPressedUnicode:)])
Packit Service b1ea74
					[[self delegate] advancedKeyPressedUnicode:([btn tag] & ~KEYCODE_UNICODE)];
Packit Service b1ea74
			}
Packit Service b1ea74
			else
Packit Service b1ea74
			{
Packit Service b1ea74
				if ([[self delegate] respondsToSelector:@selector(advancedKeyPressedVKey:)])
Packit Service b1ea74
					[[self delegate] advancedKeyPressedVKey:[btn tag]];
Packit Service b1ea74
			}
Packit Service b1ea74
			break;
Packit Service b1ea74
	}
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
@end
Packit Service fa4841
Packit Service fa4841
#pragma mark -
Packit Service fa4841
@implementation AdvancedKeyboardView (Private)
Packit Service b1ea74
Packit Service b1ea74
- (UIView *)keyboardViewForItems:(struct ButtonItem *)items columns:(int)columns rows:(int)rows
Packit Service fa4841
{
Packit Service b1ea74
	UIView *result_view = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
Packit Service b1ea74
	result_view.autoresizingMask =
Packit Service b1ea74
	    UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
Packit Service b1ea74
Packit Service b1ea74
	// calculate maximum button size
Packit Service b1ea74
	int max_btn_width = result_view.bounds.size.width / ((columns * 2) + 1);
Packit Service b1ea74
	int max_btn_height = result_view.bounds.size.height / ((rows * 2) + 1);
Packit Service b1ea74
Packit Service b1ea74
	// ensure minimum button size
Packit Service b1ea74
	CGSize btn_size = CGSizeMake(45, 30);
Packit Service b1ea74
	if (btn_size.width < max_btn_width)
Packit Service b1ea74
		btn_size.width = max_btn_width;
Packit Service b1ea74
	if (btn_size.height < max_btn_height)
Packit Service b1ea74
		btn_size.height = max_btn_height;
Packit Service b1ea74
Packit Service b1ea74
	// calc distance width and height between buttons
Packit Service b1ea74
	int dist_width = (result_view.bounds.size.width - (columns * btn_size.width)) / (columns + 1);
Packit Service b1ea74
	int dist_height = (result_view.bounds.size.height - (rows * btn_size.height)) / (rows + 1);
Packit Service b1ea74
Packit Service b1ea74
	UIImage *btn_background_img = [UIImage
Packit Service b1ea74
	    imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"keyboard_button_background"
Packit Service b1ea74
	                                                            ofType:@"png"]];
Packit Service b1ea74
	for (int j = 0; j < rows; j++)
Packit Service b1ea74
	{
Packit Service b1ea74
		for (int i = 0; i < columns; i++)
Packit Service b1ea74
		{
Packit Service b1ea74
			struct ButtonItem *curItem = &items[j * columns + i];
Packit Service b1ea74
Packit Service b1ea74
			// skip this spot?
Packit Service b1ea74
			if (curItem->tag == KEY_SKIP)
Packit Service b1ea74
				continue;
Packit Service b1ea74
Packit Service b1ea74
			// create button, set autoresizing mask and add action handler
Packit Service b1ea74
			UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
Packit Service b1ea74
			[btn setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin |
Packit Service b1ea74
			                          UIViewAutoresizingFlexibleRightMargin |
Packit Service b1ea74
			                          UIViewAutoresizingFlexibleTopMargin |
Packit Service b1ea74
			                          UIViewAutoresizingFlexibleBottomMargin |
Packit Service b1ea74
			                          UIViewAutoresizingFlexibleWidth |
Packit Service b1ea74
			                          UIViewAutoresizingFlexibleHeight)];
Packit Service b1ea74
			[btn addTarget:self
Packit Service b1ea74
			              action:@selector(keyPressed:)
Packit Service b1ea74
			    forControlEvents:UIControlEventTouchUpInside];
Packit Service b1ea74
Packit Service b1ea74
			// if merge is specified we merge this button's position with the next one
Packit Service b1ea74
			if (curItem->tag == KEY_MERGE_COLUMN)
Packit Service b1ea74
			{
Packit Service b1ea74
				// calc merged frame
Packit Service b1ea74
				[btn setFrame:CGRectMake(dist_width + (i * dist_width) + (i * btn_size.width),
Packit Service b1ea74
				                         dist_height + (j * dist_height) + (j * btn_size.height),
Packit Service b1ea74
				                         btn_size.width * 2 + dist_width, btn_size.height)];
Packit Service b1ea74
Packit Service b1ea74
				// proceed to the next column item
Packit Service b1ea74
				i++;
Packit Service b1ea74
				curItem = &items[j * columns + i];
Packit Service b1ea74
			}
Packit Service b1ea74
			else
Packit Service b1ea74
			{
Packit Service b1ea74
				[btn setFrame:CGRectMake(dist_width + (i * dist_width) + (i * btn_size.width),
Packit Service b1ea74
				                         dist_height + (j * dist_height) + (j * btn_size.height),
Packit Service b1ea74
				                         btn_size.width, btn_size.height)];
Packit Service b1ea74
			}
Packit Service b1ea74
Packit Service b1ea74
			// set button text or image parameters
Packit Service b1ea74
			if ([curItem->title hasPrefix:@"img:"] == YES)
Packit Service b1ea74
			{
Packit Service b1ea74
				UIImage *btn_image =
Packit Service b1ea74
				    [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
Packit Service b1ea74
				                                         pathForResource:[curItem->title
Packit Service b1ea74
				                                                             substringFromIndex:4]
Packit Service b1ea74
				                                                  ofType:@"png"]];
Packit Service b1ea74
				[btn setImage:btn_image forState:UIControlStateNormal];
Packit Service b1ea74
			}
Packit Service b1ea74
			else
Packit Service b1ea74
			{
Packit Service b1ea74
				[btn setTitle:curItem->title forState:UIControlStateNormal];
Packit Service b1ea74
				[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
Packit Service b1ea74
			}
Packit Service b1ea74
Packit Service b1ea74
			[btn setBackgroundImage:btn_background_img forState:UIControlStateNormal];
Packit Service b1ea74
			[btn setTag:curItem->tag];
Packit Service b1ea74
Packit Service b1ea74
			// add button to view
Packit Service b1ea74
			[result_view addSubview:btn];
Packit Service b1ea74
		}
Packit Service b1ea74
	}
Packit Service b1ea74
Packit Service b1ea74
	return result_view;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
@end