ReaderMainToolbar.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. //
  2. // ReaderMainToolbar.m
  3. // Reader v2.8.6
  4. //
  5. // Created by Julius Oklamcak on 2011-07-01.
  6. // Copyright © 2011-2015 Julius Oklamcak. All rights reserved.
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining a copy
  9. // of this software and associated documentation files (the "Software"), to deal
  10. // in the Software without restriction, including without limitation the rights to
  11. // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  12. // of the Software, and to permit persons to whom the Software is furnished to
  13. // do so, subject to the following conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be included in all
  16. // copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. //
  25. #import "ReaderConstants.h"
  26. #import "ReaderMainToolbar.h"
  27. #import "ReaderDocument.h"
  28. #import <MessageUI/MessageUI.h>
  29. @implementation ReaderMainToolbar
  30. {
  31. UIButton *markButton;
  32. UIImage *markImageN;
  33. UIImage *markImageY;
  34. }
  35. #pragma mark - Constants
  36. #define BUTTON_X 8.0f
  37. #define BUTTON_Y 8.0f
  38. #define BUTTON_SPACE 8.0f
  39. #define BUTTON_HEIGHT 30.0f
  40. #define BUTTON_FONT_SIZE 15.0f
  41. #define TEXT_BUTTON_PADDING 24.0f
  42. #define ICON_BUTTON_WIDTH 40.0f
  43. #define TITLE_FONT_SIZE 19.0f
  44. #define TITLE_HEIGHT 28.0f
  45. #define COLOR_BAR [UIColor colorWithRed:(248.0f/255.0f) green:(248.0f/255.0f) blue:(248.0f/255.0f) alpha:1.0]
  46. #define COLOR_ARANCIO [UIColor colorWithRed:241.0/255.0 green:90.0/255.0 blue:34.0/255.0 alpha:1.0]
  47. #pragma mark - Properties
  48. @synthesize delegate;
  49. #pragma mark - ReaderMainToolbar instance methods
  50. - (instancetype)initWithFrame:(CGRect)frame
  51. {
  52. return [self initWithFrame:frame document:nil];
  53. }
  54. - (instancetype)initWithFrame:(CGRect)frame document:(ReaderDocument *)document
  55. {
  56. assert(document != nil); // Must have a valid ReaderDocument
  57. if ((self = [super initWithFrame:frame]))
  58. {
  59. CGFloat viewWidth = self.bounds.size.width; // Toolbar view width
  60. #if (READER_FLAT_UI == TRUE) // Option
  61. UIImage *buttonH = nil; UIImage *buttonN = nil;
  62. #else
  63. UIImage *buttonH = [[UIImage imageNamed:@"Reader-Button-H"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];
  64. UIImage *buttonN = [[UIImage imageNamed:@"Reader-Button-N"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];
  65. #endif // end of READER_FLAT_UI Option
  66. BOOL largeDevice = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
  67. const CGFloat buttonSpacing = BUTTON_SPACE; const CGFloat iconButtonWidth = ICON_BUTTON_WIDTH;
  68. CGFloat titleX = BUTTON_X; CGFloat titleWidth = (viewWidth - (titleX + titleX));
  69. CGFloat leftButtonX = BUTTON_X; // Left-side button start X position
  70. #if (READER_STANDALONE == FALSE) // Option
  71. UIFont *doneButtonFont = [UIFont systemFontOfSize:BUTTON_FONT_SIZE];
  72. NSString *doneButtonText = NSLocalizedString(@"Done", @"button");
  73. CGSize doneButtonSize = [doneButtonText sizeWithFont:doneButtonFont];
  74. CGFloat doneButtonWidth = (doneButtonSize.width + TEXT_BUTTON_PADDING);
  75. UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
  76. doneButton.frame = CGRectMake(leftButtonX, BUTTON_Y, doneButtonWidth, BUTTON_HEIGHT);
  77. [doneButton setTitleColor:[UIColor colorWithWhite:0.0f alpha:1.0f] forState:UIControlStateNormal];
  78. [doneButton setTitleColor:[UIColor colorWithWhite:1.0f alpha:1.0f] forState:UIControlStateHighlighted];
  79. [doneButton setTitle:doneButtonText forState:UIControlStateNormal]; doneButton.titleLabel.font = doneButtonFont;
  80. [doneButton addTarget:self action:@selector(doneButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  81. [doneButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  82. [doneButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  83. doneButton.autoresizingMask = UIViewAutoresizingNone;
  84. //doneButton.backgroundColor = [UIColor grayColor];
  85. doneButton.exclusiveTouch = YES;
  86. [self addSubview:doneButton]; leftButtonX += (doneButtonWidth + buttonSpacing);
  87. titleX += (doneButtonWidth + buttonSpacing); titleWidth -= (doneButtonWidth + buttonSpacing);
  88. #endif // end of READER_STANDALONE Option
  89. #if (READER_ENABLE_THUMBS == TRUE) // Option
  90. UIButton *thumbsButton = [UIButton buttonWithType:UIButtonTypeCustom];
  91. thumbsButton.frame = CGRectMake(leftButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  92. [thumbsButton setImage:[UIImage imageNamed:@"Reader-Thumbs"] forState:UIControlStateNormal];
  93. [thumbsButton addTarget:self action:@selector(thumbsButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  94. [thumbsButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  95. [thumbsButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  96. thumbsButton.autoresizingMask = UIViewAutoresizingNone;
  97. //thumbsButton.backgroundColor = [UIColor grayColor];
  98. thumbsButton.exclusiveTouch = YES;
  99. [self addSubview:thumbsButton]; //leftButtonX += (iconButtonWidth + buttonSpacing);
  100. titleX += (iconButtonWidth + buttonSpacing); titleWidth -= (iconButtonWidth + buttonSpacing);
  101. #endif // end of READER_ENABLE_THUMBS Option
  102. CGFloat rightButtonX = viewWidth; // Right-side buttons start X position
  103. #if (READER_BOOKMARKS == TRUE) // Option
  104. rightButtonX -= (iconButtonWidth + buttonSpacing); // Position
  105. UIButton *flagButton = [UIButton buttonWithType:UIButtonTypeCustom];
  106. flagButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  107. //[flagButton setImage:[UIImage imageNamed:@"Reader-Mark-N"] forState:UIControlStateNormal];
  108. [flagButton addTarget:self action:@selector(markButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  109. [flagButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  110. [flagButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  111. flagButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  112. //flagButton.backgroundColor = [UIColor grayColor];
  113. flagButton.exclusiveTouch = YES;
  114. [self addSubview:flagButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  115. markButton = flagButton; markButton.enabled = NO; markButton.tag = NSIntegerMin;
  116. markImageN = [UIImage imageNamed:@"Reader-Mark-N"]; // N image
  117. markImageY = [UIImage imageNamed:@"Reader-Mark-Y"]; // Y image
  118. #endif // end of READER_BOOKMARKS Option
  119. if (document.canEmail == YES) // Document email enabled
  120. {
  121. if ([MFMailComposeViewController canSendMail] == YES) // Can email
  122. {
  123. unsigned long long fileSize = [document.fileSize unsignedLongLongValue];
  124. if (fileSize < 15728640ull) // Check attachment size limit (15MB)
  125. {
  126. rightButtonX -= (iconButtonWidth + buttonSpacing); // Next position
  127. UIButton *emailButton = [UIButton buttonWithType:UIButtonTypeCustom];
  128. emailButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  129. [emailButton setImage:[UIImage imageNamed:@"Reader-Email"] forState:UIControlStateNormal];
  130. [emailButton addTarget:self action:@selector(emailButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  131. [emailButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  132. [emailButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  133. emailButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  134. //emailButton.backgroundColor = [UIColor grayColor];
  135. emailButton.exclusiveTouch = YES;
  136. [self addSubview:emailButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  137. }
  138. }
  139. }
  140. if ((document.canPrint == YES) && (document.password == nil)) // Document print enabled
  141. {
  142. Class printInteractionController = NSClassFromString(@"UIPrintInteractionController");
  143. if ((printInteractionController != nil) && [printInteractionController isPrintingAvailable])
  144. {
  145. rightButtonX -= (iconButtonWidth + buttonSpacing); // Next position
  146. UIButton *printButton = [UIButton buttonWithType:UIButtonTypeCustom];
  147. printButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  148. [printButton setImage:[UIImage imageNamed:@"Reader-Print"] forState:UIControlStateNormal];
  149. [printButton addTarget:self action:@selector(printButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  150. [printButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  151. [printButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  152. printButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  153. //printButton.backgroundColor = [UIColor grayColor];
  154. printButton.exclusiveTouch = YES;
  155. [self addSubview:printButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  156. }
  157. }
  158. if (document.canExport == YES) // Document export enabled
  159. {
  160. rightButtonX -= (iconButtonWidth + buttonSpacing); // Next position
  161. UIButton *exportButton = [UIButton buttonWithType:UIButtonTypeCustom];
  162. exportButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  163. [exportButton setImage:[UIImage imageNamed:@"Reader-Export"] forState:UIControlStateNormal];
  164. [exportButton addTarget:self action:@selector(exportButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  165. [exportButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  166. [exportButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  167. exportButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  168. //exportButton.backgroundColor = [UIColor grayColor];
  169. exportButton.exclusiveTouch = YES;
  170. [self addSubview:exportButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  171. }
  172. if (largeDevice == YES) // Show document filename in toolbar
  173. {
  174. CGRect titleRect = CGRectMake(titleX, BUTTON_Y, titleWidth, TITLE_HEIGHT);
  175. UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleRect];
  176. titleLabel.textAlignment = NSTextAlignmentCenter;
  177. titleLabel.font = [UIFont systemFontOfSize:TITLE_FONT_SIZE];
  178. titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  179. titleLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
  180. titleLabel.textColor = [UIColor colorWithWhite:0.0f alpha:1.0f];
  181. titleLabel.backgroundColor = [UIColor clearColor];
  182. titleLabel.adjustsFontSizeToFitWidth = YES;
  183. titleLabel.minimumScaleFactor = 0.75f;
  184. titleLabel.text = [document.fileName stringByDeletingPathExtension];
  185. #if (READER_FLAT_UI == FALSE) // Option
  186. titleLabel.shadowColor = [UIColor colorWithWhite:0.75f alpha:1.0f];
  187. titleLabel.shadowOffset = CGSizeMake(0.0f, 1.0f);
  188. #endif // end of READER_FLAT_UI Option
  189. [self addSubview:titleLabel];
  190. }
  191. }
  192. return self;
  193. }
  194. - (void)setBookmarkState:(BOOL)state
  195. {
  196. #if (READER_BOOKMARKS == TRUE) // Option
  197. if (state != markButton.tag) // Only if different state
  198. {
  199. if (self.hidden == NO) // Only if toolbar is visible
  200. {
  201. UIImage *image = (state ? markImageY : markImageN);
  202. [markButton setImage:image forState:UIControlStateNormal];
  203. }
  204. markButton.tag = state; // Update bookmarked state tag
  205. }
  206. if (markButton.enabled == NO) markButton.enabled = YES;
  207. #endif // end of READER_BOOKMARKS Option
  208. }
  209. - (void)updateBookmarkImage
  210. {
  211. #if (READER_BOOKMARKS == TRUE) // Option
  212. if (markButton.tag != NSIntegerMin) // Valid tag
  213. {
  214. BOOL state = markButton.tag; // Bookmarked state
  215. UIImage *image = (state ? markImageY : markImageN);
  216. [markButton setImage:image forState:UIControlStateNormal];
  217. }
  218. if (markButton.enabled == NO) markButton.enabled = YES;
  219. #endif // end of READER_BOOKMARKS Option
  220. }
  221. - (void)hideToolbar
  222. {
  223. if (self.hidden == NO)
  224. {
  225. [UIView animateWithDuration:0.25 delay:0.0
  226. options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
  227. animations:^(void)
  228. {
  229. self.alpha = 0.0f;
  230. }
  231. completion:^(BOOL finished)
  232. {
  233. self.hidden = YES;
  234. }
  235. ];
  236. }
  237. }
  238. - (void)showToolbar
  239. {
  240. if (self.hidden == YES)
  241. {
  242. [self updateBookmarkImage]; // First
  243. [UIView animateWithDuration:0.25 delay:0.0
  244. options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
  245. animations:^(void)
  246. {
  247. self.hidden = NO;
  248. self.alpha = 1.0f;
  249. }
  250. completion:NULL
  251. ];
  252. }
  253. }
  254. #pragma mark - UIButton action methods
  255. - (void)doneButtonTapped:(UIButton *)button
  256. {
  257. [delegate tappedInToolbar:self doneButton:button];
  258. }
  259. - (void)thumbsButtonTapped:(UIButton *)button
  260. {
  261. [delegate tappedInToolbar:self thumbsButton:button];
  262. }
  263. - (void)exportButtonTapped:(UIButton *)button
  264. {
  265. [delegate tappedInToolbar:self exportButton:button];
  266. }
  267. - (void)printButtonTapped:(UIButton *)button
  268. {
  269. [delegate tappedInToolbar:self printButton:button];
  270. }
  271. - (void)emailButtonTapped:(UIButton *)button
  272. {
  273. [delegate tappedInToolbar:self emailButton:button];
  274. }
  275. - (void)markButtonTapped:(UIButton *)button
  276. {
  277. [delegate tappedInToolbar:self markButton:button];
  278. }
  279. @end