Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
48
third_party/FreeRDP/client/iOS/Views/AdvancedKeyboardView.h
vendored
Normal file
48
third_party/FreeRDP/client/iOS/Views/AdvancedKeyboardView.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Advanced keyboard view interface
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
// forward declaration
|
||||
@protocol AdvancedKeyboardDelegate <NSObject>
|
||||
@optional
|
||||
// called when a function key was pressed and a virtual keycode is provided
|
||||
// @key: virtual key code
|
||||
- (void)advancedKeyPressedVKey:(int)key;
|
||||
// called when a function key was pressed and the keys unicode is provided
|
||||
// @key: unicode character
|
||||
- (void)advancedKeyPressedUnicode:(int)key;
|
||||
@end
|
||||
|
||||
@interface AdvancedKeyboardView : UIView
|
||||
{
|
||||
@private
|
||||
// view containing function keys (F-keys) and function block (ins, del, home, end, ...)
|
||||
UIView *_function_keys_view;
|
||||
|
||||
// view containing numpad keys (0-9, +-/*)
|
||||
UIView *_numpad_keys_view;
|
||||
|
||||
// view containing cursor keys (up, down, left, right)
|
||||
UIView *_cursor_keys_view;
|
||||
|
||||
// currently visible view
|
||||
UIView *_cur_view;
|
||||
|
||||
// delegate
|
||||
NSObject<AdvancedKeyboardDelegate> *_delegate;
|
||||
}
|
||||
|
||||
@property(assign) NSObject<AdvancedKeyboardDelegate> *delegate;
|
||||
|
||||
// init keyboard view with frame and delegate
|
||||
- (id)initWithFrame:(CGRect)frame delegate:(NSObject<AdvancedKeyboardDelegate> *)delegate;
|
||||
|
||||
@end
|
||||
345
third_party/FreeRDP/client/iOS/Views/AdvancedKeyboardView.m
vendored
Normal file
345
third_party/FreeRDP/client/iOS/Views/AdvancedKeyboardView.m
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
Advanced keyboard view interface
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "AdvancedKeyboardView.h"
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
|
||||
// helper struct to define button layouts/settings
|
||||
struct ButtonItem
|
||||
{
|
||||
NSString *title;
|
||||
int tag;
|
||||
};
|
||||
|
||||
@interface AdvancedKeyboardView (Private)
|
||||
- (UIView *)keyboardViewForItems:(struct ButtonItem *)items columns:(int)columns rows:(int)rows;
|
||||
@end
|
||||
|
||||
@implementation AdvancedKeyboardView
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
|
||||
// defines for the different views
|
||||
#define KEY_SHOW_FUNCVIEW 0x1000
|
||||
#define KEY_SHOW_CURSORVIEW 0x1001
|
||||
#define KEY_SHOW_NUMPADVIEW 0x1002
|
||||
#define KEY_SKIP 0x8000
|
||||
#define KEY_MERGE_COLUMN 0x8001
|
||||
|
||||
#define KEYCODE_UNICODE 0x80000000
|
||||
|
||||
struct ButtonItem functionKeysItems[24] = { { @"F1", VK_F1 },
|
||||
{ @"F2", VK_F2 },
|
||||
{ @"F3", VK_F3 },
|
||||
{ @"F4", VK_F4 },
|
||||
{ @"F5", VK_F5 },
|
||||
{ @"F6", VK_F6 },
|
||||
{ @"F7", VK_F7 },
|
||||
{ @"F8", VK_F8 },
|
||||
{ @"F9", VK_F9 },
|
||||
{ @"F10", VK_F10 },
|
||||
{ @"F11", VK_F11 },
|
||||
{ @"F12", VK_F12 },
|
||||
|
||||
{ @"img:icon_key_arrows", KEY_SHOW_CURSORVIEW },
|
||||
{ @"Tab", VK_TAB },
|
||||
{ @"Ins", VK_INSERT | KBDEXT },
|
||||
{ @"Home", VK_HOME | KBDEXT },
|
||||
{ @"PgUp", VK_PRIOR | KBDEXT },
|
||||
{ @"img:icon_key_win", VK_LWIN | KBDEXT },
|
||||
|
||||
{ @"123", KEY_SHOW_NUMPADVIEW },
|
||||
{ @"Print", VK_PRINT },
|
||||
{ @"Del", VK_DELETE | KBDEXT },
|
||||
{ @"End", VK_END | KBDEXT },
|
||||
{ @"PgDn", VK_NEXT | KBDEXT },
|
||||
{ @"img:icon_key_menu", VK_APPS | KBDEXT } };
|
||||
|
||||
struct ButtonItem numPadKeysItems[24] = { { @"(", KEYCODE_UNICODE | 40 },
|
||||
{ @")", KEYCODE_UNICODE | 41 },
|
||||
{ @"7", VK_NUMPAD7 },
|
||||
{ @"8", VK_NUMPAD8 },
|
||||
{ @"9", VK_NUMPAD9 },
|
||||
{ @"-", VK_SUBTRACT },
|
||||
|
||||
{ @"/", VK_DIVIDE | KBDEXT },
|
||||
{ @"*", VK_MULTIPLY },
|
||||
{ @"4", VK_NUMPAD4 },
|
||||
{ @"5", VK_NUMPAD5 },
|
||||
{ @"6", VK_NUMPAD6 },
|
||||
{ @"+", VK_ADD },
|
||||
|
||||
{ @"Fn", KEY_SHOW_FUNCVIEW },
|
||||
{ @"Num", VK_NUMLOCK },
|
||||
{ @"1", VK_NUMPAD1 },
|
||||
{ @"2", VK_NUMPAD2 },
|
||||
{ @"3", VK_NUMPAD3 },
|
||||
{ @"img:icon_key_backspace", VK_BACK },
|
||||
|
||||
{ @"img:icon_key_arrows", KEY_SHOW_CURSORVIEW },
|
||||
{ @"=", KEYCODE_UNICODE | 61 },
|
||||
{ @"", KEY_MERGE_COLUMN },
|
||||
{ @"0", VK_NUMPAD0 },
|
||||
{ @".", VK_DECIMAL },
|
||||
{ @"img:icon_key_return", VK_RETURN | KBDEXT } };
|
||||
|
||||
struct ButtonItem cursorKeysItems[24] = { { @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"img:icon_key_arrow_up", VK_UP | KBDEXT },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
|
||||
{ @"Fn", KEY_SHOW_FUNCVIEW },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"img:icon_key_arrow_left", VK_LEFT | KBDEXT },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"img:icon_key_arrow_right", VK_RIGHT | KBDEXT },
|
||||
{ @"img:icon_key_backspace", VK_BACK },
|
||||
|
||||
{ @"123", KEY_SHOW_NUMPADVIEW },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"img:icon_key_arrow_down", VK_DOWN | KBDEXT },
|
||||
{ @"", KEY_SKIP },
|
||||
{ @"img:icon_key_return", VK_RETURN | KBDEXT } };
|
||||
|
||||
- (void)initFunctionKeysView
|
||||
{
|
||||
_function_keys_view = [[self keyboardViewForItems:functionKeysItems columns:6 rows:4] retain];
|
||||
[self addSubview:_function_keys_view];
|
||||
}
|
||||
|
||||
- (void)initNumPadKeysView
|
||||
{
|
||||
_numpad_keys_view = [[self keyboardViewForItems:numPadKeysItems columns:6 rows:4] retain];
|
||||
[self addSubview:_numpad_keys_view];
|
||||
}
|
||||
|
||||
- (void)initCursorKeysView
|
||||
{
|
||||
_cursor_keys_view = [[self keyboardViewForItems:cursorKeysItems columns:6 rows:4] retain];
|
||||
[self addSubview:_cursor_keys_view];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame delegate:(NSObject<AdvancedKeyboardDelegate> *)delegate
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self)
|
||||
{
|
||||
_delegate = delegate;
|
||||
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
||||
self.backgroundColor = [UIColor blackColor];
|
||||
// Initialization code
|
||||
|
||||
[self initCursorKeysView];
|
||||
[self initNumPadKeysView];
|
||||
[self initFunctionKeysView];
|
||||
|
||||
// set function keys view to the initial view and hide others
|
||||
_cur_view = _function_keys_view;
|
||||
[_numpad_keys_view setHidden:YES];
|
||||
[_cursor_keys_view setHidden:YES];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// draw a nice background gradient
|
||||
CGContextRef currentContext = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGGradientRef glossGradient;
|
||||
CGColorSpaceRef rgbColorspace;
|
||||
size_t num_locations = 2;
|
||||
CGFloat locations[2] = { 0.0, 1.0 };
|
||||
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35, // Start color
|
||||
1.0, 1.0, 1.0, 0.06 }; // End color
|
||||
|
||||
rgbColorspace = CGColorSpaceCreateDeviceRGB();
|
||||
glossGradient =
|
||||
CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
|
||||
|
||||
CGRect currentBounds = self.bounds;
|
||||
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
|
||||
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), currentBounds.size.height);
|
||||
CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
|
||||
|
||||
CGGradientRelease(glossGradient);
|
||||
CGColorSpaceRelease(rgbColorspace);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_function_keys_view autorelease];
|
||||
[_numpad_keys_view autorelease];
|
||||
[_cursor_keys_view autorelease];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark button events
|
||||
|
||||
- (IBAction)keyPressed:(id)sender
|
||||
{
|
||||
UIButton *btn = (UIButton *)sender;
|
||||
switch ([btn tag])
|
||||
{
|
||||
case KEY_SHOW_CURSORVIEW:
|
||||
// switch to cursor view
|
||||
[_cur_view setHidden:YES];
|
||||
[_cursor_keys_view setHidden:NO];
|
||||
_cur_view = _cursor_keys_view;
|
||||
break;
|
||||
|
||||
case KEY_SHOW_NUMPADVIEW:
|
||||
// switch to numpad view
|
||||
[_cur_view setHidden:YES];
|
||||
[_numpad_keys_view setHidden:NO];
|
||||
_cur_view = _numpad_keys_view;
|
||||
break;
|
||||
|
||||
case KEY_SHOW_FUNCVIEW:
|
||||
// switch to function keys view
|
||||
[_cur_view setHidden:YES];
|
||||
[_function_keys_view setHidden:NO];
|
||||
_cur_view = _function_keys_view;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ([btn tag] & KEYCODE_UNICODE)
|
||||
{
|
||||
if ([[self delegate] respondsToSelector:@selector(advancedKeyPressedUnicode:)])
|
||||
[[self delegate] advancedKeyPressedUnicode:([btn tag] & ~KEYCODE_UNICODE)];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([[self delegate] respondsToSelector:@selector(advancedKeyPressedVKey:)])
|
||||
[[self delegate] advancedKeyPressedVKey:[btn tag]];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@implementation AdvancedKeyboardView (Private)
|
||||
|
||||
- (UIView *)keyboardViewForItems:(struct ButtonItem *)items columns:(int)columns rows:(int)rows
|
||||
{
|
||||
UIView *result_view = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
|
||||
result_view.autoresizingMask =
|
||||
UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
||||
|
||||
// calculate maximum button size
|
||||
int max_btn_width = result_view.bounds.size.width / ((columns * 2) + 1);
|
||||
int max_btn_height = result_view.bounds.size.height / ((rows * 2) + 1);
|
||||
|
||||
// ensure minimum button size
|
||||
CGSize btn_size = CGSizeMake(45, 30);
|
||||
if (btn_size.width < max_btn_width)
|
||||
btn_size.width = max_btn_width;
|
||||
if (btn_size.height < max_btn_height)
|
||||
btn_size.height = max_btn_height;
|
||||
|
||||
// calc distance width and height between buttons
|
||||
int dist_width = (result_view.bounds.size.width - (columns * btn_size.width)) / (columns + 1);
|
||||
int dist_height = (result_view.bounds.size.height - (rows * btn_size.height)) / (rows + 1);
|
||||
|
||||
UIImage *btn_background_img = [UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"keyboard_button_background"
|
||||
ofType:@"png"]];
|
||||
for (int j = 0; j < rows; j++)
|
||||
{
|
||||
for (int i = 0; i < columns; i++)
|
||||
{
|
||||
struct ButtonItem *curItem = &items[j * columns + i];
|
||||
|
||||
// skip this spot?
|
||||
if (curItem->tag == KEY_SKIP)
|
||||
continue;
|
||||
|
||||
// create button, set autoresizing mask and add action handler
|
||||
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
[btn setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin |
|
||||
UIViewAutoresizingFlexibleRightMargin |
|
||||
UIViewAutoresizingFlexibleTopMargin |
|
||||
UIViewAutoresizingFlexibleBottomMargin |
|
||||
UIViewAutoresizingFlexibleWidth |
|
||||
UIViewAutoresizingFlexibleHeight)];
|
||||
[btn addTarget:self
|
||||
action:@selector(keyPressed:)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
// if merge is specified we merge this button's position with the next one
|
||||
if (curItem->tag == KEY_MERGE_COLUMN)
|
||||
{
|
||||
// calc merged frame
|
||||
[btn setFrame:CGRectMake(dist_width + (i * dist_width) + (i * btn_size.width),
|
||||
dist_height + (j * dist_height) + (j * btn_size.height),
|
||||
btn_size.width * 2 + dist_width, btn_size.height)];
|
||||
|
||||
// proceed to the next column item
|
||||
i++;
|
||||
curItem = &items[j * columns + i];
|
||||
}
|
||||
else
|
||||
{
|
||||
[btn setFrame:CGRectMake(dist_width + (i * dist_width) + (i * btn_size.width),
|
||||
dist_height + (j * dist_height) + (j * btn_size.height),
|
||||
btn_size.width, btn_size.height)];
|
||||
}
|
||||
|
||||
// set button text or image parameters
|
||||
if ([curItem->title hasPrefix:@"img:"] == YES)
|
||||
{
|
||||
UIImage *btn_image =
|
||||
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
|
||||
pathForResource:[curItem->title
|
||||
substringFromIndex:4]
|
||||
ofType:@"png"]];
|
||||
[btn setImage:btn_image forState:UIControlStateNormal];
|
||||
}
|
||||
else
|
||||
{
|
||||
[btn setTitle:curItem->title forState:UIControlStateNormal];
|
||||
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
[btn setBackgroundImage:btn_background_img forState:UIControlStateNormal];
|
||||
[btn setTag:curItem->tag];
|
||||
|
||||
// add button to view
|
||||
[result_view addSubview:btn];
|
||||
}
|
||||
}
|
||||
|
||||
return result_view;
|
||||
}
|
||||
|
||||
@end
|
||||
42
third_party/FreeRDP/client/iOS/Views/BlockAlertView.h
vendored
Normal file
42
third_party/FreeRDP/client/iOS/Views/BlockAlertView.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// BlockAlertView.h
|
||||
//
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface BlockAlertView : NSObject
|
||||
{
|
||||
@protected
|
||||
UIView *_view;
|
||||
NSMutableArray *_blocks;
|
||||
CGFloat _height;
|
||||
NSString *_title;
|
||||
NSString *_message;
|
||||
BOOL _shown;
|
||||
BOOL _cancelBounce;
|
||||
}
|
||||
|
||||
+ (BlockAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message;
|
||||
|
||||
+ (void)showInfoAlertWithTitle:(NSString *)title message:(NSString *)message;
|
||||
+ (void)showErrorAlert:(NSError *)error;
|
||||
|
||||
- (id)initWithTitle:(NSString *)title message:(NSString *)message;
|
||||
|
||||
- (void)setDestructiveButtonWithTitle:(NSString *)title block:(void (^)())block;
|
||||
- (void)setCancelButtonWithTitle:(NSString *)title block:(void (^)())block;
|
||||
- (void)addButtonWithTitle:(NSString *)title block:(void (^)())block;
|
||||
|
||||
- (void)addComponents:(CGRect)frame;
|
||||
|
||||
- (void)show;
|
||||
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated;
|
||||
|
||||
- (void)setupDisplay;
|
||||
|
||||
@property(nonatomic, retain) UIImage *backgroundImage;
|
||||
@property(nonatomic, readonly) UIView *view;
|
||||
@property(nonatomic, readwrite) BOOL vignetteBackground;
|
||||
|
||||
@end
|
||||
475
third_party/FreeRDP/client/iOS/Views/BlockAlertView.m
vendored
Normal file
475
third_party/FreeRDP/client/iOS/Views/BlockAlertView.m
vendored
Normal file
@@ -0,0 +1,475 @@
|
||||
//
|
||||
// BlockAlertView.m
|
||||
//
|
||||
//
|
||||
|
||||
#import "BlockAlertView.h"
|
||||
#import "BlockBackground.h"
|
||||
#import "BlockUI.h"
|
||||
|
||||
@implementation BlockAlertView
|
||||
|
||||
@synthesize view = _view;
|
||||
@synthesize backgroundImage = _backgroundImage;
|
||||
@synthesize vignetteBackground = _vignetteBackground;
|
||||
|
||||
static UIImage *background = nil;
|
||||
static UIImage *backgroundlandscape = nil;
|
||||
static UIFont *titleFont = nil;
|
||||
static UIFont *messageFont = nil;
|
||||
static UIFont *buttonFont = nil;
|
||||
|
||||
#pragma mark - init
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [BlockAlertView class])
|
||||
{
|
||||
background = [UIImage imageNamed:kAlertViewBackground];
|
||||
background =
|
||||
[[background stretchableImageWithLeftCapWidth:0
|
||||
topCapHeight:kAlertViewBackgroundCapHeight] retain];
|
||||
|
||||
backgroundlandscape = [UIImage imageNamed:kAlertViewBackgroundLandscape];
|
||||
backgroundlandscape = [[backgroundlandscape
|
||||
stretchableImageWithLeftCapWidth:0
|
||||
topCapHeight:kAlertViewBackgroundCapHeight] retain];
|
||||
|
||||
titleFont = [kAlertViewTitleFont retain];
|
||||
messageFont = [kAlertViewMessageFont retain];
|
||||
buttonFont = [kAlertViewButtonFont retain];
|
||||
}
|
||||
}
|
||||
|
||||
+ (BlockAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message
|
||||
{
|
||||
return [[[BlockAlertView alloc] initWithTitle:title message:message] autorelease];
|
||||
}
|
||||
|
||||
+ (void)showInfoAlertWithTitle:(NSString *)title message:(NSString *)message
|
||||
{
|
||||
BlockAlertView *alert = [[BlockAlertView alloc] initWithTitle:title message:message];
|
||||
[alert setCancelButtonWithTitle:NSLocalizedString(@"Dismiss", nil) block:nil];
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
|
||||
+ (void)showErrorAlert:(NSError *)error
|
||||
{
|
||||
BlockAlertView *alert = [[BlockAlertView alloc]
|
||||
initWithTitle:NSLocalizedString(@"Operation Failed", nil)
|
||||
message:[NSString
|
||||
stringWithFormat:NSLocalizedString(
|
||||
@"The operation did not complete successfully: %@",
|
||||
nil),
|
||||
error]];
|
||||
[alert setCancelButtonWithTitle:@"Dismiss" block:nil];
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (void)addComponents:(CGRect)frame
|
||||
{
|
||||
if (_title)
|
||||
{
|
||||
CGSize size = [_title sizeWithFont:titleFont
|
||||
constrainedToSize:CGSizeMake(frame.size.width - kAlertViewBorder * 2, 1000)
|
||||
lineBreakMode:NSLineBreakByWordWrapping];
|
||||
|
||||
UILabel *labelView = [[UILabel alloc]
|
||||
initWithFrame:CGRectMake(kAlertViewBorder, _height,
|
||||
frame.size.width - kAlertViewBorder * 2, size.height)];
|
||||
labelView.font = titleFont;
|
||||
labelView.numberOfLines = 0;
|
||||
labelView.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
labelView.textColor = kAlertViewTitleTextColor;
|
||||
labelView.backgroundColor = [UIColor clearColor];
|
||||
labelView.textAlignment = NSTextAlignmentCenter;
|
||||
labelView.shadowColor = kAlertViewTitleShadowColor;
|
||||
labelView.shadowOffset = kAlertViewTitleShadowOffset;
|
||||
labelView.text = _title;
|
||||
[_view addSubview:labelView];
|
||||
[labelView release];
|
||||
|
||||
_height += size.height + kAlertViewBorder;
|
||||
}
|
||||
|
||||
if (_message)
|
||||
{
|
||||
CGSize size =
|
||||
[_message sizeWithFont:messageFont
|
||||
constrainedToSize:CGSizeMake(frame.size.width - kAlertViewBorder * 2, 1000)
|
||||
lineBreakMode:NSLineBreakByWordWrapping];
|
||||
|
||||
UILabel *labelView = [[UILabel alloc]
|
||||
initWithFrame:CGRectMake(kAlertViewBorder, _height,
|
||||
frame.size.width - kAlertViewBorder * 2, size.height)];
|
||||
labelView.font = messageFont;
|
||||
labelView.numberOfLines = 0;
|
||||
labelView.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
labelView.textColor = kAlertViewMessageTextColor;
|
||||
labelView.backgroundColor = [UIColor clearColor];
|
||||
labelView.textAlignment = NSTextAlignmentCenter;
|
||||
labelView.shadowColor = kAlertViewMessageShadowColor;
|
||||
labelView.shadowOffset = kAlertViewMessageShadowOffset;
|
||||
labelView.text = _message;
|
||||
[_view addSubview:labelView];
|
||||
[labelView release];
|
||||
|
||||
_height += size.height + kAlertViewBorder;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupDisplay
|
||||
{
|
||||
[[_view subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||
[obj removeFromSuperview];
|
||||
}];
|
||||
|
||||
UIWindow *parentView = [BlockBackground sharedInstance];
|
||||
CGRect frame = parentView.bounds;
|
||||
frame.origin.x = floorf((frame.size.width - background.size.width) * 0.5);
|
||||
frame.size.width = background.size.width;
|
||||
|
||||
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
|
||||
if (UIInterfaceOrientationIsLandscape(orientation))
|
||||
{
|
||||
frame.size.width += 150;
|
||||
frame.origin.x -= 75;
|
||||
}
|
||||
|
||||
_view.frame = frame;
|
||||
|
||||
_height = kAlertViewBorder + 15;
|
||||
|
||||
if (NeedsLandscapePhoneTweaks)
|
||||
{
|
||||
_height -= 15; // landscape phones need to trimmed a bit
|
||||
}
|
||||
|
||||
[self addComponents:frame];
|
||||
|
||||
if (_shown)
|
||||
[self show];
|
||||
}
|
||||
|
||||
- (id)initWithTitle:(NSString *)title message:(NSString *)message
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_title = [title copy];
|
||||
_message = [message copy];
|
||||
|
||||
_view = [[UIView alloc] init];
|
||||
|
||||
_view.autoresizingMask =
|
||||
UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin |
|
||||
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
|
||||
|
||||
_blocks = [[NSMutableArray alloc] init];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(setupDisplay)
|
||||
name:UIApplicationDidChangeStatusBarOrientationNotification
|
||||
object:nil];
|
||||
|
||||
if ([self class] == [BlockAlertView class])
|
||||
[self setupDisplay];
|
||||
|
||||
_vignetteBackground = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_title release];
|
||||
[_message release];
|
||||
[_backgroundImage release];
|
||||
[_view release];
|
||||
[_blocks release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - Public
|
||||
|
||||
- (void)addButtonWithTitle:(NSString *)title color:(NSString *)color block:(void (^)())block
|
||||
{
|
||||
[_blocks addObject:[NSArray arrayWithObjects:block ? [[block copy] autorelease] : [NSNull null],
|
||||
title, color, nil]];
|
||||
}
|
||||
|
||||
- (void)addButtonWithTitle:(NSString *)title block:(void (^)())block
|
||||
{
|
||||
[self addButtonWithTitle:title color:@"gray" block:block];
|
||||
}
|
||||
|
||||
- (void)setCancelButtonWithTitle:(NSString *)title block:(void (^)())block
|
||||
{
|
||||
[self addButtonWithTitle:title color:@"black" block:block];
|
||||
}
|
||||
|
||||
- (void)setDestructiveButtonWithTitle:(NSString *)title block:(void (^)())block
|
||||
{
|
||||
[self addButtonWithTitle:title color:@"red" block:block];
|
||||
}
|
||||
|
||||
- (void)show
|
||||
{
|
||||
_shown = YES;
|
||||
|
||||
BOOL isSecondButton = NO;
|
||||
NSUInteger index = 0;
|
||||
for (NSUInteger i = 0; i < _blocks.count; i++)
|
||||
{
|
||||
NSArray *block = [_blocks objectAtIndex:i];
|
||||
NSString *title = [block objectAtIndex:1];
|
||||
NSString *color = [block objectAtIndex:2];
|
||||
|
||||
UIImage *image =
|
||||
[UIImage imageNamed:[NSString stringWithFormat:@"alert-%@-button.png", color]];
|
||||
image = [image stretchableImageWithLeftCapWidth:(int)(image.size.width + 1) >> 1
|
||||
topCapHeight:0];
|
||||
|
||||
CGFloat maxHalfWidth = floorf((_view.bounds.size.width - kAlertViewBorder * 3) * 0.5);
|
||||
CGFloat width = _view.bounds.size.width - kAlertViewBorder * 2;
|
||||
CGFloat xOffset = kAlertViewBorder;
|
||||
if (isSecondButton)
|
||||
{
|
||||
width = maxHalfWidth;
|
||||
xOffset = width + kAlertViewBorder * 2;
|
||||
isSecondButton = NO;
|
||||
}
|
||||
else if (i + 1 < _blocks.count)
|
||||
{
|
||||
// In this case there's another button.
|
||||
// Let's check if they fit on the same line.
|
||||
CGSize size = [title sizeWithFont:buttonFont
|
||||
minFontSize:10
|
||||
actualFontSize:nil
|
||||
forWidth:_view.bounds.size.width - kAlertViewBorder * 2
|
||||
lineBreakMode:NSLineBreakByClipping];
|
||||
|
||||
if (size.width < maxHalfWidth - kAlertViewBorder)
|
||||
{
|
||||
// It might fit. Check the next Button
|
||||
NSArray *block2 = [_blocks objectAtIndex:i + 1];
|
||||
NSString *title2 = [block2 objectAtIndex:1];
|
||||
size = [title2 sizeWithFont:buttonFont
|
||||
minFontSize:10
|
||||
actualFontSize:nil
|
||||
forWidth:_view.bounds.size.width - kAlertViewBorder * 2
|
||||
lineBreakMode:NSLineBreakByClipping];
|
||||
|
||||
if (size.width < maxHalfWidth - kAlertViewBorder)
|
||||
{
|
||||
// They'll fit!
|
||||
isSecondButton = YES; // For the next iteration
|
||||
width = maxHalfWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_blocks.count == 1)
|
||||
{
|
||||
// In this case this is the only button. We'll size according to the text
|
||||
CGSize size = [title sizeWithFont:buttonFont
|
||||
minFontSize:10
|
||||
actualFontSize:nil
|
||||
forWidth:_view.bounds.size.width - kAlertViewBorder * 2
|
||||
lineBreakMode:UILineBreakModeClip];
|
||||
|
||||
size.width = MAX(size.width, 80);
|
||||
if (size.width + 2 * kAlertViewBorder < width)
|
||||
{
|
||||
width = size.width + 2 * kAlertViewBorder;
|
||||
xOffset = floorf((_view.bounds.size.width - width) * 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
button.frame = CGRectMake(xOffset, _height, width, kAlertButtonHeight);
|
||||
button.titleLabel.font = buttonFont;
|
||||
if (IOS_LESS_THAN_6)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
button.titleLabel.minimumFontSize = 10;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
else
|
||||
{
|
||||
button.titleLabel.adjustsFontSizeToFitWidth = YES;
|
||||
button.titleLabel.adjustsLetterSpacingToFitWidth = YES;
|
||||
button.titleLabel.minimumScaleFactor = 0.1;
|
||||
}
|
||||
button.titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
button.titleLabel.shadowOffset = kAlertViewButtonShadowOffset;
|
||||
button.backgroundColor = [UIColor clearColor];
|
||||
button.tag = i + 1;
|
||||
|
||||
[button setBackgroundImage:image forState:UIControlStateNormal];
|
||||
[button setTitleColor:kAlertViewButtonTextColor forState:UIControlStateNormal];
|
||||
[button setTitleShadowColor:kAlertViewButtonShadowColor forState:UIControlStateNormal];
|
||||
[button setTitle:title forState:UIControlStateNormal];
|
||||
button.accessibilityLabel = title;
|
||||
|
||||
[button addTarget:self
|
||||
action:@selector(buttonClicked:)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[_view addSubview:button];
|
||||
|
||||
if (!isSecondButton)
|
||||
_height += kAlertButtonHeight + kAlertViewBorder;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
_height += 10; // Margin for the shadow
|
||||
|
||||
if (_height < background.size.height)
|
||||
{
|
||||
CGFloat offset = background.size.height - _height;
|
||||
_height = background.size.height;
|
||||
CGRect frame;
|
||||
for (NSUInteger i = 0; i < _blocks.count; i++)
|
||||
{
|
||||
UIButton *btn = (UIButton *)[_view viewWithTag:i + 1];
|
||||
frame = btn.frame;
|
||||
frame.origin.y += offset;
|
||||
btn.frame = frame;
|
||||
}
|
||||
}
|
||||
|
||||
CGRect frame = _view.frame;
|
||||
frame.origin.y = -_height;
|
||||
frame.size.height = _height;
|
||||
_view.frame = frame;
|
||||
|
||||
UIImageView *modalBackground = [[UIImageView alloc] initWithFrame:_view.bounds];
|
||||
|
||||
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
|
||||
modalBackground.image = backgroundlandscape;
|
||||
else
|
||||
modalBackground.image = background;
|
||||
|
||||
modalBackground.contentMode = UIViewContentModeScaleToFill;
|
||||
modalBackground.autoresizingMask =
|
||||
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
[_view insertSubview:modalBackground atIndex:0];
|
||||
[modalBackground release];
|
||||
|
||||
if (_backgroundImage)
|
||||
{
|
||||
[BlockBackground sharedInstance].backgroundImage = _backgroundImage;
|
||||
[_backgroundImage release];
|
||||
_backgroundImage = nil;
|
||||
}
|
||||
|
||||
[BlockBackground sharedInstance].vignetteBackground = _vignetteBackground;
|
||||
[[BlockBackground sharedInstance] addToMainWindow:_view];
|
||||
|
||||
__block CGPoint center = _view.center;
|
||||
center.y = floorf([BlockBackground sharedInstance].bounds.size.height * 0.5) + kAlertViewBounce;
|
||||
|
||||
_cancelBounce = NO;
|
||||
|
||||
[UIView animateWithDuration:0.4
|
||||
delay:0.0
|
||||
options:UIViewAnimationCurveEaseOut
|
||||
animations:^{
|
||||
[BlockBackground sharedInstance].alpha = 1.0f;
|
||||
_view.center = center;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
if (_cancelBounce)
|
||||
return;
|
||||
|
||||
[UIView animateWithDuration:0.1
|
||||
delay:0.0
|
||||
options:0
|
||||
animations:^{
|
||||
center.y -= kAlertViewBounce;
|
||||
_view.center = center;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:@"AlertViewFinishedAnimations"
|
||||
object:nil];
|
||||
}];
|
||||
}];
|
||||
|
||||
[self retain];
|
||||
}
|
||||
|
||||
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
|
||||
{
|
||||
_shown = NO;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
if (buttonIndex >= 0 && buttonIndex < [_blocks count])
|
||||
{
|
||||
id obj = [[_blocks objectAtIndex:buttonIndex] objectAtIndex:0];
|
||||
if (![obj isEqual:[NSNull null]])
|
||||
{
|
||||
((void (^)())obj)();
|
||||
}
|
||||
}
|
||||
|
||||
if (animated)
|
||||
{
|
||||
[UIView animateWithDuration:0.1
|
||||
delay:0.0
|
||||
options:0
|
||||
animations:^{
|
||||
CGPoint center = _view.center;
|
||||
center.y += 20;
|
||||
_view.center = center;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[UIView animateWithDuration:0.4
|
||||
delay:0.0
|
||||
options:UIViewAnimationCurveEaseIn
|
||||
animations:^{
|
||||
CGRect frame = _view.frame;
|
||||
frame.origin.y = -frame.size.height;
|
||||
_view.frame = frame;
|
||||
[[BlockBackground sharedInstance] reduceAlphaIfEmpty];
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[[BlockBackground sharedInstance] removeView:_view];
|
||||
[_view release];
|
||||
_view = nil;
|
||||
[self autorelease];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[BlockBackground sharedInstance] removeView:_view];
|
||||
[_view release];
|
||||
_view = nil;
|
||||
[self autorelease];
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - Action
|
||||
|
||||
- (void)buttonClicked:(id)sender
|
||||
{
|
||||
/* Run the button's block */
|
||||
int buttonIndex = [sender tag] - 1;
|
||||
[self dismissWithClickedButtonIndex:buttonIndex animated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
26
third_party/FreeRDP/client/iOS/Views/BlockBackground.h
vendored
Normal file
26
third_party/FreeRDP/client/iOS/Views/BlockBackground.h
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// BlockBackground.h
|
||||
// arrived
|
||||
//
|
||||
// Created by Gustavo Ambrozio on 29/11/11.
|
||||
// Copyright (c) 2011 N/A. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface BlockBackground : UIWindow
|
||||
{
|
||||
@private
|
||||
UIWindow *_previousKeyWindow;
|
||||
}
|
||||
|
||||
+ (BlockBackground *)sharedInstance;
|
||||
|
||||
- (void)addToMainWindow:(UIView *)view;
|
||||
- (void)reduceAlphaIfEmpty;
|
||||
- (void)removeView:(UIView *)view;
|
||||
|
||||
@property(nonatomic, retain) UIImage *backgroundImage;
|
||||
@property(nonatomic, readwrite) BOOL vignetteBackground;
|
||||
|
||||
@end
|
||||
238
third_party/FreeRDP/client/iOS/Views/BlockBackground.m
vendored
Normal file
238
third_party/FreeRDP/client/iOS/Views/BlockBackground.m
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
//
|
||||
// BlockBackground.m
|
||||
// arrived
|
||||
//
|
||||
// Created by Gustavo Ambrozio on 29/11/11.
|
||||
// Copyright (c) 2011 N/A. All rights reserved.
|
||||
//
|
||||
|
||||
#import "BlockBackground.h"
|
||||
|
||||
@implementation BlockBackground
|
||||
|
||||
@synthesize backgroundImage = _backgroundImage;
|
||||
@synthesize vignetteBackground = _vignetteBackground;
|
||||
|
||||
static BlockBackground *_sharedInstance = nil;
|
||||
|
||||
+ (BlockBackground *)sharedInstance
|
||||
{
|
||||
if (_sharedInstance != nil)
|
||||
{
|
||||
return _sharedInstance;
|
||||
}
|
||||
|
||||
@synchronized(self)
|
||||
{
|
||||
if (_sharedInstance == nil)
|
||||
{
|
||||
[[[self alloc] init] autorelease];
|
||||
}
|
||||
}
|
||||
|
||||
return _sharedInstance;
|
||||
}
|
||||
|
||||
+ (id)allocWithZone:(NSZone *)zone
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
if (_sharedInstance == nil)
|
||||
{
|
||||
_sharedInstance = [super allocWithZone:zone];
|
||||
return _sharedInstance;
|
||||
}
|
||||
}
|
||||
NSAssert(NO, @ "[BlockBackground alloc] explicitly called on singleton class.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)retain
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (unsigned)retainCount
|
||||
{
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
- (oneway void)release
|
||||
{
|
||||
}
|
||||
|
||||
- (id)autorelease
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setRotation:(NSNotification *)notification
|
||||
{
|
||||
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
|
||||
|
||||
CGRect orientationFrame = [UIScreen mainScreen].bounds;
|
||||
|
||||
if ((UIInterfaceOrientationIsLandscape(orientation) &&
|
||||
orientationFrame.size.height > orientationFrame.size.width) ||
|
||||
(UIInterfaceOrientationIsPortrait(orientation) &&
|
||||
orientationFrame.size.width > orientationFrame.size.height))
|
||||
{
|
||||
float temp = orientationFrame.size.width;
|
||||
orientationFrame.size.width = orientationFrame.size.height;
|
||||
orientationFrame.size.height = temp;
|
||||
}
|
||||
|
||||
self.transform = CGAffineTransformIdentity;
|
||||
self.frame = orientationFrame;
|
||||
|
||||
CGFloat posY = orientationFrame.size.height / 2;
|
||||
CGFloat posX = orientationFrame.size.width / 2;
|
||||
|
||||
CGPoint newCenter;
|
||||
CGFloat rotateAngle;
|
||||
|
||||
switch (orientation)
|
||||
{
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
rotateAngle = M_PI;
|
||||
newCenter = CGPointMake(posX, orientationFrame.size.height - posY);
|
||||
break;
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
rotateAngle = -M_PI / 2.0f;
|
||||
newCenter = CGPointMake(posY, posX);
|
||||
break;
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
rotateAngle = M_PI / 2.0f;
|
||||
newCenter = CGPointMake(orientationFrame.size.height - posY, posX);
|
||||
break;
|
||||
default: // UIInterfaceOrientationPortrait
|
||||
rotateAngle = 0.0;
|
||||
newCenter = CGPointMake(posX, posY);
|
||||
break;
|
||||
}
|
||||
|
||||
self.transform = CGAffineTransformMakeRotation(rotateAngle);
|
||||
self.center = newCenter;
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self layoutSubviews];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
if (self)
|
||||
{
|
||||
self.windowLevel = UIWindowLevelStatusBar;
|
||||
self.hidden = YES;
|
||||
self.userInteractionEnabled = NO;
|
||||
self.backgroundColor = [UIColor colorWithWhite:0.4 alpha:0.5f];
|
||||
self.vignetteBackground = NO;
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(setRotation:)
|
||||
name:UIApplicationDidChangeStatusBarOrientationNotification
|
||||
object:nil];
|
||||
[self setRotation:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addToMainWindow:(UIView *)view
|
||||
{
|
||||
[self setRotation:nil];
|
||||
|
||||
if ([self.subviews containsObject:view])
|
||||
return;
|
||||
|
||||
if (self.hidden)
|
||||
{
|
||||
_previousKeyWindow = [[[UIApplication sharedApplication] keyWindow] retain];
|
||||
self.alpha = 0.0f;
|
||||
self.hidden = NO;
|
||||
self.userInteractionEnabled = YES;
|
||||
[self makeKeyWindow];
|
||||
}
|
||||
|
||||
if (self.subviews.count > 0)
|
||||
{
|
||||
((UIView *)[self.subviews lastObject]).userInteractionEnabled = NO;
|
||||
}
|
||||
|
||||
if (_backgroundImage)
|
||||
{
|
||||
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:_backgroundImage];
|
||||
backgroundView.frame = self.bounds;
|
||||
backgroundView.contentMode = UIViewContentModeScaleToFill;
|
||||
[self addSubview:backgroundView];
|
||||
[backgroundView release];
|
||||
[_backgroundImage release];
|
||||
_backgroundImage = nil;
|
||||
}
|
||||
|
||||
[self addSubview:view];
|
||||
}
|
||||
|
||||
- (void)reduceAlphaIfEmpty
|
||||
{
|
||||
if (self.subviews.count == 1 ||
|
||||
(self.subviews.count == 2 &&
|
||||
[[self.subviews objectAtIndex:0] isKindOfClass:[UIImageView class]]))
|
||||
{
|
||||
self.alpha = 0.0f;
|
||||
self.userInteractionEnabled = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeView:(UIView *)view
|
||||
{
|
||||
[view removeFromSuperview];
|
||||
|
||||
UIView *topView = [self.subviews lastObject];
|
||||
if ([topView isKindOfClass:[UIImageView class]])
|
||||
{
|
||||
// It's a background. Remove it too
|
||||
[topView removeFromSuperview];
|
||||
}
|
||||
|
||||
if (self.subviews.count == 0)
|
||||
{
|
||||
self.hidden = YES;
|
||||
[_previousKeyWindow makeKeyWindow];
|
||||
[_previousKeyWindow release];
|
||||
_previousKeyWindow = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
((UIView *)[self.subviews lastObject]).userInteractionEnabled = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
if (_backgroundImage || !_vignetteBackground)
|
||||
return;
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
size_t locationsCount = 2;
|
||||
CGFloat locations[2] = { 0.0f, 1.0f };
|
||||
CGFloat colors[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f };
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGGradientRef gradient =
|
||||
CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
CGPoint center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
|
||||
float radius = MIN(self.bounds.size.width, self.bounds.size.height);
|
||||
CGContextDrawRadialGradient(context, gradient, center, 0, center, radius,
|
||||
kCGGradientDrawsAfterEndLocation);
|
||||
CGGradientRelease(gradient);
|
||||
}
|
||||
|
||||
@end
|
||||
74
third_party/FreeRDP/client/iOS/Views/BlockUI.h
vendored
Normal file
74
third_party/FreeRDP/client/iOS/Views/BlockUI.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// BlockUI.h
|
||||
//
|
||||
// Created by Gustavo Ambrozio on 14/2/12.
|
||||
//
|
||||
|
||||
#ifndef BlockUI_h
|
||||
#define BlockUI_h
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000
|
||||
#define NSTextAlignmentCenter UITextAlignmentCenter
|
||||
#define NSLineBreakByWordWrapping UILineBreakModeWordWrap
|
||||
#define NSLineBreakByClipping UILineBreakModeClip
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef IOS_LESS_THAN_6
|
||||
#define IOS_LESS_THAN_6 \
|
||||
!([[[UIDevice currentDevice] systemVersion] compare:@"6.0" \
|
||||
options:NSNumericSearch] != NSOrderedAscending)
|
||||
|
||||
#endif
|
||||
|
||||
#define NeedsLandscapePhoneTweaks \
|
||||
(UIInterfaceOrientationIsLandscape( \
|
||||
[[UIApplication sharedApplication] statusBarOrientation]) && \
|
||||
UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad)
|
||||
|
||||
// Action Sheet constants
|
||||
|
||||
#define kActionSheetBounce 10
|
||||
#define kActionSheetBorder 10
|
||||
#define kActionSheetButtonHeight 45
|
||||
#define kActionSheetTopMargin 15
|
||||
|
||||
#define kActionSheetTitleFont [UIFont systemFontOfSize:18]
|
||||
#define kActionSheetTitleTextColor [UIColor whiteColor]
|
||||
#define kActionSheetTitleShadowColor [UIColor blackColor]
|
||||
#define kActionSheetTitleShadowOffset CGSizeMake(0, -1)
|
||||
|
||||
#define kActionSheetButtonFont [UIFont boldSystemFontOfSize:20]
|
||||
#define kActionSheetButtonTextColor [UIColor whiteColor]
|
||||
#define kActionSheetButtonShadowColor [UIColor blackColor]
|
||||
#define kActionSheetButtonShadowOffset CGSizeMake(0, -1)
|
||||
|
||||
#define kActionSheetBackground @"action-sheet-panel.png"
|
||||
#define kActionSheetBackgroundCapHeight 30
|
||||
|
||||
// Alert View constants
|
||||
|
||||
#define kAlertViewBounce 20
|
||||
#define kAlertViewBorder (NeedsLandscapePhoneTweaks ? 5 : 10)
|
||||
#define kAlertButtonHeight (NeedsLandscapePhoneTweaks ? 35 : 44)
|
||||
|
||||
#define kAlertViewTitleFont [UIFont boldSystemFontOfSize:20]
|
||||
#define kAlertViewTitleTextColor [UIColor colorWithWhite:244.0 / 255.0 alpha:1.0]
|
||||
#define kAlertViewTitleShadowColor [UIColor blackColor]
|
||||
#define kAlertViewTitleShadowOffset CGSizeMake(0, -1)
|
||||
|
||||
#define kAlertViewMessageFont [UIFont systemFontOfSize:18]
|
||||
#define kAlertViewMessageTextColor [UIColor colorWithWhite:244.0 / 255.0 alpha:1.0]
|
||||
#define kAlertViewMessageShadowColor [UIColor blackColor]
|
||||
#define kAlertViewMessageShadowOffset CGSizeMake(0, -1)
|
||||
|
||||
#define kAlertViewButtonFont [UIFont boldSystemFontOfSize:18]
|
||||
#define kAlertViewButtonTextColor [UIColor whiteColor]
|
||||
#define kAlertViewButtonShadowColor [UIColor blackColor]
|
||||
#define kAlertViewButtonShadowOffset CGSizeMake(0, -1)
|
||||
|
||||
#define kAlertViewBackground @"alert-window.png"
|
||||
#define kAlertViewBackgroundLandscape @"alert-window-landscape.png"
|
||||
#define kAlertViewBackgroundCapHeight 38
|
||||
|
||||
#endif
|
||||
24
third_party/FreeRDP/client/iOS/Views/BookmarkTableCell.h
vendored
Normal file
24
third_party/FreeRDP/client/iOS/Views/BookmarkTableCell.h
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Custom bookmark table cell
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface BookmarkTableCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_title;
|
||||
IBOutlet UILabel *_sub_title;
|
||||
IBOutlet UIImageView *_connection_state_icon;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *title;
|
||||
@property(retain, nonatomic) UILabel *subTitle;
|
||||
@property(retain, nonatomic) UIImageView *connectionStateIcon;
|
||||
|
||||
@end
|
||||
39
third_party/FreeRDP/client/iOS/Views/BookmarkTableCell.m
vendored
Normal file
39
third_party/FreeRDP/client/iOS/Views/BookmarkTableCell.m
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Custom bookmark table cell
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "BookmarkTableCell.h"
|
||||
|
||||
@implementation BookmarkTableCell
|
||||
|
||||
@synthesize title = _title, subTitle = _sub_title, connectionStateIcon = _connection_state_icon;
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
|
||||
{
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
22
third_party/FreeRDP/client/iOS/Views/EditButtonTableViewCell.h
vendored
Normal file
22
third_party/FreeRDP/client/iOS/Views/EditButtonTableViewCell.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Custom table cell with a button
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EditButtonTableViewCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_label;
|
||||
IBOutlet UIButton *_button;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *label;
|
||||
@property(retain, nonatomic) UIButton *button;
|
||||
|
||||
@end
|
||||
34
third_party/FreeRDP/client/iOS/Views/EditButtonTableViewCell.m
vendored
Normal file
34
third_party/FreeRDP/client/iOS/Views/EditButtonTableViewCell.m
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Custom table cell with a button
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "EditButtonTableViewCell.h"
|
||||
|
||||
@implementation EditButtonTableViewCell
|
||||
|
||||
@synthesize label = _label, button = _button;
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self)
|
||||
{
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
@end
|
||||
22
third_party/FreeRDP/client/iOS/Views/EditFlagTableViewCell.h
vendored
Normal file
22
third_party/FreeRDP/client/iOS/Views/EditFlagTableViewCell.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Custom table cell with toggle switch
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EditFlagTableViewCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_label;
|
||||
IBOutlet UISwitch *_toggle;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *label;
|
||||
@property(retain, nonatomic) UISwitch *toggle;
|
||||
|
||||
@end
|
||||
34
third_party/FreeRDP/client/iOS/Views/EditFlagTableViewCell.m
vendored
Normal file
34
third_party/FreeRDP/client/iOS/Views/EditFlagTableViewCell.m
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Custom table cell with toggle switch
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "EditFlagTableViewCell.h"
|
||||
|
||||
@implementation EditFlagTableViewCell
|
||||
|
||||
@synthesize label = _label, toggle = _toggle;
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self)
|
||||
{
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
@end
|
||||
25
third_party/FreeRDP/client/iOS/Views/EditSecretTextTableViewCell.h
vendored
Normal file
25
third_party/FreeRDP/client/iOS/Views/EditSecretTextTableViewCell.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Custom table cell with secret edit text field
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EditSecretTextTableViewCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_label;
|
||||
IBOutlet UITextField *_textfield;
|
||||
IBOutlet UIButton *_unhide_button;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *label;
|
||||
@property(retain, nonatomic) UITextField *textfield;
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled;
|
||||
|
||||
@end
|
||||
61
third_party/FreeRDP/client/iOS/Views/EditSecretTextTableViewCell.m
vendored
Normal file
61
third_party/FreeRDP/client/iOS/Views/EditSecretTextTableViewCell.m
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Custom table cell with secret edit text field
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "EditSecretTextTableViewCell.h"
|
||||
|
||||
@implementation EditSecretTextTableViewCell
|
||||
|
||||
@synthesize label = _label, textfield = _textfield;
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
[_unhide_button setTitle:NSLocalizedString(@"Unhide", @"Button title 'Unhide'")
|
||||
forState:UIControlStateNormal];
|
||||
[_unhide_button addTarget:self
|
||||
action:@selector(togglePasswordMode:)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled
|
||||
{
|
||||
[_label setEnabled:enabled];
|
||||
[_textfield setEnabled:enabled];
|
||||
[_unhide_button setEnabled:enabled];
|
||||
}
|
||||
|
||||
#pragma mark - action handlers
|
||||
- (void)togglePasswordMode:(id)sender
|
||||
{
|
||||
BOOL isSecure = [_textfield isSecureTextEntry];
|
||||
|
||||
if (isSecure)
|
||||
{
|
||||
[_unhide_button setTitle:NSLocalizedString(@"Hide", @"Button title 'Hide'")
|
||||
forState:UIControlStateNormal];
|
||||
[_textfield setSecureTextEntry:NO];
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL first_responder = [_textfield isFirstResponder];
|
||||
// little trick to make non-secure to secure transition working - this seems to be an ios
|
||||
// bug:
|
||||
// http://stackoverflow.com/questions/6710019/uitextfield-securetextentry-works-going-from-yes-to-no-but-changing-back-to-y
|
||||
[_textfield setEnabled:NO];
|
||||
[_unhide_button setTitle:NSLocalizedString(@"Unhide", @"Button title 'Unhide'")
|
||||
forState:UIControlStateNormal];
|
||||
[_textfield setSecureTextEntry:YES];
|
||||
[_textfield setEnabled:YES];
|
||||
if (first_responder)
|
||||
[_textfield becomeFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
22
third_party/FreeRDP/client/iOS/Views/EditSelectionTableViewCell.h
vendored
Normal file
22
third_party/FreeRDP/client/iOS/Views/EditSelectionTableViewCell.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Custom table cell with a label on the right, showing the current selection
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EditSelectionTableViewCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_label;
|
||||
IBOutlet UILabel *_selection;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *label;
|
||||
@property(retain, nonatomic) UILabel *selection;
|
||||
|
||||
@end
|
||||
34
third_party/FreeRDP/client/iOS/Views/EditSelectionTableViewCell.m
vendored
Normal file
34
third_party/FreeRDP/client/iOS/Views/EditSelectionTableViewCell.m
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Custom table cell with a label on the right, showing the current selection
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "EditSelectionTableViewCell.h"
|
||||
|
||||
@implementation EditSelectionTableViewCell
|
||||
|
||||
@synthesize label = _label, selection = _selection;
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self)
|
||||
{
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
@end
|
||||
20
third_party/FreeRDP/client/iOS/Views/EditSubEditTableViewCell.h
vendored
Normal file
20
third_party/FreeRDP/client/iOS/Views/EditSubEditTableViewCell.h
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Custom table cell indicating a switch to a sub-view
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EditSubEditTableViewCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_label;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *label;
|
||||
|
||||
@end
|
||||
34
third_party/FreeRDP/client/iOS/Views/EditSubEditTableViewCell.m
vendored
Normal file
34
third_party/FreeRDP/client/iOS/Views/EditSubEditTableViewCell.m
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Custom table cell indicating a switch to a sub-view
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "EditSubEditTableViewCell.h"
|
||||
|
||||
@implementation EditSubEditTableViewCell
|
||||
|
||||
@synthesize label = _label;
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self)
|
||||
{
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
@end
|
||||
22
third_party/FreeRDP/client/iOS/Views/EditTextTableViewCell.h
vendored
Normal file
22
third_party/FreeRDP/client/iOS/Views/EditTextTableViewCell.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Custom table cell with edit text field
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EditTextTableViewCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_label;
|
||||
IBOutlet UITextField *_textfield;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *label;
|
||||
@property(retain, nonatomic) UITextField *textfield;
|
||||
|
||||
@end
|
||||
34
third_party/FreeRDP/client/iOS/Views/EditTextTableViewCell.m
vendored
Normal file
34
third_party/FreeRDP/client/iOS/Views/EditTextTableViewCell.m
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Custom table cell with edit text field
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "EditTextTableViewCell.h"
|
||||
|
||||
@implementation EditTextTableViewCell
|
||||
|
||||
@synthesize label = _label, textfield = _textfield;
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self)
|
||||
{
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
@end
|
||||
21
third_party/FreeRDP/client/iOS/Views/RDPSessionView.h
vendored
Normal file
21
third_party/FreeRDP/client/iOS/Views/RDPSessionView.h
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
RDP Session View
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "RDPSession.h"
|
||||
|
||||
@interface RDPSessionView : UIView
|
||||
{
|
||||
RDPSession *_session;
|
||||
}
|
||||
|
||||
- (void)setSession:(RDPSession *)session;
|
||||
|
||||
@end
|
||||
58
third_party/FreeRDP/client/iOS/Views/RDPSessionView.m
vendored
Normal file
58
third_party/FreeRDP/client/iOS/Views/RDPSessionView.m
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
RDP Session View
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "RDPSessionView.h"
|
||||
|
||||
@implementation RDPSessionView
|
||||
|
||||
- (void)setSession:(RDPSession *)session
|
||||
{
|
||||
_session = session;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
_session = nil;
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
if (_session != nil && [_session bitmapContext])
|
||||
{
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGImageRef cgImage = CGBitmapContextCreateImage([_session bitmapContext]);
|
||||
|
||||
CGContextTranslateCTM(context, 0, [self bounds].size.height);
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
CGContextClipToRect(context,
|
||||
CGRectMake(rect.origin.x,
|
||||
[self bounds].size.height - rect.origin.y - rect.size.height,
|
||||
rect.size.width, rect.size.height));
|
||||
CGContextDrawImage(context,
|
||||
CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height),
|
||||
cgImage);
|
||||
|
||||
CGImageRelease(cgImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just clear the screen with black
|
||||
[[UIColor blackColor] set];
|
||||
UIRectFill([self bounds]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
28
third_party/FreeRDP/client/iOS/Views/SessionTableCell.h
vendored
Normal file
28
third_party/FreeRDP/client/iOS/Views/SessionTableCell.h
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Custom session table cell
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface SessionTableCell : UITableViewCell
|
||||
{
|
||||
IBOutlet UILabel *_title;
|
||||
IBOutlet UILabel *_server;
|
||||
IBOutlet UILabel *_username;
|
||||
IBOutlet UIImageView *_screenshot;
|
||||
IBOutlet UIButton *_disconnect_button;
|
||||
}
|
||||
|
||||
@property(retain, nonatomic) UILabel *title;
|
||||
@property(retain, nonatomic) UILabel *server;
|
||||
@property(retain, nonatomic) UILabel *username;
|
||||
@property(retain, nonatomic) UIImageView *screenshot;
|
||||
@property(retain, nonatomic) UIButton *disconnectButton;
|
||||
|
||||
@end
|
||||
42
third_party/FreeRDP/client/iOS/Views/SessionTableCell.m
vendored
Normal file
42
third_party/FreeRDP/client/iOS/Views/SessionTableCell.m
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Custom session table cell
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "SessionTableCell.h"
|
||||
|
||||
@implementation SessionTableCell
|
||||
|
||||
@synthesize title = _title, server = _server, username = _username, screenshot = _screenshot,
|
||||
disconnectButton = _disconnect_button;
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self)
|
||||
{
|
||||
// Initialization code.
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state.
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
75
third_party/FreeRDP/client/iOS/Views/TouchPointerView.h
vendored
Normal file
75
third_party/FreeRDP/client/iOS/Views/TouchPointerView.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
RDP Touch Pointer View
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
// protocol for touch pointer callbacks
|
||||
@protocol TouchPointerDelegate
|
||||
// callback if touch pointer should be closed
|
||||
- (void)touchPointerClose;
|
||||
// callback for a left click action
|
||||
- (void)touchPointerLeftClick:(CGPoint)pos down:(BOOL)down;
|
||||
// callback for a right click action
|
||||
- (void)touchPointerRightClick:(CGPoint)pos down:(BOOL)down;
|
||||
// callback for pointer move action
|
||||
- (void)touchPointerMove:(CGPoint)pos;
|
||||
// callback if scrolling is performed
|
||||
- (void)touchPointerScrollDown:(BOOL)down;
|
||||
// callback for toggling the standard keyboard
|
||||
- (void)touchPointerToggleKeyboard;
|
||||
// callback for toggling the extended keyboard
|
||||
- (void)touchPointerToggleExtendedKeyboard;
|
||||
// callback for reset session view
|
||||
- (void)touchPointerResetSessionView;
|
||||
@end
|
||||
|
||||
@interface TouchPointerView : UIView
|
||||
{
|
||||
// transformation and image currently drawn
|
||||
CGAffineTransform _pointer_transformation;
|
||||
UIImage *_cur_pointer_img;
|
||||
|
||||
// action images
|
||||
UIImage *_default_pointer_img;
|
||||
UIImage *_active_pointer_img;
|
||||
UIImage *_lclick_pointer_img;
|
||||
UIImage *_rclick_pointer_img;
|
||||
UIImage *_scroll_pointer_img;
|
||||
UIImage *_extkeyboard_pointer_img;
|
||||
UIImage *_keyboard_pointer_img;
|
||||
UIImage *_reset_pointer_img;
|
||||
|
||||
// predefined areas for all actions
|
||||
CGRect _pointer_areas[9];
|
||||
|
||||
// scroll/drag n drop handling
|
||||
CGPoint _prev_touch_location;
|
||||
BOOL _pointer_moving;
|
||||
BOOL _pointer_scrolling;
|
||||
|
||||
NSObject<TouchPointerDelegate> *_delegate;
|
||||
}
|
||||
|
||||
@property(assign) IBOutlet NSObject<TouchPointerDelegate> *delegate;
|
||||
|
||||
// positions the pointer on screen if it got offscreen after an orentation change or after
|
||||
// displaying the keyboard
|
||||
- (void)ensurePointerIsVisible;
|
||||
|
||||
// returns the extent required for the scrollview to use the touch pointer near the edges of the
|
||||
// session view
|
||||
- (UIEdgeInsets)getEdgeInsets;
|
||||
|
||||
// return pointer dimension and position information
|
||||
- (CGPoint)getPointerPosition;
|
||||
- (int)getPointerWidth;
|
||||
- (int)getPointerHeight;
|
||||
|
||||
@end
|
||||
358
third_party/FreeRDP/client/iOS/Views/TouchPointerView.m
vendored
Normal file
358
third_party/FreeRDP/client/iOS/Views/TouchPointerView.m
vendored
Normal file
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
RDP Touch Pointer View
|
||||
|
||||
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#import "TouchPointerView.h"
|
||||
#import "Utils.h"
|
||||
|
||||
#define RESET_DEFAULT_POINTER_IMAGE_DELAY 0.15
|
||||
|
||||
#define POINTER_ACTION_CURSOR 0
|
||||
#define POINTER_ACTION_CLOSE 3
|
||||
#define POINTER_ACTION_RCLICK 2
|
||||
#define POINTER_ACTION_LCLICK 4
|
||||
#define POINTER_ACTION_MOVE 4
|
||||
#define POINTER_ACTION_SCROLL 5
|
||||
#define POINTER_ACTION_KEYBOARD 7
|
||||
#define POINTER_ACTION_EXTKEYBOARD 8
|
||||
#define POINTER_ACTION_RESET 6
|
||||
|
||||
@interface TouchPointerView (Private)
|
||||
- (void)setCurrentPointerImage:(UIImage *)image;
|
||||
- (void)displayPointerActionImage:(UIImage *)image;
|
||||
- (BOOL)pointInsidePointer:(CGPoint)point;
|
||||
- (BOOL)pointInsidePointerArea:(int)area point:(CGPoint)point;
|
||||
- (CGPoint)getCursorPosition;
|
||||
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
|
||||
- (void)handleSingleTap:(UITapGestureRecognizer *)gesture;
|
||||
- (void)handlerForGesture:(UIGestureRecognizer *)gesture sendClick:(BOOL)sendClick;
|
||||
@end
|
||||
|
||||
@implementation TouchPointerView
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
|
||||
// set content mode when rotating (keep aspect ratio)
|
||||
[self setContentMode:UIViewContentModeTopLeft];
|
||||
|
||||
// load touchPointerImage
|
||||
_default_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_default"
|
||||
ofType:@"png"]] retain];
|
||||
_active_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_active"
|
||||
ofType:@"png"]] retain];
|
||||
_lclick_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_lclick"
|
||||
ofType:@"png"]] retain];
|
||||
_rclick_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_rclick"
|
||||
ofType:@"png"]] retain];
|
||||
_scroll_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_scroll"
|
||||
ofType:@"png"]] retain];
|
||||
_extkeyboard_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_ext_keyboard"
|
||||
ofType:@"png"]] retain];
|
||||
_keyboard_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_keyboard"
|
||||
ofType:@"png"]] retain];
|
||||
_reset_pointer_img = [[UIImage
|
||||
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"touch_pointer_reset"
|
||||
ofType:@"png"]] retain];
|
||||
_cur_pointer_img = _default_pointer_img;
|
||||
_pointer_transformation = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
|
||||
|
||||
// init flags
|
||||
_pointer_moving = NO;
|
||||
_pointer_scrolling = NO;
|
||||
|
||||
// create areas array
|
||||
CGFloat area_width = [_cur_pointer_img size].width / 3.0f;
|
||||
CGFloat area_height = [_cur_pointer_img size].height / 3.0f;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
_pointer_areas[j + i * 3] =
|
||||
CGRectMake(j * area_width, i * area_height, area_width, area_height);
|
||||
}
|
||||
}
|
||||
|
||||
// init gesture recognizers
|
||||
UITapGestureRecognizer *singleTapRecognizer =
|
||||
[[[UITapGestureRecognizer alloc] initWithTarget:self
|
||||
action:@selector(handleSingleTap:)] autorelease];
|
||||
[singleTapRecognizer setNumberOfTouchesRequired:1];
|
||||
[singleTapRecognizer setNumberOfTapsRequired:1];
|
||||
|
||||
UILongPressGestureRecognizer *dragDropRecognizer = [[[UILongPressGestureRecognizer alloc]
|
||||
initWithTarget:self
|
||||
action:@selector(handleDragDrop:)] autorelease];
|
||||
dragDropRecognizer.minimumPressDuration = 0.4;
|
||||
// dragDropRecognizer.allowableMovement = 1000.0;
|
||||
|
||||
UILongPressGestureRecognizer *pointerMoveScrollRecognizer =
|
||||
[[[UILongPressGestureRecognizer alloc] initWithTarget:self
|
||||
action:@selector(handlePointerMoveScroll:)]
|
||||
autorelease];
|
||||
pointerMoveScrollRecognizer.minimumPressDuration = 0.15;
|
||||
pointerMoveScrollRecognizer.allowableMovement = 1000.0;
|
||||
[pointerMoveScrollRecognizer requireGestureRecognizerToFail:dragDropRecognizer];
|
||||
|
||||
[self addGestureRecognizer:singleTapRecognizer];
|
||||
[self addGestureRecognizer:dragDropRecognizer];
|
||||
[self addGestureRecognizer:pointerMoveScrollRecognizer];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
[_default_pointer_img autorelease];
|
||||
[_active_pointer_img autorelease];
|
||||
[_lclick_pointer_img autorelease];
|
||||
[_rclick_pointer_img autorelease];
|
||||
[_scroll_pointer_img autorelease];
|
||||
[_extkeyboard_pointer_img autorelease];
|
||||
[_keyboard_pointer_img autorelease];
|
||||
[_reset_pointer_img autorelease];
|
||||
}
|
||||
|
||||
#pragma mark - Public interface
|
||||
|
||||
// positions the pointer on screen if it got offscreen after an orentation change
|
||||
- (void)ensurePointerIsVisible
|
||||
{
|
||||
CGRect bounds = [self bounds];
|
||||
if (_pointer_transformation.tx > (bounds.size.width - _cur_pointer_img.size.width))
|
||||
_pointer_transformation.tx = bounds.size.width - _cur_pointer_img.size.width;
|
||||
if (_pointer_transformation.ty > (bounds.size.height - _cur_pointer_img.size.height))
|
||||
_pointer_transformation.ty = bounds.size.height - _cur_pointer_img.size.height;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
// show/hides the touch pointer
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
[super setHidden:hidden];
|
||||
|
||||
// if shown center pointer in view
|
||||
if (!hidden)
|
||||
{
|
||||
_pointer_transformation = CGAffineTransformMakeTranslation(
|
||||
([self bounds].size.width - [_cur_pointer_img size].width) / 2,
|
||||
([self bounds].size.height - [_cur_pointer_img size].height) / 2);
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIEdgeInsets)getEdgeInsets
|
||||
{
|
||||
return UIEdgeInsetsMake(0, 0, [_cur_pointer_img size].width, [_cur_pointer_img size].height);
|
||||
}
|
||||
|
||||
- (CGPoint)getPointerPosition
|
||||
{
|
||||
return CGPointMake(_pointer_transformation.tx, _pointer_transformation.ty);
|
||||
}
|
||||
|
||||
- (int)getPointerWidth
|
||||
{
|
||||
return [_cur_pointer_img size].width;
|
||||
}
|
||||
|
||||
- (int)getPointerHeight
|
||||
{
|
||||
return [_cur_pointer_img size].height;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation TouchPointerView (Private)
|
||||
|
||||
- (void)setCurrentPointerImage:(UIImage *)image
|
||||
{
|
||||
_cur_pointer_img = image;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)displayPointerActionImage:(UIImage *)image
|
||||
{
|
||||
[self setCurrentPointerImage:image];
|
||||
[self performSelector:@selector(setCurrentPointerImage:)
|
||||
withObject:_default_pointer_img
|
||||
afterDelay:RESET_DEFAULT_POINTER_IMAGE_DELAY];
|
||||
}
|
||||
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, _pointer_transformation);
|
||||
CGContextDrawImage(
|
||||
context, CGRectMake(0, 0, [_cur_pointer_img size].width, [_cur_pointer_img size].height),
|
||||
[_cur_pointer_img CGImage]);
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
// helper that returns YES if the given point is within the pointer
|
||||
- (BOOL)pointInsidePointer:(CGPoint)point
|
||||
{
|
||||
CGRect rec = CGRectMake(0, 0, [_cur_pointer_img size].width, [_cur_pointer_img size].height);
|
||||
return CGRectContainsPoint(CGRectApplyAffineTransform(rec, _pointer_transformation), point);
|
||||
}
|
||||
|
||||
// helper that returns YES if the given point is within the given pointer area
|
||||
- (BOOL)pointInsidePointerArea:(int)area point:(CGPoint)point
|
||||
{
|
||||
CGRect rec = _pointer_areas[area];
|
||||
return CGRectContainsPoint(CGRectApplyAffineTransform(rec, _pointer_transformation), point);
|
||||
}
|
||||
|
||||
// returns the position of the cursor
|
||||
- (CGPoint)getCursorPosition
|
||||
{
|
||||
CGRect transPointerArea =
|
||||
CGRectApplyAffineTransform(_pointer_areas[POINTER_ACTION_CURSOR], _pointer_transformation);
|
||||
return CGPointMake(CGRectGetMidX(transPointerArea), CGRectGetMidY(transPointerArea));
|
||||
}
|
||||
|
||||
// this filters events - if the pointer was clicked the scrollview won't get any events
|
||||
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
return [self pointInsidePointer:point];
|
||||
}
|
||||
|
||||
#pragma mark - Action handlers
|
||||
|
||||
// handles single tap gestures, returns YES if the event was handled by the pointer, NO otherwise
|
||||
- (void)handleSingleTap:(UITapGestureRecognizer *)gesture
|
||||
{
|
||||
// get touch position within our view
|
||||
CGPoint touchPos = [gesture locationInView:self];
|
||||
|
||||
// look if pointer was in one of our action areas
|
||||
if ([self pointInsidePointerArea:POINTER_ACTION_CLOSE point:touchPos])
|
||||
[[self delegate] touchPointerClose];
|
||||
else if ([self pointInsidePointerArea:POINTER_ACTION_LCLICK point:touchPos])
|
||||
{
|
||||
[self displayPointerActionImage:_lclick_pointer_img];
|
||||
[[self delegate] touchPointerLeftClick:[self getCursorPosition] down:YES];
|
||||
[[self delegate] touchPointerLeftClick:[self getCursorPosition] down:NO];
|
||||
}
|
||||
else if ([self pointInsidePointerArea:POINTER_ACTION_RCLICK point:touchPos])
|
||||
{
|
||||
[self displayPointerActionImage:_rclick_pointer_img];
|
||||
[[self delegate] touchPointerRightClick:[self getCursorPosition] down:YES];
|
||||
[[self delegate] touchPointerRightClick:[self getCursorPosition] down:NO];
|
||||
}
|
||||
else if ([self pointInsidePointerArea:POINTER_ACTION_KEYBOARD point:touchPos])
|
||||
{
|
||||
[self displayPointerActionImage:_keyboard_pointer_img];
|
||||
[[self delegate] touchPointerToggleKeyboard];
|
||||
}
|
||||
else if ([self pointInsidePointerArea:POINTER_ACTION_EXTKEYBOARD point:touchPos])
|
||||
{
|
||||
[self displayPointerActionImage:_extkeyboard_pointer_img];
|
||||
[[self delegate] touchPointerToggleExtendedKeyboard];
|
||||
}
|
||||
else if ([self pointInsidePointerArea:POINTER_ACTION_RESET point:touchPos])
|
||||
{
|
||||
[self displayPointerActionImage:_reset_pointer_img];
|
||||
[[self delegate] touchPointerResetSessionView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handlerForGesture:(UIGestureRecognizer *)gesture sendClick:(BOOL)sendClick
|
||||
{
|
||||
if ([gesture state] == UIGestureRecognizerStateBegan)
|
||||
{
|
||||
CGPoint touchPos = [gesture locationInView:self];
|
||||
if ([self pointInsidePointerArea:POINTER_ACTION_LCLICK point:touchPos])
|
||||
{
|
||||
_prev_touch_location = touchPos;
|
||||
_pointer_moving = YES;
|
||||
if (sendClick == YES)
|
||||
{
|
||||
[[self delegate] touchPointerLeftClick:[self getCursorPosition] down:YES];
|
||||
[self setCurrentPointerImage:_active_pointer_img];
|
||||
}
|
||||
}
|
||||
else if ([self pointInsidePointerArea:POINTER_ACTION_SCROLL point:touchPos])
|
||||
{
|
||||
[self setCurrentPointerImage:_scroll_pointer_img];
|
||||
_prev_touch_location = touchPos;
|
||||
_pointer_scrolling = YES;
|
||||
}
|
||||
}
|
||||
else if ([gesture state] == UIGestureRecognizerStateChanged)
|
||||
{
|
||||
if (_pointer_moving)
|
||||
{
|
||||
CGPoint touchPos = [gesture locationInView:self];
|
||||
_pointer_transformation = CGAffineTransformTranslate(
|
||||
_pointer_transformation, touchPos.x - _prev_touch_location.x,
|
||||
touchPos.y - _prev_touch_location.y);
|
||||
[[self delegate] touchPointerMove:[self getCursorPosition]];
|
||||
_prev_touch_location = touchPos;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
else if (_pointer_scrolling)
|
||||
{
|
||||
CGPoint touchPos = [gesture locationInView:self];
|
||||
float delta = touchPos.y - _prev_touch_location.y;
|
||||
if (delta > GetScrollGestureDelta())
|
||||
{
|
||||
[[self delegate] touchPointerScrollDown:YES];
|
||||
_prev_touch_location = touchPos;
|
||||
}
|
||||
else if (delta < -GetScrollGestureDelta())
|
||||
{
|
||||
[[self delegate] touchPointerScrollDown:NO];
|
||||
_prev_touch_location = touchPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ([gesture state] == UIGestureRecognizerStateEnded)
|
||||
{
|
||||
if (_pointer_moving)
|
||||
{
|
||||
if (sendClick == YES)
|
||||
[[self delegate] touchPointerLeftClick:[self getCursorPosition] down:NO];
|
||||
_pointer_moving = NO;
|
||||
[self setCurrentPointerImage:_default_pointer_img];
|
||||
}
|
||||
|
||||
if (_pointer_scrolling)
|
||||
{
|
||||
[self setCurrentPointerImage:_default_pointer_img];
|
||||
_pointer_scrolling = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handles long press gestures
|
||||
- (void)handleDragDrop:(UILongPressGestureRecognizer *)gesture
|
||||
{
|
||||
[self handlerForGesture:gesture sendClick:YES];
|
||||
}
|
||||
|
||||
- (void)handlePointerMoveScroll:(UILongPressGestureRecognizer *)gesture
|
||||
{
|
||||
[self handlerForGesture:gesture sendClick:NO];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user