ReaderMainToolbar.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. //
  2. // ReaderMainToolbar.m
  3. // Reader v2.9.0
  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. #pragma mark - Properties
  46. @synthesize delegate;
  47. #pragma mark - ReaderMainToolbar instance methods
  48. - (instancetype)initWithFrame:(CGRect)frame
  49. {
  50. return [self initWithFrame:frame document:nil];
  51. }
  52. - (instancetype)initWithFrame:(CGRect)frame document:(ReaderDocument *)document
  53. {
  54. assert(document != nil); // Must have a valid ReaderDocument
  55. if ((self = [super initWithFrame:frame]))
  56. {
  57. CGFloat viewWidth = self.bounds.size.width; // Toolbar view width
  58. #if (READER_FLAT_UI == TRUE) // Option
  59. UIImage *buttonH = nil; UIImage *buttonN = nil;
  60. #else
  61. UIImage *buttonH = [[UIImage imageNamed:@"Reader-Button-H"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];
  62. UIImage *buttonN = [[UIImage imageNamed:@"Reader-Button-N"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];
  63. #endif // end of READER_FLAT_UI Option
  64. BOOL largeDevice = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
  65. const CGFloat buttonSpacing = BUTTON_SPACE; const CGFloat iconButtonWidth = ICON_BUTTON_WIDTH;
  66. CGFloat titleX = BUTTON_X; CGFloat titleWidth = (viewWidth - (titleX + titleX));
  67. CGFloat leftButtonX = BUTTON_X; // Left-side button start X position
  68. #if (READER_STANDALONE == FALSE) // Option
  69. UIFont *doneButtonFont = [UIFont systemFontOfSize:BUTTON_FONT_SIZE];
  70. NSString *doneButtonText = NSLocalizedString(@"Done", @"button text");
  71. CGSize doneButtonSize = [doneButtonText sizeWithAttributes:@{NSFontAttributeName : doneButtonFont}];
  72. CGFloat doneButtonWidth = (ceil(doneButtonSize.width) + TEXT_BUTTON_PADDING);
  73. UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
  74. doneButton.frame = CGRectMake(leftButtonX, BUTTON_Y, doneButtonWidth, BUTTON_HEIGHT);
  75. [doneButton setTitleColor:[UIColor colorWithWhite:0.0f alpha:1.0f] forState:UIControlStateNormal];
  76. [doneButton setTitleColor:[UIColor colorWithWhite:1.0f alpha:1.0f] forState:UIControlStateHighlighted];
  77. [doneButton setTitle:doneButtonText forState:UIControlStateNormal]; doneButton.titleLabel.font = doneButtonFont;
  78. [doneButton addTarget:self action:@selector(doneButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  79. [doneButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  80. [doneButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  81. doneButton.autoresizingMask = UIViewAutoresizingNone;
  82. //doneButton.backgroundColor = [UIColor grayColor];
  83. doneButton.exclusiveTouch = YES;
  84. [self addSubview:doneButton]; leftButtonX += (doneButtonWidth + buttonSpacing);
  85. titleX += (doneButtonWidth + buttonSpacing); titleWidth -= (doneButtonWidth + buttonSpacing);
  86. #endif // end of READER_STANDALONE Option
  87. #if (READER_ENABLE_THUMBS == TRUE) // Option
  88. UIButton *thumbsButton = [UIButton buttonWithType:UIButtonTypeCustom];
  89. thumbsButton.frame = CGRectMake(leftButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  90. [thumbsButton setImage:[UIImage imageNamed:@"Reader-Thumbs"] forState:UIControlStateNormal];
  91. [thumbsButton addTarget:self action:@selector(thumbsButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  92. [thumbsButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  93. [thumbsButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  94. thumbsButton.autoresizingMask = UIViewAutoresizingNone;
  95. //thumbsButton.backgroundColor = [UIColor grayColor];
  96. thumbsButton.exclusiveTouch = YES;
  97. [self addSubview:thumbsButton]; //leftButtonX += (iconButtonWidth + buttonSpacing);
  98. titleX += (iconButtonWidth + buttonSpacing); titleWidth -= (iconButtonWidth + buttonSpacing);
  99. #endif // end of READER_ENABLE_THUMBS Option
  100. CGFloat rightButtonX = viewWidth; // Right-side buttons start X position
  101. #if (READER_BOOKMARKS == TRUE) // Option
  102. rightButtonX -= (iconButtonWidth + buttonSpacing); // Position
  103. UIButton *flagButton = [UIButton buttonWithType:UIButtonTypeCustom];
  104. flagButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  105. //[flagButton setImage:[UIImage imageNamed:@"Reader-Mark-N"] forState:UIControlStateNormal];
  106. [flagButton addTarget:self action:@selector(markButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  107. [flagButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  108. [flagButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  109. flagButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  110. //flagButton.backgroundColor = [UIColor grayColor];
  111. flagButton.exclusiveTouch = YES;
  112. [self addSubview:flagButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  113. markButton = flagButton; markButton.enabled = NO; markButton.tag = NSIntegerMin;
  114. markImageN = [UIImage imageNamed:@"Reader-Mark-N"]; // N image
  115. markImageY = [UIImage imageNamed:@"Reader-Mark-Y"]; // Y image
  116. #endif // end of READER_BOOKMARKS Option
  117. if (document.canEmail == YES) // Document email enabled
  118. {
  119. if ([MFMailComposeViewController canSendMail] == YES) // Can email
  120. {
  121. unsigned long long fileSize = [document.fileSize unsignedLongLongValue];
  122. if (fileSize < 15728640ull) // Check attachment size limit (15MB)
  123. {
  124. rightButtonX -= (iconButtonWidth + buttonSpacing); // Next position
  125. UIButton *emailButton = [UIButton buttonWithType:UIButtonTypeCustom];
  126. emailButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  127. [emailButton setImage:[UIImage imageNamed:@"Reader-Email"] forState:UIControlStateNormal];
  128. [emailButton addTarget:self action:@selector(emailButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  129. [emailButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  130. [emailButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  131. emailButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  132. //emailButton.backgroundColor = [UIColor grayColor];
  133. emailButton.exclusiveTouch = YES;
  134. [self addSubview:emailButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  135. }
  136. }
  137. }
  138. if ((document.canPrint == YES) && (document.password == nil)) // Document print enabled
  139. {
  140. Class printInteractionController = NSClassFromString(@"UIPrintInteractionController");
  141. if ((printInteractionController != nil) && [printInteractionController isPrintingAvailable])
  142. {
  143. rightButtonX -= (iconButtonWidth + buttonSpacing); // Next position
  144. UIButton *printButton = [UIButton buttonWithType:UIButtonTypeCustom];
  145. printButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  146. [printButton setImage:[UIImage imageNamed:@"Reader-Print"] forState:UIControlStateNormal];
  147. [printButton addTarget:self action:@selector(printButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  148. [printButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  149. [printButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  150. printButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  151. //printButton.backgroundColor = [UIColor grayColor];
  152. printButton.exclusiveTouch = YES;
  153. [self addSubview:printButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  154. }
  155. }
  156. if (document.canExport == YES) // Document export enabled
  157. {
  158. rightButtonX -= (iconButtonWidth + buttonSpacing); // Next position
  159. UIButton *exportButton = [UIButton buttonWithType:UIButtonTypeCustom];
  160. exportButton.frame = CGRectMake(rightButtonX, BUTTON_Y, iconButtonWidth, BUTTON_HEIGHT);
  161. [exportButton setImage:[UIImage imageNamed:@"Reader-Export"] forState:UIControlStateNormal];
  162. [exportButton addTarget:self action:@selector(exportButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  163. [exportButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
  164. [exportButton setBackgroundImage:buttonN forState:UIControlStateNormal];
  165. exportButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  166. //exportButton.backgroundColor = [UIColor grayColor];
  167. exportButton.exclusiveTouch = YES;
  168. [self addSubview:exportButton]; titleWidth -= (iconButtonWidth + buttonSpacing);
  169. }
  170. if (largeDevice == YES) // Show document filename in toolbar
  171. {
  172. CGRect titleRect = CGRectMake(titleX, BUTTON_Y, titleWidth, TITLE_HEIGHT);
  173. UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleRect];
  174. titleLabel.textAlignment = NSTextAlignmentCenter;
  175. titleLabel.font = [UIFont systemFontOfSize:TITLE_FONT_SIZE];
  176. titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  177. titleLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
  178. titleLabel.textColor = [UIColor colorWithWhite:0.0f alpha:1.0f];
  179. titleLabel.backgroundColor = [UIColor clearColor];
  180. titleLabel.adjustsFontSizeToFitWidth = YES;
  181. titleLabel.minimumScaleFactor = 0.75f;
  182. titleLabel.text = [document.fileName stringByDeletingPathExtension];
  183. #if (READER_FLAT_UI == FALSE) // Option
  184. titleLabel.shadowColor = [UIColor colorWithWhite:0.75f alpha:1.0f];
  185. titleLabel.shadowOffset = CGSizeMake(0.0f, 1.0f);
  186. #endif // end of READER_FLAT_UI Option
  187. [self addSubview:titleLabel];
  188. }
  189. }
  190. return self;
  191. }
  192. - (void)setBookmarkState:(BOOL)state
  193. {
  194. #if (READER_BOOKMARKS == TRUE) // Option
  195. if (state != markButton.tag) // Only if different state
  196. {
  197. if (self.hidden == NO) // Only if toolbar is visible
  198. {
  199. UIImage *image = (state ? markImageY : markImageN);
  200. [markButton setImage:image forState:UIControlStateNormal];
  201. }
  202. markButton.tag = state; // Update bookmarked state tag
  203. }
  204. if (markButton.enabled == NO) markButton.enabled = YES;
  205. #endif // end of READER_BOOKMARKS Option
  206. }
  207. - (void)updateBookmarkImage
  208. {
  209. #if (READER_BOOKMARKS == TRUE) // Option
  210. if (markButton.tag != NSIntegerMin) // Valid tag
  211. {
  212. BOOL state = markButton.tag; // Bookmarked state
  213. UIImage *image = (state ? markImageY : markImageN);
  214. [markButton setImage:image forState:UIControlStateNormal];
  215. }
  216. if (markButton.enabled == NO) markButton.enabled = YES;
  217. #endif // end of READER_BOOKMARKS Option
  218. }
  219. - (void)hideToolbar
  220. {
  221. if (self.hidden == NO)
  222. {
  223. [UIView animateWithDuration:0.25 delay:0.0
  224. options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
  225. animations:^(void)
  226. {
  227. self.alpha = 0.0f;
  228. }
  229. completion:^(BOOL finished)
  230. {
  231. self.hidden = YES;
  232. }
  233. ];
  234. }
  235. }
  236. - (void)showToolbar
  237. {
  238. if (self.hidden == YES)
  239. {
  240. [self updateBookmarkImage]; // First
  241. [UIView animateWithDuration:0.25 delay:0.0
  242. options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
  243. animations:^(void)
  244. {
  245. self.hidden = NO;
  246. self.alpha = 1.0f;
  247. }
  248. completion:NULL
  249. ];
  250. }
  251. }
  252. #pragma mark - UIButton action methods
  253. - (void)doneButtonTapped:(UIButton *)button
  254. {
  255. [delegate tappedInToolbar:self doneButton:button];
  256. }
  257. - (void)thumbsButtonTapped:(UIButton *)button
  258. {
  259. [delegate tappedInToolbar:self thumbsButton:button];
  260. }
  261. - (void)exportButtonTapped:(UIButton *)button
  262. {
  263. [delegate tappedInToolbar:self exportButton:button];
  264. }
  265. - (void)printButtonTapped:(UIButton *)button
  266. {
  267. [delegate tappedInToolbar:self printButton:button];
  268. }
  269. - (void)emailButtonTapped:(UIButton *)button
  270. {
  271. [delegate tappedInToolbar:self emailButton:button];
  272. }
  273. - (void)markButtonTapped:(UIButton *)button
  274. {
  275. [delegate tappedInToolbar:self markButton:button];
  276. }
  277. @end