Skip to content
Browse files

Initial import for new version

  • Loading branch information...
1 parent 1bbf782 commit efc60aa461305c1348c24b566e8d4de2478b7e0b @ccp0101 committed
Showing with 4,115 additions and 0 deletions.
  1. +231 −0 iTransmission/NSLogger/LoggerClient.h
  2. +2,286 −0 iTransmission/NSLogger/LoggerClient.m
  3. +113 −0 iTransmission/NSLogger/LoggerCommon.h
  4. BIN iTransmission/SVSegmentedControl/SVSegmentedControl.bundle/inner-shadow.png
  5. BIN iTransmission/SVSegmentedControl/SVSegmentedControl.bundle/inner-shadow@2x.png
  6. +46 −0 iTransmission/SVSegmentedControl/SVSegmentedControl.h
  7. +433 −0 iTransmission/SVSegmentedControl/SVSegmentedControl.m
  8. +26 −0 iTransmission/SVSegmentedControl/SVSegmentedThumb.h
  9. +230 −0 iTransmission/SVSegmentedControl/SVSegmentedThumb.m
  10. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/action.png
  11. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/back.png
  12. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/forward.png
  13. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/refresh.png
  14. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/stop.png
  15. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/back.png
  16. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/back@2x.png
  17. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/forward.png
  18. BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/forward@2x.png
  19. +33 −0 iTransmission/SVWebViewController/SVWebViewController.h
  20. +460 −0 iTransmission/SVWebViewController/SVWebViewController.m
  21. BIN iTransmission/bar-bg@2x.png
  22. BIN iTransmission/browser-original.png
  23. BIN iTransmission/settings-icon.png
  24. BIN iTransmission/statusbar-bg.png
  25. BIN iTransmission/texture_darkwhite.png
  26. BIN iTransmission/texture_white.png
  27. +257 −0 make_depend/build.sh
View
231 iTransmission/NSLogger/LoggerClient.h
@@ -0,0 +1,231 @@
+/*
+ * LoggerClient.h
+ *
+ * version 1.0 2011-10-30
+ *
+ * Part of NSLogger (client side)
+ * https://github.com/fpillet/NSLogger
+ *
+ * BSD license follows (http://www.opensource.org/licenses/bsd-license.php)
+ *
+ * Copyright (c) 2010-2011 Florent Pillet All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions in
+ * binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution. Neither the name of Florent
+ * Pillet nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#import <unistd.h>
+#import <pthread.h>
+#import <libkern/OSAtomic.h>
+#import <Foundation/Foundation.h>
+#import <CoreFoundation/CoreFoundation.h>
+#import <SystemConfiguration/SystemConfiguration.h>
+#if !TARGET_OS_IPHONE
+#import <CoreServices/CoreServices.h>
+#endif
+
+// This define is here so that user application can test whether NSLogger Client is
+// being included in the project, and potentially configure their macros accordingly
+#define NSLOGGER_WAS_HERE 1
+
+// Set this to 0 if you absolutely NOT want any access to Cocoa (Objective-C, NS* calls)
+// We need a couple ones to reliably obtain the thread number and device information
+// Note that since we need NSAutoreleasePool when using Cocoa in the logger's worker thread,
+// we need to put Cocoa in multithreading mode. Also, ALLOW_COCOA_USE allows the client code
+// to use NSLog()-style message formatting (less verbose than CFShow()-style) through the
+// use of -[NSString stringWithFormat:arguments:]
+#define ALLOW_COCOA_USE 1
+
+/* -----------------------------------------------------------------
+ * Logger option flags & default options
+ * -----------------------------------------------------------------
+ */
+enum {
+ kLoggerOption_LogToConsole = 0x01,
+ kLoggerOption_BufferLogsUntilConnection = 0x02,
+ kLoggerOption_BrowseBonjour = 0x04,
+ kLoggerOption_BrowseOnlyLocalDomain = 0x08,
+ kLoggerOption_UseSSL = 0x10
+};
+
+#define LOGGER_DEFAULT_OPTIONS (kLoggerOption_BufferLogsUntilConnection | \
+ kLoggerOption_BrowseBonjour | \
+ kLoggerOption_BrowseOnlyLocalDomain | \
+ kLoggerOption_UseSSL)
+
+/* -----------------------------------------------------------------
+ * Structure defining a Logger
+ * -----------------------------------------------------------------
+ */
+typedef struct
+{
+ CFStringRef bufferFile; // If non-NULL, all buffering is done to the specified file instead of in-memory
+ CFStringRef host; // Viewer host to connect to (instead of using Bonjour)
+ UInt32 port; // port on the viewer host
+
+ CFMutableArrayRef bonjourServiceBrowsers; // Active service browsers
+ CFMutableArrayRef bonjourServices; // Services being tried
+ CFNetServiceBrowserRef bonjourDomainBrowser; // Domain browser
+
+ CFMutableArrayRef logQueue; // Message queue
+ pthread_mutex_t logQueueMutex;
+ pthread_cond_t logQueueEmpty;
+
+ pthread_t workerThread; // The worker thread responsible for Bonjour resolution, connection and logs transmission
+ CFRunLoopSourceRef messagePushedSource; // A message source that fires on the worker thread when messages are available for send
+ CFRunLoopSourceRef bufferFileChangedSource; // A message source that fires on the worker thread when the buffer file configuration changes
+
+ CFWriteStreamRef logStream; // The connected stream we're writing to
+ CFWriteStreamRef bufferWriteStream; // If bufferFile not NULL and we're not connected, points to a stream for writing log data
+ CFReadStreamRef bufferReadStream; // If bufferFile not NULL, points to a read stream that will be emptied prior to sending the rest of in-memory messages
+
+ SCNetworkReachabilityRef reachability; // The reachability object we use to determine when the target host becomes reachable
+ CFRunLoopTimerRef checkHostTimer; // A timer to regularly check connection to the defined host, along with reachability for added reliability
+
+ uint8_t *sendBuffer; // data waiting to be sent
+ NSUInteger sendBufferSize;
+ NSUInteger sendBufferUsed; // number of bytes of the send buffer currently in use
+ NSUInteger sendBufferOffset; // offset in sendBuffer to start sending at
+
+ int32_t messageSeq; // sequential message number (added to each message sent)
+
+ // settings
+ uint32_t options; // Flags, see enum above
+ CFStringRef bonjourServiceType; // leave NULL to use the default
+ CFStringRef bonjourServiceName; // leave NULL to use the first one available
+
+ // internal state
+ BOOL connected; // Set to YES once the write stream declares the connection open
+ volatile BOOL quit; // Set to YES to terminate the logger worker thread's runloop
+ BOOL incompleteSendOfFirstItem; // set to YES if we are sending the first item in the queue and it's bigger than what the buffer can hold
+} Logger;
+
+
+/* -----------------------------------------------------------------
+ * LOGGING FUNCTIONS
+ * -----------------------------------------------------------------
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Functions to set and get the default logger
+extern void LoggerSetDefaultLogger(Logger *aLogger);
+extern Logger *LoggerGetDefaultLogger(void);
+
+// Initialize a new logger, set as default logger if this is the first one
+// Options default to:
+// - logging to console = NO
+// - buffer until connection = YES
+// - browse Bonjour = YES
+// - browse only locally on Bonjour = YES
+extern Logger* LoggerInit(void);
+
+// Set logger options if you don't want the default options (see above)
+extern void LoggerSetOptions(Logger *logger, uint32_t options);
+
+// Set Bonjour logging names, so you can force the logger to use a specific service type
+// or direct logs to the machine on your network which publishes a specific name
+extern void LoggerSetupBonjour(Logger *logger, CFStringRef bonjourServiceType, CFStringRef bonjourServiceName);
+
+// Directly set the viewer host (hostname or IP address) and port we want to connect to. If set, LoggerStart() will
+// try to connect there first before trying Bonjour
+extern void LoggerSetViewerHost(Logger *logger, CFStringRef hostName, UInt32 port);
+
+
+// Configure the logger to use a local file for buffering, instead of memory.
+// - If you initially set a buffer file after logging started but while a logger connection
+// has not been acquired, the contents of the log queue will be written to the buffer file
+// the next time a logging function is called, or when LoggerStop() is called.
+// - If you want to change the buffering file after logging started, you should first
+// call LoggerStop() the call LoggerSetBufferFile(). Note that all logs stored in the previous
+// buffer file WON'T be transferred to the new file in this case.
+extern void LoggerSetBufferFile(Logger *logger, CFStringRef absolutePath);
+
+// Activate the logger, try connecting
+extern void LoggerStart(Logger *logger);
+
+//extern void LoggerConnectToHost(CFDataRef address, int port);
+
+// Deactivate and free the logger.
+extern void LoggerStop(Logger *logger);
+
+// Pause the current thread until all messages from the logger have been transmitted
+// this is useful to use before an assert() aborts your program. If waitForConnection is YES,
+// LoggerFlush() will block even if the client is not currently connected to the desktop
+// viewer. You should be using NO most of the time, but in some cases it can be useful.
+extern void LoggerFlush(Logger *logger, BOOL waitForConnection);
+
+/* Logging functions. Each function exists in four versions:
+ *
+ * - one without a Logger instance (uses default logger) and without filename/line/function (no F suffix)
+ * - one without a Logger instance but with filename/line/function (F suffix)
+ * - one with a Logger instance (use a specific Logger) and without filename/line/function (no F suffix)
+ * - one with a Logger instance (use a specific Logger) and with filename/line/function (F suffix)
+ *
+ * The exception being the single LogMessageCompat() function which is designed to be a drop-in replacement for NSLog()
+ *
+ */
+
+// Log a message, calling format compatible with NSLog
+extern void LogMessageCompat(NSString *format, ...);
+
+// Log a message. domain can be nil if default domain.
+extern void LogMessage(NSString *domain, int level, NSString *format, ...);
+extern void LogMessageF(const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, NSString *format, ...);
+extern void LogMessageTo(Logger *logger, NSString *domain, int level, NSString *format, ...);
+extern void LogMessageToF(Logger *logger, const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, NSString *format, ...);
+
+// Log a message. domain can be nil if default domain (versions with va_list format args instead of ...)
+extern void LogMessage_va(NSString *domain, int level, NSString *format, va_list args);
+extern void LogMessageF_va(const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, NSString *format, va_list args);
+extern void LogMessageTo_va(Logger *logger, NSString *domain, int level, NSString *format, va_list args);
+extern void LogMessageToF_va(Logger *logger, const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, NSString *format, va_list args);
+
+// Send binary data to remote logger
+extern void LogData(NSString *domain, int level, NSData *data);
+extern void LogDataF(const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, NSData *data);
+extern void LogDataTo(Logger *logger, NSString *domain, int level, NSData *data);
+extern void LogDataToF(Logger *logger, const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, NSData *data);
+
+// Send image data to remote logger
+extern void LogImageData(NSString *domain, int level, int width, int height, NSData *data);
+extern void LogImageDataF(const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, int width, int height, NSData *data);
+extern void LogImageDataTo(Logger *logger, NSString *domain, int level, int width, int height, NSData *data);
+extern void LogImageDataToF(Logger *logger, const char *filename, int lineNumber, const char *functionName, NSString *domain, int level, int width, int height, NSData *data);
+
+// Mark the start of a block. This allows the remote logger to group blocks together
+extern void LogStartBlock(NSString *format, ...);
+extern void LogStartBlockTo(Logger *logger, NSString *format, ...);
+
+// Mark the end of a block
+extern void LogEndBlock(void);
+extern void LogEndBlockTo(Logger *logger);
+
+// Log a marker (text can be null)
+extern void LogMarker(NSString *text);
+extern void LogMarkerTo(Logger *logger, NSString *text);
+
+#ifdef __cplusplus
+};
+#endif
View
2,286 iTransmission/NSLogger/LoggerClient.m
2,286 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
113 iTransmission/NSLogger/LoggerCommon.h
@@ -0,0 +1,113 @@
+/*
+ * LoggerCommon.h
+ *
+ * version 1.0 2011-10-30
+ *
+ * Definitions common to NSLogger Viewer and NSLoggerClient
+ * for the binary messages format
+ * https://github.com/fpillet/NSLogger
+ *
+ * BSD license follows (http://www.opensource.org/licenses/bsd-license.php)
+ *
+ * Copyright (c) 2010-2011 Florent Pillet All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. Redistributions in
+ * binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution. Neither the name of Florent
+ * Pillet nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* NSLogger native binary message format:
+ * Each message is a dictionary encoded in a compact format. All values are stored
+ * in network order (big endian). A message is made of several "parts", which are
+ * typed chunks of data, each with a specific purpose (partKey), data type (partType)
+ * and data size (partSize).
+ *
+ * uint32_t totalSize (total size for the whole message)
+ * uint16_t partCount (number of parts below)
+ * [repeat partCount times]:
+ * uint8_t partKey the part key
+ * uint8_t partType (string, binary, image, int16, int32, int64)
+ * uint32_t partSize (only for string, binary and image types, others are implicit)
+ * .. `partSize' data bytes
+ *
+ * Complete message is usually made of:
+ * - a PART_KEY_MESSAGE_TYPE (mandatory) which contains one of the LOGMSG_TYPE_* values
+ * - a PART_KEY_TIMESTAMP_S (mandatory) which is the timestamp returned by gettimeofday() (seconds from 01.01.1970 00:00)
+ * - a PART_KEY_TIMESTAMP_MS (optional) complement of the timestamp seconds, in milliseconds
+ * - a PART_KEY_TIMESTAMP_US (optional) complement of the timestamp seconds and milliseconds, in microseconds
+ * - a PART_KEY_THREAD_ID (mandatory) the ID of the user thread that produced the log entry
+ * - a PART_KEY_TAG (optional) a tag that helps categorizing and filtering logs from your application, and shows up in viewer logs
+ * - a PART_KEY_LEVEL (optional) a log level that helps filtering logs from your application (see as few or as much detail as you need)
+ * - a PART_KEY_MESSAGE which is the message text, binary data or image
+ * - a PART_KEY_MESSAGE_SEQ which is the message sequence number (message# sent by client)
+ * - a PART_KEY_FILENAME (optional) with the filename from which the log was generated
+ * - a PART_KEY_LINENUMBER (optional) the linenumber in the filename at which the log was generated
+ * - a PART_KEY_FUNCTIONNAME (optional) the function / method / selector from which the log was generated
+ * - if logging an image, PART_KEY_IMAGE_WIDTH and PART_KEY_IMAGE_HEIGHT let the desktop know the image size without having to actually decode it
+ */
+
+// Constants for the "part key" field
+#define PART_KEY_MESSAGE_TYPE 0
+#define PART_KEY_TIMESTAMP_S 1 // "seconds" component of timestamp
+#define PART_KEY_TIMESTAMP_MS 2 // milliseconds component of timestamp (optional, mutually exclusive with PART_KEY_TIMESTAMP_US)
+#define PART_KEY_TIMESTAMP_US 3 // microseconds component of timestamp (optional, mutually exclusive with PART_KEY_TIMESTAMP_MS)
+#define PART_KEY_THREAD_ID 4
+#define PART_KEY_TAG 5
+#define PART_KEY_LEVEL 6
+#define PART_KEY_MESSAGE 7
+#define PART_KEY_IMAGE_WIDTH 8 // messages containing an image should also contain a part with the image size
+#define PART_KEY_IMAGE_HEIGHT 9 // (this is mainly for the desktop viewer to compute the cell size without having to immediately decode the image)
+#define PART_KEY_MESSAGE_SEQ 10 // the sequential number of this message which indicates the order in which messages are generated
+#define PART_KEY_FILENAME 11 // when logging, message can contain a file name
+#define PART_KEY_LINENUMBER 12 // as well as a line number
+#define PART_KEY_FUNCTIONNAME 13 // and a function or method name
+
+// Constants for parts in LOGMSG_TYPE_CLIENTINFO
+#define PART_KEY_CLIENT_NAME 20
+#define PART_KEY_CLIENT_VERSION 21
+#define PART_KEY_OS_NAME 22
+#define PART_KEY_OS_VERSION 23
+#define PART_KEY_CLIENT_MODEL 24 // For iPhone, device model (i.e 'iPhone', 'iPad', etc)
+#define PART_KEY_UNIQUEID 25 // for remote device identification, part of LOGMSG_TYPE_CLIENTINFO
+
+// Area starting at which you may define your own constants
+#define PART_KEY_USER_DEFINED 100
+
+// Constants for the "partType" field
+#define PART_TYPE_STRING 0 // Strings are stored as UTF-8 data
+#define PART_TYPE_BINARY 1 // A block of binary data
+#define PART_TYPE_INT16 2
+#define PART_TYPE_INT32 3
+#define PART_TYPE_INT64 4
+#define PART_TYPE_IMAGE 5 // An image, stored in PNG format
+
+// Data values for the PART_KEY_MESSAGE_TYPE parts
+#define LOGMSG_TYPE_LOG 0 // A standard log message
+#define LOGMSG_TYPE_BLOCKSTART 1 // The start of a "block" (a group of log entries)
+#define LOGMSG_TYPE_BLOCKEND 2 // The end of the last started "block"
+#define LOGMSG_TYPE_CLIENTINFO 3 // Information about the client app
+#define LOGMSG_TYPE_DISCONNECT 4 // Pseudo-message on the desktop side to identify client disconnects
+#define LOGMSG_TYPE_MARK 5 // Pseudo-message that defines a "mark" that users can place in the log flow
+
+// Default Bonjour service identifiers
+#define LOGGER_SERVICE_TYPE_SSL CFSTR("_nslogger-ssl._tcp")
+#define LOGGER_SERVICE_TYPE CFSTR("_nslogger._tcp")
View
BIN iTransmission/SVSegmentedControl/SVSegmentedControl.bundle/inner-shadow.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVSegmentedControl/SVSegmentedControl.bundle/inner-shadow@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
46 iTransmission/SVSegmentedControl/SVSegmentedControl.h
@@ -0,0 +1,46 @@
+//
+// SWSegmentedControl.h
+// SWSegmentedControl
+//
+// Created by Sam Vermette on 26.10.10.
+// Copyright 2010 Sam Vermette. All rights reserved.
+//
+// https://github.com/samvermette/SVSegmentedControl
+//
+
+#import <UIKit/UIKit.h>
+#import "SVSegmentedThumb.h"
+#import <AvailabilityMacros.h>
+
+@protocol SVSegmentedControlDelegate;
+
+@interface SVSegmentedControl : UIControl
+
+@property (nonatomic, assign) id<SVSegmentedControlDelegate> delegate DEPRECATED_ATTRIBUTE; // deprecated: use addTarget:action:forControlEvents: instead
+@property (nonatomic, copy) void (^selectedSegmentChangedHandler)(id sender); // you can also use addTarget:action:forControlEvents:
+
+@property (nonatomic, retain, readonly) SVSegmentedThumb *thumb;
+@property (nonatomic, readwrite) NSUInteger selectedIndex; // default is 0
+@property (nonatomic, readwrite) BOOL animateToInitialSelection; // default is NO
+
+@property (nonatomic, retain) UIImage *backgroundImage; // default is nil
+@property (nonatomic, retain) UIFont *font; // default is [UIFont boldSystemFontOfSize:15]
+@property (nonatomic, retain) UIColor *textColor; // default is [UIColor grayColor];
+@property (nonatomic, retain) UIColor *shadowColor; // default is [UIColor blackColor]
+@property (nonatomic, readwrite) CGSize shadowOffset; // default is CGSizeMake(0, -1)
+@property (nonatomic, readwrite) CGFloat segmentPadding DEPRECATED_ATTRIBUTE; // deprecated: use titleEdgeInsets instead
+@property (nonatomic, readwrite) UIEdgeInsets titleEdgeInsets; // default is UIEdgeInsetsMake(0, 10, 0, 10)
+@property (nonatomic, readwrite) CGFloat height; // default is 32.0
+@property (nonatomic, readwrite) BOOL crossFadeLabelsOnDrag; // default is NO
+
+- (SVSegmentedControl*)initWithSectionTitles:(NSArray*)titlesArray;
+- (void)moveThumbToIndex:(NSUInteger)segmentIndex animate:(BOOL)animate;
+
+@end
+
+
+@protocol SVSegmentedControlDelegate
+
+- (void)segmentedControl:(SVSegmentedControl*)segmentedControl didSelectIndex:(NSUInteger)index;
+
+@end
View
433 iTransmission/SVSegmentedControl/SVSegmentedControl.m
@@ -0,0 +1,433 @@
+//
+// SWSegmentedControl.m
+// SWSegmentedControl
+//
+// Created by Sam Vermette on 26.10.10.
+// Copyright 2010 Sam Vermette. All rights reserved.
+//
+// https://github.com/samvermette/SVSegmentedControl
+
+#import <QuartzCore/QuartzCore.h>
+#import "SVSegmentedControl.h"
+
+#define SVSegmentedControlBG [[UIImage imageNamed:@"SVSegmentedControl.bundle/inner-shadow"] stretchableImageWithLeftCapWidth:4 topCapHeight:5]
+
+
+@interface SVSegmentedThumb ()
+
+@property (nonatomic, assign) SVSegmentedControl *segmentedControl;
+@property (nonatomic, assign) UIFont *font;
+
+@property (nonatomic, readonly) UILabel *label;
+@property (nonatomic, readonly) UILabel *secondLabel;
+
+- (void)activate;
+- (void)deactivate;
+
+@end
+
+
+
+@interface SVSegmentedControl()
+
+- (void)activate;
+- (void)snap:(BOOL)animated;
+- (void)updateTitles;
+- (void)toggle;
+
+@property (nonatomic, retain) NSMutableArray *titlesArray;
+@property (nonatomic, retain) NSMutableArray *thumbRects;
+
+@property (nonatomic, readwrite) NSUInteger snapToIndex;
+@property (nonatomic, readwrite) BOOL trackingThumb;
+@property (nonatomic, readwrite) BOOL moved;
+@property (nonatomic, readwrite) BOOL activated;
+
+@property (nonatomic, readwrite) CGFloat halfSize;
+@property (nonatomic, readwrite) CGFloat dragOffset;
+@property (nonatomic, readwrite) CGFloat segmentWidth;
+@property (nonatomic, readwrite) CGFloat thumbHeight;
+
+@end
+
+
+@implementation SVSegmentedControl
+
+@synthesize delegate, selectedSegmentChangedHandler, selectedIndex, animateToInitialSelection;
+@synthesize backgroundImage, font, textColor, shadowColor, shadowOffset, segmentPadding, titleEdgeInsets, height, crossFadeLabelsOnDrag;
+@synthesize titlesArray, thumb, thumbRects, snapToIndex, trackingThumb, moved, activated, halfSize, dragOffset, segmentWidth, thumbHeight;
+
+#pragma mark -
+#pragma mark Life Cycle
+
+- (void)dealloc {
+
+ self.titlesArray = nil;
+ self.selectedSegmentChangedHandler = nil;
+ self.thumbRects = nil;
+
+ // avoid deprecated warnings
+ [self setValue:nil forKey:@"delegate"];
+
+ self.font = nil;
+ self.textColor = nil;
+ self.shadowColor = nil;
+ self.backgroundImage = nil;
+}
+
+
+- (id)initWithSectionTitles:(NSArray*)array {
+
+ if (self = [super initWithFrame:CGRectZero]) {
+ self.titlesArray = [NSMutableArray arrayWithArray:array];
+ self.thumbRects = [NSMutableArray arrayWithCapacity:[array count]];
+
+ self.backgroundColor = [UIColor clearColor];
+ self.clipsToBounds = YES;
+ self.userInteractionEnabled = YES;
+ self.animateToInitialSelection = NO;
+ self.clipsToBounds = NO;
+
+ self.font = [UIFont boldSystemFontOfSize:15];
+ self.textColor = [UIColor grayColor];
+ self.shadowColor = [UIColor blackColor];
+ self.shadowOffset = CGSizeMake(0, -1);
+
+ self.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10);
+ self.height = 32.0;
+
+ self.selectedIndex = 0;
+ self.thumb.segmentedControl = self;
+ }
+
+ return self;
+}
+
+- (SVSegmentedThumb *)thumb {
+
+ if(thumb == nil)
+ thumb = [[SVSegmentedThumb alloc] initWithFrame:CGRectZero];
+
+ return thumb;
+}
+
+- (void)willMoveToSuperview:(UIView *)newSuperview {
+
+ if(newSuperview == nil)
+ return;
+
+ int c = [self.titlesArray count];
+ int i = 0;
+
+ self.segmentWidth = 0;
+
+ for(NSString *titleString in self.titlesArray) {
+ CGFloat stringWidth = [titleString sizeWithFont:self.font].width+(self.titleEdgeInsets.left+self.titleEdgeInsets.right+4);
+ self.segmentWidth = MAX(stringWidth, self.segmentWidth);
+ }
+
+ self.segmentWidth = ceil((self.segmentWidth*2)/2); // make it an even number so we can position with center
+ self.bounds = CGRectMake(0, 0, self.segmentWidth*c, self.height);
+ self.thumbHeight = self.thumb.backgroundImage ? self.thumb.backgroundImage.size.height : self.height-5;
+
+ i = 0;
+
+ for(NSString *titleString in self.titlesArray) {
+ [self.thumbRects addObject:[NSValue valueWithCGRect:CGRectMake(self.segmentWidth*i+2, 2, self.segmentWidth-4, self.thumbHeight)]];
+ i++;
+ }
+
+ self.thumb.frame = [[self.thumbRects objectAtIndex:0] CGRectValue];
+ self.thumb.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.thumb.bounds cornerRadius:2].CGPath;
+ self.thumb.label.text = [self.titlesArray objectAtIndex:0];
+ self.thumb.font = self.font;
+
+ [self insertSubview:self.thumb atIndex:0];
+
+ BOOL animateInitial = self.animateToInitialSelection;
+
+ if(self.selectedIndex == 0)
+ animateInitial = NO;
+
+ [self moveThumbToIndex:selectedIndex animate:animateInitial];
+}
+
+
+- (void)drawRect:(CGRect)rect {
+
+ CGContextRef context = UIGraphicsGetCurrentContext();
+
+ if(self.backgroundImage)
+ [self.backgroundImage drawInRect:rect];
+
+ else {
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
+
+ CGContextSaveGState(context);
+
+ CGPathRef roundedRect = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:4].CGPath;
+ CGContextAddPath(context, roundedRect);
+ CGContextClip(context);
+
+ // BACKGROUND GRADIENT
+
+ CGFloat components[4] = {
+ 0, 0.55,
+ 0, 0.4
+ };
+
+ CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
+ CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0,CGRectGetHeight(rect)-1), 0);
+ CGGradientRelease(gradient);
+ CGColorSpaceRelease(colorSpace);
+
+ [[[UIImage imageNamed:@"SVSegmentedControl.bundle/inner-shadow"] stretchableImageWithLeftCapWidth:4 topCapHeight:5] drawInRect:rect];
+ }
+
+ CGContextSetShadowWithColor(context, self.shadowOffset, 0, self.shadowColor.CGColor);
+
+ [self.textColor set];
+
+ CGFloat posY = ceil((CGRectGetHeight(rect)-self.font.pointSize+self.font.descender)/2)+self.titleEdgeInsets.top-self.titleEdgeInsets.bottom;
+ int pointSize = self.font.pointSize;
+
+ if(pointSize%2 != 0)
+ posY--;
+
+ int i = 0;
+
+ for(NSString *titleString in self.titlesArray) {
+ [titleString drawInRect:CGRectMake((self.segmentWidth*i), posY, self.segmentWidth, self.font.pointSize) withFont:self.font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];
+ i++;
+ }
+}
+
+#pragma mark -
+#pragma mark Tracking
+
+- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
+ [super beginTrackingWithTouch:touch withEvent:event];
+
+ CGPoint cPos = [touch locationInView:self.thumb];
+ self.activated = NO;
+
+ self.snapToIndex = floor(self.thumb.center.x/self.segmentWidth);
+
+ if(CGRectContainsPoint(self.thumb.bounds, cPos)) {
+ self.trackingThumb = YES;
+ [self.thumb deactivate];
+ self.dragOffset = (self.thumb.frame.size.width/2)-cPos.x;
+ }
+
+ return YES;
+}
+
+- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
+ [super continueTrackingWithTouch:touch withEvent:event];
+
+ CGPoint cPos = [touch locationInView:self];
+ CGFloat newPos = cPos.x+self.dragOffset;
+ CGFloat newMaxX = newPos+(CGRectGetWidth(self.thumb.frame)/2);
+ CGFloat newMinX = newPos-(CGRectGetWidth(self.thumb.frame)/2);
+
+ CGFloat buffer = 2.0; // to prevent the thumb from moving slightly too far
+ CGFloat pMaxX = CGRectGetMaxX(self.bounds) - buffer;
+ CGFloat pMinX = CGRectGetMinX(self.bounds) + buffer;
+
+ if((newMaxX > pMaxX || newMinX < pMinX) && self.trackingThumb) {
+ self.snapToIndex = floor(self.thumb.center.x/self.segmentWidth);
+
+ if(newMaxX-pMaxX > 10 || pMinX-newMinX > 10)
+ self.moved = YES;
+
+ [self snap:NO];
+
+ if (self.crossFadeLabelsOnDrag)
+ [self updateTitles];
+ }
+
+ else if(self.trackingThumb) {
+ self.thumb.center = CGPointMake(cPos.x+self.dragOffset, self.thumb.center.y);
+ self.moved = YES;
+
+ if (self.crossFadeLabelsOnDrag)
+ [self updateTitles];
+ }
+
+ return YES;
+}
+
+- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
+ [super endTrackingWithTouch:touch withEvent:event];
+
+ CGPoint cPos = [touch locationInView:self];
+ CGFloat pMaxX = CGRectGetMaxX(self.bounds);
+ CGFloat pMinX = CGRectGetMinX(self.bounds);
+
+ if(!self.moved && self.trackingThumb && [self.titlesArray count] == 2)
+ [self toggle];
+
+ else if(!self.activated && cPos.x > pMinX && cPos.x < pMaxX) {
+ self.snapToIndex = floor(cPos.x/self.segmentWidth);
+ [self snap:YES];
+ }
+
+ else {
+ CGFloat posX = cPos.x;
+
+ if(posX < pMinX)
+ posX = pMinX;
+
+ if(posX > pMaxX)
+ posX = pMaxX-1;
+
+ self.snapToIndex = floor(posX/self.segmentWidth);
+ [self snap:YES];
+ }
+}
+
+- (void)cancelTrackingWithEvent:(UIEvent *)event {
+ [super cancelTrackingWithEvent:event];
+
+ if(self.trackingThumb)
+ [self snap:NO];
+}
+
+#pragma mark -
+
+- (void)snap:(BOOL)animated {
+
+ [self.thumb deactivate];
+
+ if(self.crossFadeLabelsOnDrag)
+ self.thumb.secondLabel.alpha = 0;
+
+ int index;
+
+ if(self.snapToIndex != -1)
+ index = self.snapToIndex;
+ else
+ index = floor(self.thumb.center.x/self.segmentWidth);
+
+ self.thumb.label.text = [self.titlesArray objectAtIndex:index];
+
+ if(animated)
+ [self moveThumbToIndex:index animate:YES];
+ else
+ self.thumb.frame = [[self.thumbRects objectAtIndex:index] CGRectValue];
+}
+
+- (void)updateTitles {
+ int hoverIndex = floor(self.thumb.center.x/self.segmentWidth);
+
+ BOOL secondTitleOnLeft = ((self.thumb.center.x / self.segmentWidth) - hoverIndex) < 0.5;
+
+ if (secondTitleOnLeft && hoverIndex > 0) {
+ self.thumb.label.alpha = 0.5 + ((self.thumb.center.x / self.segmentWidth) - hoverIndex);
+ self.thumb.secondLabel.text = [self.titlesArray objectAtIndex:hoverIndex - 1];
+ self.thumb.secondLabel.alpha = 0.5 - ((self.thumb.center.x / self.segmentWidth) - hoverIndex);
+ }
+
+ else if (hoverIndex + 1 < self.titlesArray.count) {
+ self.thumb.label.alpha = 0.5 + (1 - ((self.thumb.center.x / self.segmentWidth) - hoverIndex));
+ self.thumb.secondLabel.text = [self.titlesArray objectAtIndex:hoverIndex + 1];
+ self.thumb.secondLabel.alpha = ((self.thumb.center.x / self.segmentWidth) - hoverIndex) - 0.5;
+ }
+
+ else {
+ self.thumb.secondLabel.text = nil;
+ self.thumb.label.alpha = 1.0;
+ }
+
+ self.thumb.label.text = [self.titlesArray objectAtIndex:hoverIndex];
+}
+
+- (void)activate {
+
+ self.trackingThumb = self.moved = NO;
+
+ self.thumb.label.text = [self.titlesArray objectAtIndex:self.selectedIndex];
+
+ if(self.selectedSegmentChangedHandler)
+ self.selectedSegmentChangedHandler(self);
+
+ if([self valueForKey:@"delegate"]) {
+ id controlDelegate = [self valueForKey:@"delegate"];
+
+ if([controlDelegate respondsToSelector:@selector(segmentedControl:didSelectIndex:)])
+ [controlDelegate segmentedControl:self didSelectIndex:selectedIndex];
+ }
+
+ [UIView animateWithDuration:0.1
+ delay:0
+ options:UIViewAnimationOptionAllowUserInteraction
+ animations:^{
+ self.activated = YES;
+ [self.thumb activate];
+ }
+ completion:NULL];
+}
+
+
+- (void)toggle {
+
+ if(self.snapToIndex == 0)
+ self.snapToIndex = 1;
+ else
+ self.snapToIndex = 0;
+
+ [self snap:YES];
+}
+
+- (void)moveThumbToIndex:(NSUInteger)segmentIndex animate:(BOOL)animate {
+
+ self.selectedIndex = segmentIndex;
+ [self sendActionsForControlEvents:UIControlEventValueChanged];
+
+ if(animate) {
+
+ [self.thumb deactivate];
+
+ [UIView animateWithDuration:0.2
+ delay:0
+ options:UIViewAnimationOptionCurveEaseOut
+ animations:^{
+ self.thumb.frame = [[self.thumbRects objectAtIndex:segmentIndex] CGRectValue];
+
+ if(self.crossFadeLabelsOnDrag)
+ [self updateTitles];
+ }
+ completion:^(BOOL finished){
+ [self activate];
+ }];
+ }
+
+ else {
+ self.thumb.frame = [[self.thumbRects objectAtIndex:segmentIndex] CGRectValue];
+ [self activate];
+ }
+}
+
+#pragma mark -
+
+- (void)setBackgroundImage:(UIImage *)newImage {
+
+ if(backgroundImage)
+ backgroundImage = nil;
+
+ if(newImage) {
+ backgroundImage = newImage;
+ self.height = backgroundImage.size.height;
+ }
+}
+
+- (void)setSegmentPadding:(CGFloat)newPadding {
+ // deprecated; this method is provided for backward compatibility
+ // use titleEdgeInsets instead
+
+ self.titleEdgeInsets = UIEdgeInsetsMake(0, newPadding, 0, newPadding);
+}
+
+
+
+@end
View
26 iTransmission/SVSegmentedControl/SVSegmentedThumb.h
@@ -0,0 +1,26 @@
+//
+// SVSegmentedThumb.h
+// SVSegmentedControl
+//
+// Created by Sam Vermette on 25.05.11.
+// Copyright 2011 Sam Vermette. All rights reserved.
+//
+// https://github.com/samvermette/SVSegmentedControl
+//
+
+#import <UIKit/UIKit.h>
+
+@class SVSegmentedControl;
+
+@interface SVSegmentedThumb : UIView
+
+@property (nonatomic, retain) UIImage *backgroundImage; // default is nil;
+@property (nonatomic, retain) UIImage *highlightedBackgroundImage; // default is nil;
+
+@property (nonatomic, strong) UIColor *tintColor; // default is [UIColor grayColor]
+@property (nonatomic, strong) UIColor *textColor; // default is [UIColor whiteColor]
+@property (nonatomic, strong) UIColor *shadowColor; // default is [UIColor blackColor]
+@property (nonatomic, readwrite) CGSize shadowOffset; // default is CGSizeMake(0, -1)
+@property (nonatomic, readwrite) BOOL castsShadow; // default is YES
+
+@end
View
230 iTransmission/SVSegmentedControl/SVSegmentedThumb.m
@@ -0,0 +1,230 @@
+//
+// SVSegmentedThumb.m
+// SVSegmentedControl
+//
+// Created by Sam Vermette on 25.05.11.
+// Copyright 2011 Sam Vermette. All rights reserved.
+//
+// https://github.com/samvermette/SVSegmentedControl
+//
+
+#import "SVSegmentedThumb.h"
+#import <QuartzCore/QuartzCore.h>
+#import "SVSegmentedControl.h"
+
+@interface SVSegmentedThumb ()
+
+@property (nonatomic, readwrite) BOOL selected;
+@property (nonatomic, assign) SVSegmentedControl *segmentedControl;
+@property (nonatomic, assign) UIFont *font;
+
+@property (nonatomic, strong) UILabel *label;
+@property (nonatomic, strong) UILabel *secondLabel;
+
+- (void)activate;
+- (void)deactivate;
+
+@end
+
+
+@implementation SVSegmentedThumb
+
+@synthesize segmentedControl, backgroundImage, highlightedBackgroundImage, castsShadow, font, tintColor, textColor, shadowColor, shadowOffset, selected;
+@synthesize label, secondLabel;
+
+- (void)dealloc {
+
+ self.backgroundImage = nil;
+ self.highlightedBackgroundImage = nil;
+}
+
+
+- (id)initWithFrame:(CGRect)frame {
+
+ self = [super initWithFrame:frame];
+
+ if (self) {
+ self.userInteractionEnabled = NO;
+ self.backgroundColor = [UIColor clearColor];
+ self.layer.shadowOffset = CGSizeMake(0, 0);
+ self.layer.shadowRadius = 1;
+ self.layer.shadowColor = [UIColor blackColor].CGColor;
+ self.layer.shadowOpacity = 1;
+ self.layer.shouldRasterize = YES;
+
+ self.textColor = [UIColor whiteColor];
+ self.shadowColor = [UIColor blackColor];
+ self.shadowOffset = CGSizeMake(0, -1);
+ self.tintColor = [UIColor grayColor];
+ }
+
+ return self;
+}
+
+- (UILabel*)label {
+
+ if(label == nil) {
+ label = [[UILabel alloc] initWithFrame:self.bounds];
+ label.textAlignment = UITextAlignmentCenter;
+ label.font = self.font;
+ label.backgroundColor = [UIColor clearColor];
+ [self addSubview:label];
+ }
+
+ return label;
+}
+
+- (UILabel*)secondLabel {
+
+ if(secondLabel == nil) {
+ secondLabel = [[UILabel alloc] initWithFrame:self.bounds];
+ secondLabel.textAlignment = UITextAlignmentCenter;
+ secondLabel.font = self.font;
+ secondLabel.backgroundColor = [UIColor clearColor];
+ [self addSubview:secondLabel];
+ }
+
+ return secondLabel;
+}
+
+
+- (void)drawRect:(CGRect)rect {
+
+ if(self.backgroundImage && !self.selected)
+ [self.backgroundImage drawInRect:rect];
+
+ else if(self.highlightedBackgroundImage && self.selected)
+ [self.highlightedBackgroundImage drawInRect:rect];
+
+ else {
+
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
+
+ // STROKE GRADIENT
+
+ CGPathRef strokeRect = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:2].CGPath;
+ CGContextAddPath(context, strokeRect);
+ CGContextClip(context);
+
+ CGContextSaveGState(context);
+
+ CGFloat strokeComponents[4] = {
+ 0.55, 1,
+ 0.40, 1
+ };
+
+ if(self.selected) {
+ strokeComponents[0]-=0.1;
+ strokeComponents[2]-=0.1;
+ }
+
+ CGGradientRef strokeGradient = CGGradientCreateWithColorComponents(colorSpace, strokeComponents, NULL, 2);
+ CGContextDrawLinearGradient(context, strokeGradient, CGPointMake(0,0), CGPointMake(0,CGRectGetHeight(rect)), 0);
+ CGGradientRelease(strokeGradient);
+
+
+ // FILL GRADIENT
+
+ CGPathRef fillRect = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, 1, 1) cornerRadius:1].CGPath;
+ CGContextAddPath(context, fillRect);
+ CGContextClip(context);
+
+ CGFloat fillComponents[4] = {
+ 0.5, 1,
+ 0.35, 1
+ };
+
+ if(self.selected) {
+ fillComponents[0]-=0.1;
+ fillComponents[2]-=0.1;
+ }
+
+ CGGradientRef fillGradient = CGGradientCreateWithColorComponents(colorSpace, fillComponents, NULL, 2);
+ CGContextDrawLinearGradient(context, fillGradient, CGPointMake(0,0), CGPointMake(0,CGRectGetHeight(rect)), 0);
+ CGGradientRelease(fillGradient);
+
+ CGColorSpaceRelease(colorSpace);
+
+ CGContextRestoreGState(context);
+ [self.tintColor set];
+ UIRectFillUsingBlendMode(rect, kCGBlendModeOverlay);
+ }
+}
+
+
+#pragma mark -
+#pragma mark Setters
+
+
+- (void)setTintColor:(UIColor *)newColor {
+
+ if(tintColor)
+ tintColor = nil;
+
+ if(newColor)
+ tintColor = newColor;
+
+ [self setNeedsDisplay];
+}
+
+- (void)setFont:(UIFont *)newFont {
+ self.label.font = self.secondLabel.font = newFont;
+}
+
+- (void)setTextColor:(UIColor *)newColor {
+ self.label.textColor = self.secondLabel.textColor = newColor;
+}
+
+- (void)setShadowColor:(UIColor *)newColor {
+ self.label.shadowColor = self.secondLabel.shadowColor = newColor;
+}
+
+- (void)setShadowOffset:(CGSize)newOffset {
+ self.label.shadowOffset = self.secondLabel.shadowOffset = newOffset;
+}
+
+
+#pragma mark -
+
+- (void)setFrame:(CGRect)newFrame {
+ [super setFrame:newFrame];
+
+ newFrame.size.height = self.segmentedControl.height-5;
+ self.label.frame = self.secondLabel.frame = CGRectMake(0, 0+self.segmentedControl.titleEdgeInsets.top-self.segmentedControl.titleEdgeInsets.bottom, newFrame.size.width, newFrame.size.height);
+}
+
+
+- (void)setCastsShadow:(BOOL)b {
+ self.layer.shadowOpacity = b ? 1 : 0;
+}
+
+
+- (void)setSelected:(BOOL)s {
+
+ selected = s;
+
+ if(selected && !self.segmentedControl.crossFadeLabelsOnDrag && !self.highlightedBackgroundImage)
+ self.alpha = 0.8;
+ else
+ self.alpha = 1;
+
+ [self setNeedsDisplay];
+}
+
+- (void)activate {
+ [self setSelected:NO];
+
+ if(!self.segmentedControl.crossFadeLabelsOnDrag)
+ self.label.alpha = 1;
+}
+
+- (void)deactivate {
+ [self setSelected:YES];
+
+ if(!self.segmentedControl.crossFadeLabelsOnDrag)
+ self.label.alpha = 0;
+}
+
+
+@end
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/action.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/back.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/forward.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/refresh.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPad/stop.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/back.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/back@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/forward.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/SVWebViewController/SVWebViewController.bundle/iPhone/forward@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
33 iTransmission/SVWebViewController/SVWebViewController.h
@@ -0,0 +1,33 @@
+//
+// SVWebViewController.h
+//
+// Created by Sam Vermette on 08.11.10.
+// Copyright 2010 Sam Vermette. All rights reserved.
+//
+
+#import <MessageUI/MessageUI.h>
+
+
+@interface SVWebViewController : UIViewController <UIWebViewDelegate, UIActionSheetDelegate, MFMailComposeViewControllerDelegate> {
+ UIWebView *rWebView;
+ UINavigationBar *navBar;
+ UIToolbar *toolbar;
+
+ // iPhone UI
+ UINavigationItem *navItem;
+ UIBarButtonItem *backBarButton, *forwardBarButton, *refreshStopBarButton, *actionBarButton;
+
+ // iPad UI
+ UIButton *backButton, *forwardButton, *refreshStopButton, *actionButton;
+ UILabel *titleLabel;
+ CGFloat titleLeftOffset;
+
+ BOOL deviceIsTablet, stoppedLoading;
+}
+
+@property (nonatomic, retain) UIWebView *webView;
+@property (nonatomic, retain) NSString *urlString;
+
+- (SVWebViewController*)initWithAddress:(NSString*)string;
+
+@end
View
460 iTransmission/SVWebViewController/SVWebViewController.m
@@ -0,0 +1,460 @@
+//
+// SVWebViewController.m
+//
+// Created by Sam Vermette on 08.11.10.
+// Copyright 2010 Sam Vermette. All rights reserved.
+//
+
+#import "SVWebViewController.h"
+
+@interface SVWebViewController (private)
+
+- (void)layoutSubviews;
+- (void)setupToolbar;
+- (void)setupTabletToolbar;
+- (void)stopLoading;
+
+@end
+
+@implementation SVWebViewController
+
+@synthesize webView = rWebView;
+@synthesize urlString;
+
+- (SVWebViewController*)initWithAddress:(NSString*)string {
+
+ self = [super initWithNibName:nil bundle:[NSBundle mainBundle]];
+
+ self.urlString = string;
+
+ if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
+ deviceIsTablet = YES;
+
+ return self;
+}
+
+- (void)viewDidLoad {
+
+ [super viewDidLoad];
+
+ CGRect deviceBounds = [[UIApplication sharedApplication] keyWindow].bounds;
+
+ if(!deviceIsTablet) {
+
+ backBarButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPhone/back"] style:UIBarButtonItemStylePlain target:self.webView action:@selector(goBack)];
+ backBarButton.imageInsets = UIEdgeInsetsMake(2, 0, -2, 0);
+ backBarButton.width = 18;
+
+ forwardBarButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPhone/forward"] style:UIBarButtonItemStylePlain target:self.webView action:@selector(goForward)];
+ forwardBarButton.imageInsets = UIEdgeInsetsMake(2, 0, -2, 0);
+ forwardBarButton.width = 18;
+
+ actionBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(showActions)];
+
+ if(self.navigationController == nil) {
+
+ navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,CGRectGetWidth(deviceBounds),44)];
+ navBar.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleBottomMargin;
+ [self.view addSubview:navBar];
+
+ navItem = [[UINavigationItem alloc] initWithTitle:self.title];
+ [navBar setItems:[NSArray arrayWithObject:navItem] animated:YES];
+
+ toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.view.bounds)-44, CGRectGetWidth(deviceBounds), 44)];
+ toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleWidth;
+ [self.view addSubview:toolbar];
+ }
+
+ else {
+ navBar = self.navigationController.navigationBar;
+ toolbar = self.navigationController.toolbar;
+ }
+ }
+
+ else {
+
+ if(self.navigationController == nil) {
+
+ navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,CGRectGetWidth(deviceBounds),44)];
+ navBar.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleBottomMargin;
+ [self.view addSubview:navBar];
+
+ UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissController)];
+
+ navItem = [[UINavigationItem alloc] initWithTitle:nil];
+ navItem.leftBarButtonItem = doneButton;
+
+ [navBar setItems:[NSArray arrayWithObject:navItem] animated:YES];
+
+ titleLeftOffset = [@"Done" sizeWithFont:[UIFont boldSystemFontOfSize:12]].width+33;
+ }
+
+ else {
+ self.hidesBottomBarWhenPushed = YES;
+ self.title = nil;
+
+ navBar = self.navigationController.navigationBar;
+ navBar.autoresizesSubviews = YES;
+
+ NSArray* viewCtrlers = self.navigationController.viewControllers;
+ UIViewController* prevCtrler = [viewCtrlers objectAtIndex:[viewCtrlers count]-2];
+ titleLeftOffset = [prevCtrler.navigationItem.backBarButtonItem.title sizeWithFont:[UIFont boldSystemFontOfSize:12]].width+26;
+ }
+
+ backButton = [UIButton buttonWithType:UIButtonTypeCustom];
+ [backButton setBackgroundImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPad/back"] forState:UIControlStateNormal];
+ backButton.frame = CGRectZero;
+ [backButton addTarget:self.webView action:@selector(goBack) forControlEvents:UIControlEventTouchUpInside];
+ backButton.adjustsImageWhenHighlighted = NO;
+ backButton.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
+ backButton.showsTouchWhenHighlighted = YES;
+
+ forwardButton = [UIButton buttonWithType:UIButtonTypeCustom];
+ [forwardButton setBackgroundImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPad/forward"] forState:UIControlStateNormal];
+ forwardButton.frame = CGRectZero;
+ [forwardButton addTarget:self.webView action:@selector(goForward) forControlEvents:UIControlEventTouchUpInside];
+ forwardButton.adjustsImageWhenHighlighted = NO;
+ forwardButton.showsTouchWhenHighlighted = YES;
+
+ actionButton = [UIButton buttonWithType:UIButtonTypeCustom];
+ [actionButton setBackgroundImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPad/action"] forState:UIControlStateNormal];
+ actionButton.frame = CGRectZero;
+ [actionButton addTarget:self action:@selector(showActions) forControlEvents:UIControlEventTouchUpInside];
+ actionButton.adjustsImageWhenHighlighted = NO;
+ actionButton.showsTouchWhenHighlighted = YES;
+
+ refreshStopButton = [UIButton buttonWithType:UIButtonTypeCustom];
+ [refreshStopButton setBackgroundImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPad/refresh"] forState:UIControlStateNormal];
+ refreshStopButton.frame = CGRectZero;
+ refreshStopButton.adjustsImageWhenHighlighted = NO;
+ refreshStopButton.showsTouchWhenHighlighted = YES;
+
+ titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
+ titleLabel.font = [UIFont boldSystemFontOfSize:20];
+ titleLabel.textColor = [UIColor colorWithRed:0.42353 green:0.45098 blue:0.48235 alpha:1.];
+ titleLabel.shadowColor = [UIColor colorWithWhite:1 alpha:0.7];
+ titleLabel.backgroundColor = [UIColor clearColor];
+ titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
+ titleLabel.textAlignment = UITextAlignmentRight;
+ titleLabel.shadowOffset = CGSizeMake(0, 1);
+
+ [navBar addSubview:titleLabel];
+
+ [navBar addSubview:refreshStopButton];
+ [navBar addSubview:backButton];
+ [navBar addSubview:forwardButton];
+ [navBar addSubview:actionButton];
+ }
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:YES];
+
+ if(!deviceIsTablet)
+ [self.navigationController setToolbarHidden:NO animated:YES];
+
+ [self setupToolbar];
+ [self layoutSubviews];
+
+
+ if(self.modalViewController)
+ return;
+
+ if (self.urlString) {
+ NSURL *searchURL = [NSURL URLWithString:self.urlString];
+ [self.webView loadRequest:[NSURLRequest requestWithURL:searchURL]];
+ }
+
+ if(deviceIsTablet && self.navigationController) {
+ titleLabel.alpha = 0;
+ refreshStopButton.alpha = 0;
+ backButton.alpha = 0;
+ forwardButton.alpha = 0;
+ actionButton.alpha = 0;
+
+ [UIView animateWithDuration:0.3 animations:^{
+ titleLabel.alpha = 1;
+ refreshStopButton.alpha = 1;
+ backButton.alpha = 1;
+ forwardButton.alpha = 1;
+ actionButton.alpha = 1;
+ }];
+ }
+}
+
+
+- (void)viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+
+ if(self.modalViewController)
+ return;
+
+ [self.navigationController setToolbarHidden:YES animated:YES];
+
+ if(deviceIsTablet && self.navigationController) {
+ [UIView animateWithDuration:0.3 animations:^{
+ titleLabel.alpha = 0;
+ refreshStopButton.alpha = 0;
+ backButton.alpha = 0;
+ forwardButton.alpha = 0;
+ actionButton.alpha = 0;
+ }];
+ }
+}
+
+
+- (void)viewDidDisappear:(BOOL)animated {
+ [super viewDidDisappear:animated];
+
+ if(self.modalViewController)
+ return;
+
+ [self stopLoading];
+ [self.webView removeFromSuperview];
+ self.webView.delegate = nil;
+ self.webView = nil;
+}
+
+
+#pragma mark -
+#pragma mark Layout Methods
+
+- (void)layoutSubviews {
+ CGRect deviceBounds = self.view.bounds;
+
+ if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation) && !deviceIsTablet && !self.navigationController) {
+ navBar.frame = CGRectMake(0, 0, CGRectGetWidth(deviceBounds), 32);
+ toolbar.frame = CGRectMake(0, CGRectGetHeight(deviceBounds)-32, CGRectGetWidth(deviceBounds), 32);
+ } else if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation) && !deviceIsTablet && !self.navigationController) {
+ navBar.frame = CGRectMake(0, 0, CGRectGetWidth(deviceBounds), 44);
+ toolbar.frame = CGRectMake(0, CGRectGetHeight(deviceBounds)-44, CGRectGetWidth(deviceBounds), 44);
+ }
+
+ if(self.navigationController && deviceIsTablet)
+ self.webView.frame = CGRectMake(0, 0, CGRectGetWidth(deviceBounds), CGRectGetHeight(deviceBounds));
+ else if(deviceIsTablet)
+ self.webView.frame = CGRectMake(0, CGRectGetMaxY(navBar.frame), CGRectGetWidth(deviceBounds), CGRectGetHeight(deviceBounds)-CGRectGetMaxY(navBar.frame));
+ else if(self.navigationController && !deviceIsTablet)
+ self.webView.frame = CGRectMake(0, 0, CGRectGetWidth(deviceBounds), CGRectGetMaxY(self.view.bounds));
+ else if(!deviceIsTablet)
+ self.webView.frame = CGRectMake(0, CGRectGetMaxY(navBar.frame), CGRectGetWidth(deviceBounds), CGRectGetMinY(toolbar.frame)-CGRectGetMaxY(navBar.frame));
+
+ backButton.frame = CGRectMake(CGRectGetWidth(deviceBounds)-180, 0, 44, 44);
+ forwardButton.frame = CGRectMake(CGRectGetWidth(deviceBounds)-120, 0, 44, 44);
+ actionButton.frame = CGRectMake(CGRectGetWidth(deviceBounds)-60, 0, 44, 44);
+ refreshStopButton.frame = CGRectMake(CGRectGetWidth(deviceBounds)-240, 0, 44, 44);
+ titleLabel.frame = CGRectMake(titleLeftOffset, 0, CGRectGetWidth(deviceBounds)-240-titleLeftOffset-5, 44);
+}
+
+
+- (void)setupToolbar {
+
+ if(!navItem.leftBarButtonItem) {
+ UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissController)];
+ [navItem setLeftBarButtonItem:doneButton animated:YES];
+ }
+
+ if(self.navigationController != nil)
+ self.navigationItem.title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];
+ else
+ navItem.title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];
+
+ if(![self.webView canGoBack])
+ backBarButton.enabled = NO;
+ else
+ backBarButton.enabled = YES;
+
+ if(![self.webView canGoForward])
+ forwardBarButton.enabled = NO;
+ else
+ forwardBarButton.enabled = YES;
+
+ if(self.webView.loading && !stoppedLoading)
+ refreshStopBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(stopLoading)];
+
+ else
+ refreshStopBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self.webView action:@selector(reload)];
+
+ UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
+
+ UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
+ fixedSpace.width = 5;
+
+ NSURLRequest *req = self.webView.request;
+
+ if(req && ![req.URL.absoluteString isEqualToString:@""] && [req.URL.absoluteString rangeOfString:@".app"].location == NSNotFound)
+ actionBarButton.enabled = YES;
+ else
+ actionBarButton.enabled = NO;
+
+ NSArray *newButtons = [NSArray arrayWithObjects:fixedSpace, backBarButton, flexSpace, forwardBarButton, flexSpace, refreshStopBarButton, flexSpace, actionBarButton, fixedSpace, nil];
+ [toolbar setItems:newButtons];
+ [toolbar sizeToFit];
+}
+
+
+- (void)setupTabletToolbar {
+
+ titleLabel.text = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];
+
+ if(![self.webView canGoBack])
+ backButton.enabled = NO;
+ else
+ backButton.enabled = YES;
+
+ if(![self.webView canGoForward])
+ forwardButton.enabled = NO;
+ else
+ forwardButton.enabled = YES;
+
+ if(self.webView.loading && !stoppedLoading) {
+ [refreshStopButton removeTarget:self.webView action:@selector(reload) forControlEvents:UIControlEventTouchUpInside];
+ [refreshStopButton addTarget:self action:@selector(stopLoading) forControlEvents:UIControlEventTouchUpInside];
+ [refreshStopButton setBackgroundImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPad/stop"] forState:UIControlStateNormal];
+ }
+
+ else {
+ [refreshStopButton removeTarget:self action:@selector(stopLoading) forControlEvents:UIControlEventTouchUpInside];
+ [refreshStopButton addTarget:self.webView action:@selector(reload) forControlEvents:UIControlEventTouchUpInside];
+ [refreshStopButton setBackgroundImage:[UIImage imageNamed:@"SVWebViewController.bundle/iPad/refresh"] forState:UIControlStateNormal];
+ }
+}
+
+
+#pragma mark -
+#pragma mark Orientation Support
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+
+ return YES;
+}
+
+- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
+ [self layoutSubviews];
+}
+
+
+#pragma mark -
+#pragma mark UIWebViewDelegate
+
+- (UIWebView*) webView {
+
+ if (!rWebView) {
+ rWebView = [[UIWebView alloc] initWithFrame:self.view.bounds];
+ rWebView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleBottomMargin;
+ rWebView.delegate = self;
+ rWebView.scalesPageToFit = YES;
+ [self.view addSubview:rWebView];
+ }
+
+ return rWebView;
+}
+
+
+- (void)webViewDidStartLoad:(UIWebView *)webView {
+
+ stoppedLoading = NO;
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
+
+ if(!deviceIsTablet)
+ [self setupToolbar];
+ else
+ [self setupTabletToolbar];
+}
+
+
+- (void)webViewDidFinishLoad:(UIWebView *)webView {
+
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
+
+ if(!deviceIsTablet)
+ [self setupToolbar];
+ else
+ [self setupTabletToolbar];
+}
+
+- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
+
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
+}
+
+
+#pragma mark -
+#pragma mark Action Methods
+
+- (void)stopLoading {
+
+ stoppedLoading = YES;
+ [self.webView stopLoading];
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
+
+ if(!deviceIsTablet)
+ [self setupToolbar];
+ else
+ [self setupTabletToolbar];
+}
+
+- (void)showActions {
+
+ UIActionSheet *actionSheet = [[UIActionSheet alloc]
+ initWithTitle: nil
+ delegate: self
+ cancelButtonTitle: nil
+ destructiveButtonTitle: nil
+ otherButtonTitles: NSLocalizedString(@"Open in Safari", @"SVWebViewController"), nil];
+
+
+ if([MFMailComposeViewController canSendMail])
+ [actionSheet addButtonWithTitle:NSLocalizedString(@"Mail Link to this Page", @"SVWebViewController")];
+
+ [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel",@"SVWebViewController")];
+ actionSheet.cancelButtonIndex = [actionSheet numberOfButtons]-1;
+
+ if(!deviceIsTablet)
+ [actionSheet showFromToolbar:toolbar];
+ else if(!self.navigationController)
+ [actionSheet showFromRect:CGRectOffset(actionButton.frame, 0, -5) inView:self.view animated:YES];
+ else if(self.navigationController)
+ [actionSheet showFromRect:CGRectOffset(actionButton.frame, 0, -49) inView:self.view animated:YES];
+
+}
+
+
+- (void)dismissController {
+ [self dismissModalViewControllerAnimated:YES];
+}
+
+#pragma mark -
+#pragma mark UIActionSheetDelegate
+
+- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
+
+ if([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:NSLocalizedString(@"Open in Safari", @"SVWebViewController")])
+ [[UIApplication sharedApplication] openURL:self.webView.request.URL];
+
+ else if([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:NSLocalizedString(@"Mail Link to this Page", @"SVWebViewController")]) {
+
+ MFMailComposeViewController *emailComposer = [[MFMailComposeViewController alloc] init];
+
+ [emailComposer setMailComposeDelegate: self];
+ NSString *title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];
+ [emailComposer setSubject:title];
+
+ [emailComposer setMessageBody:self.webView.request.URL.absoluteString isHTML:NO];
+
+ emailComposer.modalPresentationStyle = UIModalPresentationFormSheet;
+
+ [self presentModalViewController:emailComposer animated:YES];
+ }
+
+}
+
+#pragma mark -
+#pragma mark MFMailComposeViewControllerDelegate
+
+- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
+ [controller dismissModalViewControllerAnimated:YES];
+}
+
+
+@end
View
BIN iTransmission/bar-bg@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/browser-original.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/settings-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/statusbar-bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/texture_darkwhite.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN iTransmission/texture_white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
257 make_depend/build.sh
@@ -0,0 +1,257 @@
+#!/bin/bash
+
+#########################
+ARCH="armv7"
+SDK_VERSION="5.0"
+PARALLEL_NUM=1
+#########################
+
+PKG_CONFIG_VERSION=0.25 # DO NOT USE 0.26 which has broken dependency on glib
+CURL_VERSION=7.21.5
+LIBEVENT_VERSION="2.0.15-stable"
+ZLIB_VERSION=1.2.5
+OPENSSL_VERSION=1.0.0e
+TRANSMISSION_VERSION=2.41
+
+export BUILD_DIR="$PWD/out/${ARCH}"
+
+if [ ${ARCH} = "i386" ]
+ then
+ PLATFORM="iPhoneSimulator"
+elif [ ${ARCH} = "armv7" ]
+ then
+ PLATFORM="iPhoneOS"
+elif [ ${ARCH} = "armv6" ]
+ then
+ PLATFORM="iPhoneOS"
+else
+ echo "invalid arch ${ARCH} specified"
+ exit
+fi
+
+function do_export {
+ export DEVROOT="/Developer/Platforms/${PLATFORM}.platform/Developer"
+ export SDKROOT="/Developer/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}$SDK_VERSION.sdk"
+ export LD=${DEVROOT}/usr/bin/ld
+ export CPP=/usr/bin/cpp
+ export CXX="${DEVROOT}/usr/bin/g++ -arch ${ARCH}"
+ unset AR
+ unset AS
+ # export AR=${DEVROOT}/usr/bin/ar
+ # export AS=${DEVROOT}/usr/bin/as
+ export NM=${DEVROOT}/usr/bin/nm
+ export CXXCPP=/usr/bin/cpp
+ export RANLIB=${DEVROOT}/usr/bin/ranlib
+ export CC="${DEVROOT}/usr/bin/gcc -arch ${ARCH}"
+ export CFLAGS="-I${BUILD_DIR}/include -I${SDKROOT}/usr/include -pipe -no-cpp-precomp -isysroot ${SDKROOT}"
+ export CXXFLAGS="${CFLAGS}"
+ export LDFLAGS=" -L${BUILD_DIR}/lib -pipe -no-cpp-precomp -L${SDKROOT}/usr/lib -L${DEVROOT}/usr/lib -isysroot ${SDKROOT} -Wl,-syslibroot $SDKROOT"
+ export PREFIX_DIR="${BUILD_DIR}"
+ export COMMON_OPTIONS="--prefix=${PREFIX_DIR} --disable-shared --enable-static --disable-ipv6 --disable-manual "
+
+ if [ ${PLATFORM} = "iPhoneOS" ]
+ then
+ COMMON_OPTIONS="--host arm-apple-darwin ${COMMON_OPTIONS}"
+ elif [ ${PLATFORM} = "iPhoneSimulator" ]
+ then
+ COMMON_OPTIONS="--host i386-apple-darwin ${COMMON_OPTIONS}"
+ fi
+
+ if ! echo "$PATH"|grep -q "${BUILD_DIR}/tools/bin"
+ then
+ export PATH="${BUILD_DIR}/tools/bin:${PATH}"
+ fi
+
+ export PKG_CONFIG_PATH="${SDKROOT}/usr/lib/pkgconfig:${BUILD_DIR}/lib/pkgconfig"
+}
+
+function do_unset {
+ unset DEVROOT
+ unset SDKROOT
+ unset LD
+ unset CPP
+ unset CXX
+ unset AR
+ unset AS
+ unset NM
+ unset CXXCPP
+ unset RANLIB
+ unset CC
+ unset CFLAGS
+ unset LDFLAGS
+ unset PREFIX_DIR
+ unset COMMON_OPTIONS
+ export PATH=$(echo $PATH | sed -e "s;:\?${BUILD_DIR}/tools/bin;;" -e "s;${BUILD_DIR}/tools/bin:\?;;")
+}
+
+function do_pkg_config {
+ if [ ! -e "pkg-config-${PKG_CONFIG_VERSION}.tar.gz" ]
+ then
+ /usr/bin/curl -O "http://pkg-config.freedesktop.org/releases/pkg-config-${PKG_CONFIG_VERSION}.tar.gz"
+ fi
+
+ rm -rf "pkg-config-${PKG_CONFIG_VERSION}"
+ tar zxvf "pkg-config-${PKG_CONFIG_VERSION}.tar.gz"
+
+ pushd "pkg-config-${PKG_CONFIG_VERSION}"
+
+ do_unset
+ ./configure --prefix="${BUILD_DIR}/tools" ${COMMON_OPTIONS}
+ make -j2
+ make install
+
+ popd # "pkg-config-${PKG_CONFIG_VERSION}"
+}
+
+function do_openssl {
+ export PACKAGE_NAME="openssl-${OPENSSL_VERSION}"
+ if [ ! -e "${PACKAGE_NAME}.tar.gz" ]
+ then
+ /usr/bin/curl -O "http://www.openssl.org/source/${PACKAGE_NAME}.tar.gz"
+ fi
+
+ rm -rf "${PACKAGE_NAME}"
+ tar zxvf "${PACKAGE_NAME}.tar.gz"
+
+ pushd ${PACKAGE_NAME}
+
+ do_export
+
+ ./configure BSD-generic32 --openssldir=${BUILD_DIR}
+
+ # Patch for iOS, taken from https://github.com/st3fan/ios-openssl/blame/master/build.sh
+ perl -i -pe "s|static volatile sig_atomic_t intr_signal|static volatile int intr_signal|" ./crypto/ui/ui_openssl.c
+ perl -i -pe "s|^CC= gcc|CC= ${CC}|g" Makefile
+ perl -i -pe "s|^CFLAG= (.*)|CFLAG= ${CFLAGS} $1|g" Makefile
+
+ if [ ${PLATFORM} = "iPhoneSimulator" ]
+ then
+ pushd crypto/bn
+ rm -f bn_prime.h
+ perl bn_prime.pl >bn_prime.h
+ popd
+ fi
+
+ make -j ${PARALLEL_NUM}
+ make install
+
+ rm -rf ${BUILD_DIR}/share/man
+
+ popd
+
+}
+
+function do_zlib {
+ export PACKAGE_NAME="zlib-${ZLIB_VERSION}"
+ if [ ! -e "${PACKAGE_NAME}.tar.gz" ]
+ then
+# /usr/bin/curl -O "http://zlib.net/zlib-${ZLIB_VERSION}.tar.gz"
+ /usr/bin/curl -O "http://www.gknw.de/mirror/zlib/${PACKAGE_NAME}.tar.gz"
+ fi
+
+ rm -rf "${PACKAGE_NAME}"
+ tar zxvf "${PACKAGE_NAME}.tar.gz"
+
+ pushd ${PACKAGE_NAME}
+
+ do_export
+
+ ./configure --prefix="${BUILD_DIR}" --static
+
+ # Fix installation error
+ curl "http://static.ccp.li/zlib-Makefile-patch" | patch -p0
+
+ make -j ${PARALLEL_NUM}
+ make install
+
+ rm -rf ${BUILD_DIR}/share/man
+
+ popd
+}
+
+function do_curl {
+ export PACKAGE_NAME="curl-${CURL_VERSION}"
+ if [ ! -e "${PACKAGE_NAME}.tar.gz" ]
+ then
+ # /usr/bin/curl -O "http://curl.haxx.se/download/${PACKAGE_NAME}.tar.gz"
+ /usr/bin/curl -O "http://www.execve.net/curl/${PACKAGE_NAME}.tar.gz"
+ fi
+
+ rm -rf "${PACKAGE_NAME}"
+ tar zxvf "${PACKAGE_NAME}.tar.gz"
+
+ pushd ${PACKAGE_NAME}
+
+ do_export
+
+ ./configure --prefix="${BUILD_DIR}" ${COMMON_OPTIONS} --with-random=/dev/urandom --with-ssl --with-zlib LDFLAGS="${LDFLAGS}"
+
+ make -j ${PARALLEL_NUM}
+ make install
+
+ popd
+}
+
+function do_libevent {
+ export PACKAGE_NAME="libevent-${LIBEVENT_VERSION}"
+ if [ ! -e "${PACKAGE_NAME}.tar.gz" ]
+ then
+ /usr/bin/curl -O "https://github.com/downloads/libevent/libevent/${PACKAGE_NAME}.tar.gz"
+ fi
+
+ rm -rf "${PACKAGE_NAME}"
+ tar zxvf "${PACKAGE_NAME}.tar.gz"
+
+ pushd ${PACKAGE_NAME}
+
+ do_export
+
+ ./configure --prefix="${BUILD_DIR}" ${COMMON_OPTIONS}
+
+ make -j ${PARALLEL_NUM}
+ make install
+
+ popd
+}
+
+function do_transmission {
+ export PACKAGE_NAME="transmission-${TRANSMISSION_VERSION}"
+ if [ ! -e "${PACKAGE_NAME}.tar.bz2" ]
+ then
+ /usr/bin/curl -O "http://transmission.cachefly.net/${PACKAGE_NAME}.tar.bz2"
+ fi
+
+ rm -rf "${PACKAGE_NAME}"
+ tar jxvf "${PACKAGE_NAME}.tar.bz2"
+
+ pushd ${PACKAGE_NAME}
+
+ do_export
+
+ ./configure --prefix="${BUILD_DIR}" ${COMMON_OPTIONS} --enable-largefile --enable-utp --disable-nls --enable-lightweight --enable-cli --enable-daemon --disable-mac --disable-gtk --with-kqueue --enable-debug
+
+ if [ ! -e "${SDKROOT}/usr/include/net/route.h" ]
+ then
+ mkdir -p ${BUILD_DIR}/include/net
+ cp "/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDK_VERSION}.sdk/usr/include/net/route.h" "${BUILD_DIR}/include/net/route.h"
+ fi
+
+ make -j ${PARALLEL_NUM}
+ make install
+
+ # Default installation doesn't copy library and header files
+ mkdir -p ${BUILD_DIR}/include/libtransmission
+ find ./libtransmission -name "*.h" -exec cp "{}" ${BUILD_DIR}/include/libtransmission \;
+ find . -name "*.a" -exec cp "{}" ${BUILD_DIR}/lib \;
+
+ popd
+}
+
+# do_pkg_config
+# do_zlib
+# do_openssl
+# do_curl
+# do_libevent
+do_transmission
+
+# do_unset

0 comments on commit efc60aa

Please sign in to comment.
Something went wrong with that request. Please try again.