/legacy/TelegraphKit/TGToolbarButton.m

https://gitlab.com/iranjith4/Telegram · Objective C · 648 lines · 531 code · 115 blank · 2 comment · 110 complexity · c1db8dcd4b1dcb0c74a5cd8d45393538 MD5 · raw file

  1. #import "TGToolbarButton.h"
  2. #import "TGImageUtils.h"
  3. static UIImage *backgroundBack()
  4. {
  5. static UIImage *image = nil;
  6. if (image == nil)
  7. image = [[UIImage imageNamed:@"BackButton.png"] stretchableImageWithLeftCapWidth:15 topCapHeight:0];
  8. return image;
  9. }
  10. static UIImage *backgroundBackPressed()
  11. {
  12. static UIImage *image = nil;
  13. if (image == nil)
  14. image = [[UIImage imageNamed:@"BackButton_Pressed.png"] stretchableImageWithLeftCapWidth:15 topCapHeight:0];
  15. return image;
  16. }
  17. static UIImage *backgroundBackLandscape()
  18. {
  19. static UIImage *image = nil;
  20. if (image == nil)
  21. image = [[UIImage imageNamed:@"BackButton_Landscape.png"] stretchableImageWithLeftCapWidth:15 topCapHeight:0];
  22. return image;
  23. }
  24. static UIImage *backgroundBackLandscapePressed()
  25. {
  26. static UIImage *image = nil;
  27. if (image == nil)
  28. image = [[UIImage imageNamed:@"BackButton_Landscape_Pressed.png"] stretchableImageWithLeftCapWidth:15 topCapHeight:0];
  29. return image;
  30. }
  31. static UIImage *backgroundGeneric()
  32. {
  33. static UIImage *image = nil;
  34. if (image == nil)
  35. image = [[UIImage imageNamed:@"HeaderButton.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0];
  36. return image;
  37. }
  38. static UIImage *backgroundGenericPressed()
  39. {
  40. static UIImage *image = nil;
  41. if (image == nil)
  42. image = [[UIImage imageNamed:@"HeaderButton_Pressed.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0];
  43. return image;
  44. }
  45. static UIImage *backgroundGenericLandscape()
  46. {
  47. static UIImage *image = nil;
  48. if (image == nil)
  49. image = [[UIImage imageNamed:@"HeaderButton_Landscape.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0];
  50. return image;
  51. }
  52. static UIImage *backgroundGenericPressedLandscape()
  53. {
  54. static UIImage *image = nil;
  55. if (image == nil)
  56. image = [[UIImage imageNamed:@"HeaderButton_Landscape_Pressed.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0];
  57. return image;
  58. }
  59. static UIImage *backgroundDone()
  60. {
  61. static UIImage *image = nil;
  62. if (image == nil)
  63. {
  64. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Blue.png"];
  65. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  66. }
  67. return image;
  68. }
  69. static UIImage *backgroundDonePressed()
  70. {
  71. static UIImage *image = nil;
  72. if (image == nil)
  73. {
  74. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Blue_Pressed.png"];
  75. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  76. }
  77. return image;
  78. }
  79. static UIImage *backgroundDoneLandscape()
  80. {
  81. static UIImage *image = nil;
  82. if (image == nil)
  83. {
  84. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Blue_Landscape.png"];
  85. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  86. }
  87. return image;
  88. }
  89. static UIImage *backgroundDoneLandscapePressed()
  90. {
  91. static UIImage *image = nil;
  92. if (image == nil)
  93. {
  94. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Blue_Landscape_Pressed.png"];
  95. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  96. }
  97. return image;
  98. }
  99. static UIImage *backgroundDoneBlack()
  100. {
  101. static UIImage *image = nil;
  102. if (image == nil)
  103. {
  104. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Login_Blue.png"];
  105. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  106. }
  107. return image;
  108. }
  109. static UIImage *backgroundDoneBlackPressed()
  110. {
  111. static UIImage *image = nil;
  112. if (image == nil)
  113. {
  114. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Login_Blue_Pressed.png"];
  115. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  116. }
  117. return image;
  118. }
  119. static UIImage *backgroundDoneBlackLandscape()
  120. {
  121. static UIImage *image = nil;
  122. if (image == nil)
  123. {
  124. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Login_Blue_Landscape.png"];
  125. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  126. }
  127. return image;
  128. }
  129. static UIImage *backgroundDoneBlackLandscapePressed()
  130. {
  131. static UIImage *image = nil;
  132. if (image == nil)
  133. {
  134. UIImage *rawImage = [UIImage imageNamed:@"HeaderButton_Login_Blue_Landscape_Pressed.png"];
  135. image = [rawImage stretchableImageWithLeftCapWidth:(int)(rawImage.size.width / 2) topCapHeight:0];
  136. }
  137. return image;
  138. }
  139. static UIImage *backgroundDelete()
  140. {
  141. static UIImage *image = nil;
  142. if (image == nil)
  143. image = [[UIImage imageNamed:@"Header_Button_Delete.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0];
  144. return image;
  145. }
  146. static UIImage *backgroundDeleteLandscape()
  147. {
  148. static UIImage *image = nil;
  149. if (image == nil)
  150. image = [[UIImage imageNamed:@"Header_Button_Delete.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0];
  151. return image;
  152. }
  153. static UIColor *textColorForButton(int type)
  154. {
  155. switch (type)
  156. {
  157. case TGToolbarButtonTypeDone:
  158. case TGToolbarButtonTypeDoneBlack:
  159. {
  160. break;
  161. }
  162. default:
  163. break;
  164. }
  165. return [UIColor whiteColor];
  166. }
  167. static UIColor *shadowColorForButton(int type)
  168. {
  169. switch (type)
  170. {
  171. case TGToolbarButtonTypeDone:
  172. case TGToolbarButtonTypeDoneBlack:
  173. {
  174. return UIColorRGBA(0x042651, 0.3f);
  175. }
  176. default:
  177. break;
  178. }
  179. return UIColorRGBA(0x0e284d, 0.4f);
  180. }
  181. @interface TGToolbarButton ()
  182. {
  183. NSString *_text;
  184. UIImage *_image;
  185. UIImage *_imageLandscape;
  186. UIImage *_imageHighlighted;
  187. }
  188. @property (nonatomic) bool landscapeInitialized;
  189. @property (nonatomic, strong) UIImage *customImageNormal;
  190. @property (nonatomic, strong) UIImage *customImageNormalHighlighted;
  191. @property (nonatomic, strong) UIImage *customImageLandscape;
  192. @property (nonatomic, strong) UIImage *customImageLandscapeHighlighted;
  193. @property (nonatomic, strong) UIColor *customTextColor;
  194. @property (nonatomic, strong) UIColor *customShadowColor;
  195. @end
  196. @implementation TGToolbarButton
  197. @synthesize type = _type;
  198. @synthesize touchInset = _touchInset;
  199. @synthesize minWidth = _minWidth;
  200. @synthesize paddingLeft = _paddingLeft;
  201. @synthesize paddingRight = _paddingRight;
  202. @synthesize landscapeOffset = _landscapeOffset;
  203. @synthesize buttonLabelView = _buttonLabelView;
  204. @synthesize buttonImageView = _buttonImageView;
  205. @synthesize landscapeInitialized = _landscapeInitialized;
  206. @synthesize isLandscape = _isLandscape;
  207. @synthesize customImageNormal = _customImageNormal;
  208. @synthesize customImageNormalHighlighted = _customImageNormalHighlighted;
  209. @synthesize customImageLandscape = _customImageLandscape;
  210. @synthesize customImageLandscapeHighlighted = _customImageLandscapeHighlighted;
  211. @synthesize customTextColor = _customTextColor;
  212. @synthesize customShadowColor = _customShadowColor;
  213. @synthesize backSemantics = _backSemantics;
  214. - (id)initWithType:(TGToolbarButtonType)type
  215. {
  216. self = [super init];
  217. if (self != nil)
  218. {
  219. _type = type;
  220. _touchInset = CGSizeMake(8, 8);
  221. _minWidth = 0;
  222. _paddingLeft = 7;
  223. _paddingRight = 7;
  224. self.exclusiveTouch = true;
  225. if (type == TGToolbarButtonTypeBack)
  226. {
  227. _paddingLeft = 15;
  228. _paddingRight = 9;
  229. }
  230. _isLandscape = false;
  231. _landscapeInitialized = false;
  232. _buttonLabelView = [[UILabel alloc] init];
  233. _buttonLabelView.font = [UIFont boldSystemFontOfSize:12];
  234. _buttonLabelView.textColor = textColorForButton(type);
  235. _buttonLabelView.shadowColor = shadowColorForButton(type);
  236. _buttonLabelView.shadowOffset = CGSizeMake(0, -1);
  237. _buttonLabelView.backgroundColor = [UIColor clearColor];
  238. [self addSubview:_buttonLabelView];
  239. _buttonImageView = [[UIImageView alloc] init];
  240. [self addSubview:_buttonImageView];
  241. self.text = @"";
  242. self.image = nil;
  243. _landscapeOffset = 0;
  244. self.adjustsImageWhenDisabled = false;
  245. self.adjustsImageWhenHighlighted = false;
  246. self.enabled = true;
  247. [self updateBackground];
  248. }
  249. return self;
  250. }
  251. - (id)initWithCustomImages:(UIImage *)imageNormal imageNormalHighlighted:(UIImage *)imageNormalHighlighted imageLandscape:(UIImage *)imageLandscape imageLandscapeHighlighted:(UIImage *)imageLandscapeHighlighted textColor:(UIColor *)textColor shadowColor:(UIColor *)shadowColor
  252. {
  253. self = [super init];
  254. if (self != nil)
  255. {
  256. _type = TGToolbarButtonTypeCustom;
  257. _touchInset = CGSizeMake(8, 8);
  258. _minWidth = 0;
  259. _paddingLeft = 7;
  260. _paddingRight = 7;
  261. self.exclusiveTouch = true;
  262. _isLandscape = false;
  263. _landscapeInitialized = false;
  264. _customTextColor = textColor;
  265. _customShadowColor = shadowColor;
  266. _buttonLabelView = [[UILabel alloc] init];
  267. _buttonLabelView.font = [UIFont boldSystemFontOfSize:12];
  268. _buttonLabelView.textColor = _customTextColor != nil ? _customTextColor : textColorForButton(TGToolbarButtonTypeGeneric);
  269. _buttonLabelView.shadowColor = _customShadowColor != nil ? _customShadowColor : shadowColorForButton(TGToolbarButtonTypeGeneric);
  270. _buttonLabelView.shadowOffset = CGSizeMake(0, -1);
  271. _buttonLabelView.backgroundColor = [UIColor clearColor];
  272. [self addSubview:_buttonLabelView];
  273. _buttonImageView = [[UIImageView alloc] init];
  274. [self addSubview:_buttonImageView];
  275. self.text = @"";
  276. self.image = nil;
  277. _landscapeOffset = 0;
  278. self.adjustsImageWhenDisabled = false;
  279. self.adjustsImageWhenHighlighted = false;
  280. self.enabled = true;
  281. _customImageNormal = imageNormal;
  282. _customImageNormalHighlighted = imageNormalHighlighted;
  283. _customImageLandscape = imageLandscape;
  284. _customImageLandscapeHighlighted = imageLandscapeHighlighted;
  285. [self updateBackground];
  286. }
  287. return self;
  288. }
  289. - (bool)backSemantics
  290. {
  291. return _type == TGToolbarButtonTypeBack || _backSemantics;
  292. }
  293. - (void)updateBackground
  294. {
  295. UIImage *background = nil;
  296. UIImage *backgroundPressed = nil;
  297. if (_type == TGToolbarButtonTypeCustom)
  298. {
  299. background = _isLandscape ? _customImageLandscape : _customImageNormal;
  300. backgroundPressed = _isLandscape ? _customImageLandscapeHighlighted : _customImageNormalHighlighted;
  301. }
  302. else if (_type == TGToolbarButtonTypeGeneric)
  303. {
  304. background = _isLandscape ? backgroundGenericLandscape() : backgroundGeneric();
  305. backgroundPressed = _isLandscape ? backgroundGenericPressedLandscape() : backgroundGenericPressed();
  306. }
  307. else if (_type == TGToolbarButtonTypeBack)
  308. {
  309. background = _isLandscape ? backgroundBackLandscape() : backgroundBack();
  310. backgroundPressed = _isLandscape ? backgroundBackLandscapePressed() : backgroundBackPressed();
  311. }
  312. else if (_type == TGToolbarButtonTypeDone)
  313. {
  314. background = _isLandscape ? backgroundDoneLandscape() : backgroundDone();
  315. backgroundPressed = _isLandscape ? backgroundDoneLandscapePressed() : backgroundDonePressed();
  316. }
  317. else if (_type == TGToolbarButtonTypeDoneBlack)
  318. {
  319. background = _isLandscape ? backgroundDoneBlackLandscape() : backgroundDoneBlack();
  320. backgroundPressed = _isLandscape ? backgroundDoneBlackLandscapePressed() : backgroundDoneBlackPressed();
  321. }
  322. else if (_type == TGToolbarButtonTypeImage)
  323. {
  324. background = nil;
  325. }
  326. else if (_type == TGToolbarButtonTypeDelete)
  327. {
  328. background = _isLandscape ? backgroundDeleteLandscape() : backgroundDelete();
  329. }
  330. [self setBackgroundImage:background forState:UIControlStateNormal];
  331. [self setBackgroundImage:backgroundPressed forState:UIControlStateHighlighted];
  332. [self setBackgroundImage:backgroundPressed forState:UIControlStateHighlighted | UIControlStateSelected];
  333. [self setBackgroundImage:backgroundPressed forState:UIControlStateSelected];
  334. }
  335. - (NSString *)text
  336. {
  337. return _text;
  338. }
  339. - (void)setText:(NSString *)text
  340. {
  341. _text = text;
  342. if (text == nil)
  343. {
  344. _buttonLabelView.text = @"";
  345. _buttonLabelView.hidden = true;
  346. }
  347. else
  348. {
  349. _buttonLabelView.text = text;
  350. _buttonLabelView.hidden = false;
  351. }
  352. }
  353. - (UIImage *)image
  354. {
  355. return _image;
  356. }
  357. - (void)setImage:(UIImage *)image
  358. {
  359. _image = image;
  360. if (image == nil)
  361. {
  362. _buttonImageView.image = nil;
  363. _buttonImageView.hidden = true;
  364. }
  365. else
  366. {
  367. _buttonImageView.image = image;
  368. _buttonImageView.hidden = false;
  369. }
  370. }
  371. - (UIImage *)imageLandscape
  372. {
  373. return _imageLandscape;
  374. }
  375. - (void)setImageLandscape:(UIImage *)imageLandscape
  376. {
  377. _imageLandscape = imageLandscape;
  378. }
  379. - (UIImage *)imageHighlighted
  380. {
  381. return _imageHighlighted;
  382. }
  383. - (void)setImageHighlighted:(UIImage *)image
  384. {
  385. _imageHighlighted = image;
  386. if (image == nil)
  387. {
  388. _buttonImageView.highlightedImage = nil;
  389. }
  390. else
  391. {
  392. _buttonImageView.highlightedImage = image;
  393. }
  394. }
  395. - (bool)isLandscape
  396. {
  397. return _isLandscape;
  398. }
  399. - (void)setIsLandscape:(bool)isLandscape
  400. {
  401. if (isLandscape != _isLandscape || !_landscapeInitialized)
  402. {
  403. _landscapeInitialized = true;
  404. _isLandscape = isLandscape;
  405. if (_image != nil && _imageLandscape != nil)
  406. {
  407. _buttonImageView.image = isLandscape ? _imageLandscape : _image;
  408. [_buttonImageView sizeToFit];
  409. }
  410. [self layoutSubviews];
  411. [self updateBackground];
  412. CGRect frame = self.frame;
  413. if ([self.superview conformsToProtocol:@protocol(TGBarItemSemantics)])
  414. {
  415. float offset = [(id<TGBarItemSemantics>)self.superview barButtonsOffset];
  416. if (isLandscape)
  417. frame.origin.y = 2 + offset;
  418. else
  419. frame.origin.y = 0 + offset;
  420. }
  421. else
  422. {
  423. if (isLandscape)
  424. frame.origin.y = 3;
  425. else
  426. frame.origin.y = 7;
  427. }
  428. frame.size.height = isLandscape ? 25 : 30;
  429. self.frame = frame;
  430. }
  431. }
  432. - (void)sizeToFit
  433. {
  434. float width = _paddingLeft + _paddingRight;
  435. float height = _isLandscape ? 25 : 30;
  436. if (!_buttonLabelView.hidden)
  437. {
  438. [_buttonLabelView sizeToFit];
  439. width += _buttonLabelView.frame.size.width;
  440. }
  441. if (_buttonImageView.image != nil)
  442. {
  443. CGRect frame = _buttonImageView.frame;
  444. frame.size = _buttonImageView.image.size;
  445. _buttonImageView.frame = frame;
  446. width += _buttonImageView.frame.size.width;
  447. }
  448. if (width < _minWidth)
  449. width = _minWidth;
  450. self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, width, height);
  451. }
  452. - (void)layoutSubviews
  453. {
  454. [super layoutSubviews];
  455. CGRect bounds = self.bounds;
  456. CGRect labelFrame = _buttonLabelView.frame;
  457. CGRect imageFrame = _buttonImageView.frame;
  458. float retinaPixel = TGIsRetina() ? 0.5f : 0.0f;
  459. int addY = _isLandscape ? 1 : 0;
  460. int imageAddY = 0;
  461. if (!_buttonLabelView.hidden)
  462. {
  463. [_buttonLabelView sizeToFit];
  464. labelFrame = _buttonLabelView.frame;
  465. labelFrame.origin.y = (float)((bounds.size.height - labelFrame.size.height) / 2) - (!_isLandscape ? 0 : 1.0f) - retinaPixel + addY - (_type != TGToolbarButtonTypeBack && !_isLandscape ? retinaPixel : 0.0f);
  466. }
  467. else
  468. labelFrame.size = CGSizeZero;
  469. if (!_buttonImageView.hidden && _buttonImageView.image != nil)
  470. {
  471. imageFrame = _buttonImageView.frame;
  472. imageFrame.origin.y = CGFloor(((bounds.size.height - imageFrame.size.height) / 2) + imageAddY);
  473. }
  474. else
  475. imageFrame.size = CGSizeZero;
  476. int spacing = 4;
  477. if (labelFrame.size.width == 0 || imageFrame.size.width == 0)
  478. spacing = 0;
  479. labelFrame.origin.x = ((bounds.size.width - _paddingLeft - _paddingRight - labelFrame.size.width - spacing - imageFrame.size.width) / 2 + _paddingLeft);
  480. imageFrame.origin.x = (labelFrame.origin.x + labelFrame.size.width + spacing);
  481. if (TGIsRetina())
  482. {
  483. labelFrame.origin.x = ((int)(labelFrame.origin.x * 2.0f)) / 2;
  484. imageFrame.origin.x = ((int)(imageFrame.origin.x * 2.0f)) / 2;
  485. }
  486. else
  487. {
  488. labelFrame.origin.x = CGFloor(labelFrame.origin.x);
  489. imageFrame.origin.x = CGFloor(imageFrame.origin.x);
  490. }
  491. if (_type == TGToolbarButtonTypeBack && _isLandscape)
  492. labelFrame.origin.x -= 1;
  493. _buttonLabelView.frame = labelFrame;
  494. _buttonImageView.frame = imageFrame;
  495. }
  496. - (void)setEnabled:(BOOL)enabled
  497. {
  498. _buttonLabelView.alpha = !enabled ? 0.6f : 1.0f;
  499. [super setEnabled:enabled];
  500. }
  501. - (void)setHighlighted:(BOOL)highlighted
  502. {
  503. //_buttonLabelView.shadowColor = shadowColorForButton(_type, highlighted || self.selected);
  504. [super setHighlighted:highlighted];
  505. }
  506. - (void)setSelected:(BOOL)selected
  507. {
  508. //_buttonLabelView.shadowColor = shadowColorForButton(_type, selected || self.highlighted);
  509. [super setSelected:selected];
  510. }
  511. - (CGRect)backgroundRectForBounds:(CGRect)bounds
  512. {
  513. CGRect backgroundFrame = CGRectOffset([super backgroundRectForBounds:bounds], 0, (TGIsRetina() && _isLandscape) ? 0.5f : 0.0f);
  514. if (_type == TGToolbarButtonTypeBack)
  515. {
  516. backgroundFrame.origin.x -= 1;
  517. backgroundFrame.size.width += 1;
  518. if (!_isLandscape && TGIsRetina())
  519. {
  520. backgroundFrame.origin.y += 0.5f;
  521. }
  522. }
  523. return backgroundFrame;
  524. }
  525. - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)__unused event
  526. {
  527. if (self.alpha < FLT_EPSILON || self.hidden)
  528. return nil;
  529. if (CGRectContainsPoint(CGRectInset(self.bounds, -_touchInset.width, -_touchInset.height), point))
  530. return self;
  531. return nil;
  532. }
  533. @end