VLCMovieViewControlPanelView.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*****************************************************************************
  2. * VLCMovieViewControlPanelView.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2015 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Tobias Conradi <videolan@tobias-conradi.de>
  9. * Carola Nitz <nitz.carola@googlemail.com>
  10. *
  11. * Refer to the COPYING file of the official project for license.
  12. *****************************************************************************/
  13. #import "VLCMovieViewControlPanelView.h"
  14. #import "VLCPlaybackController.h"
  15. @interface VLCMovieViewControlPanelView ()
  16. @property (nonatomic, strong) UIView *playbackControls;
  17. @property (nonatomic, strong) NSMutableArray *constraints;
  18. @property (nonatomic, assign) BOOL compactMode;
  19. @property (nonatomic, strong) VLCPlaybackController *playbackController;
  20. @end
  21. @implementation VLCMovieViewControlPanelView
  22. static const CGFloat maxCompactWidth = 420.0;
  23. - (instancetype)initWithFrame:(CGRect)frame
  24. {
  25. self = [super initWithFrame:frame];
  26. if (self) {
  27. [self setupSubviews];
  28. [self setupConstraints];
  29. _compactMode = YES;
  30. [self setupConstraints:_compactMode];
  31. }
  32. return self;
  33. }
  34. - (void)setupSubviews
  35. {
  36. _playbackSpeedButton = [[UIButton alloc] initWithFrame:CGRectZero];
  37. [_playbackSpeedButton setImage:[UIImage imageNamed:@"speedIcon"] forState:UIControlStateNormal];
  38. _playbackSpeedButton.translatesAutoresizingMaskIntoConstraints = NO;
  39. [self addSubview:_playbackSpeedButton];
  40. _trackSwitcherButton = [[UIButton alloc] initWithFrame:CGRectZero];
  41. [_trackSwitcherButton setImage:[UIImage imageNamed:@"audioTrackIcon"] forState:UIControlStateNormal];
  42. _trackSwitcherButton.translatesAutoresizingMaskIntoConstraints = NO;
  43. [self addSubview:_trackSwitcherButton];
  44. _playbackControls = [[UIView alloc] initWithFrame:CGRectZero];
  45. _playbackControls.translatesAutoresizingMaskIntoConstraints = NO;
  46. [self addSubview:_playbackControls];
  47. _bwdButton = [[UIButton alloc] initWithFrame:CGRectZero];
  48. [_bwdButton setImage:[UIImage imageNamed:@"backIcon"] forState:UIControlStateNormal];
  49. _bwdButton.translatesAutoresizingMaskIntoConstraints = NO;
  50. [_playbackControls addSubview:_bwdButton];
  51. _playPauseButton = [[UIButton alloc] initWithFrame:CGRectZero];
  52. [_playPauseButton setImage:[UIImage imageNamed:@"playIcon"] forState:UIControlStateNormal];
  53. _playPauseButton.translatesAutoresizingMaskIntoConstraints = NO;
  54. [_playbackControls addSubview:_playPauseButton];
  55. _fwdButton = [[UIButton alloc] initWithFrame:CGRectZero];
  56. [_fwdButton setImage:[UIImage imageNamed:@"forwardIcon"] forState:UIControlStateNormal];
  57. _fwdButton.translatesAutoresizingMaskIntoConstraints = NO;
  58. [_playbackControls addSubview:_fwdButton];
  59. _videoFilterButton = [[UIButton alloc] initWithFrame:CGRectZero];
  60. [_videoFilterButton setImage:[UIImage imageNamed:@"videoEffectsIcon"] forState:UIControlStateNormal];
  61. _videoFilterButton.translatesAutoresizingMaskIntoConstraints = NO;
  62. [self addSubview:_videoFilterButton];
  63. _moreActionsButton = [[UIButton alloc] initWithFrame:CGRectZero];
  64. [_moreActionsButton setImage:[UIImage imageNamed:@"More"] forState:UIControlStateNormal];
  65. _moreActionsButton.translatesAutoresizingMaskIntoConstraints = NO;
  66. [self addSubview:_moreActionsButton];
  67. _volumeView = [[VLCVolumeView alloc] initWithFrame:CGRectZero];
  68. _volumeView.translatesAutoresizingMaskIntoConstraints = NO;
  69. [self addSubview:_volumeView];
  70. _playbackSpeedButton.accessibilityLabel = NSLocalizedString(@"PLAYBACK_SPEED", nil);
  71. _trackSwitcherButton.accessibilityLabel = NSLocalizedString(@"OPEN_TRACK_PANEL", nil);
  72. _bwdButton.accessibilityLabel = NSLocalizedString(@"BWD_BUTTON", nil);
  73. _playPauseButton.accessibilityLabel = NSLocalizedString(@"PLAY_PAUSE_BUTTON", nil);
  74. _playPauseButton.accessibilityHint = NSLocalizedString(@"LONGPRESS_TO_STOP", nil);
  75. _fwdButton.accessibilityLabel = NSLocalizedString(@"FWD_BUTTON", nil);
  76. _videoFilterButton.accessibilityLabel = NSLocalizedString(@"VIDEO_FILTER", nil);
  77. UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(playPauseLongPress:)];
  78. [_playPauseButton addGestureRecognizer:longPressRecognizer];
  79. [self.volumeView setVolumeThumbImage:[UIImage imageNamed:@"sliderKnob"] forState:UIControlStateNormal];
  80. }
  81. - (void)setupConstraints
  82. {
  83. NSDictionary *viewsDict = @{
  84. @"forward" : self.fwdButton,
  85. @"backward" : self.bwdButton,
  86. @"playpause" : self.playPauseButton,
  87. @"speed" : self.playbackSpeedButton,
  88. @"track" : self.trackSwitcherButton,
  89. @"more" : self.moreActionsButton,
  90. @"filter" : self.videoFilterButton,
  91. @"volume" : self.volumeView,
  92. };
  93. NSMutableArray *staticConstraints = [NSMutableArray new];
  94. [staticConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[backward(40)]-(margin@750)-[playpause(40)]-(margin@750)-[forward(40)]|"
  95. options:NSLayoutFormatAlignAllCenterY
  96. metrics:@{@"margin": @15.0}
  97. views:viewsDict]];
  98. [staticConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[backward(40)]|"
  99. options:NSLayoutFormatAlignAllCenterX
  100. metrics:nil
  101. views:viewsDict]];
  102. for (NSString *object in viewsDict) {
  103. NSString *format = [NSString stringWithFormat:@"V:[%@(40)]", object];
  104. [staticConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:format
  105. options:NSLayoutFormatAlignAllCenterX
  106. metrics:nil
  107. views:viewsDict]];
  108. }
  109. [NSLayoutConstraint activateConstraints:staticConstraints];
  110. }
  111. - (void)updateViewConstraints
  112. {
  113. BOOL compactMode = CGRectGetWidth(self.frame) <= maxCompactWidth;
  114. if (self.compactMode != compactMode) {
  115. self.compactMode = compactMode;
  116. [self setupConstraints:compactMode];
  117. }
  118. }
  119. - (void)setupConstraints:(BOOL)compactMode
  120. {
  121. [self removeConstraints:_constraints];
  122. NSDictionary *viewsDict = @{@"speed" : self.playbackSpeedButton,
  123. @"track" : self.trackSwitcherButton,
  124. @"playback" : self.playbackControls,
  125. @"filter" : self.videoFilterButton,
  126. @"actions" : self.moreActionsButton,
  127. @"volume" : self.volumeView,
  128. };
  129. _constraints = [NSMutableArray array];
  130. if (compactMode) {
  131. [_constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[speed(35)]-[track(35)]-(>=8)-[playback]-(>=8)-[filter(35)]-[actions(35)]-|"
  132. options:NSLayoutFormatAlignAllCenterY
  133. metrics:nil
  134. views:viewsDict]];
  135. [_constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=10)-[volume(==300)]-(>=10)-|"
  136. options:0
  137. metrics:nil
  138. views:viewsDict]];
  139. [_constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[playback]-[volume]-|"
  140. options:NSLayoutFormatAlignAllCenterX
  141. metrics:nil
  142. views:viewsDict]];
  143. } else {
  144. [_constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[volume(>=150)]-(>=8)-[playback]-(>=8)-[speed(35)]-[track(35)]-[filter(35)]-[actions(35)]-|"
  145. options:NSLayoutFormatAlignAllCenterY
  146. metrics:nil
  147. views:viewsDict]];
  148. [_constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[playback]-|"
  149. options:0
  150. metrics:nil
  151. views:viewsDict]];
  152. }
  153. [_constraints addObject:[NSLayoutConstraint constraintWithItem:self.playbackControls
  154. attribute:NSLayoutAttributeCenterX
  155. relatedBy:NSLayoutRelationEqual
  156. toItem:self
  157. attribute:NSLayoutAttributeCenterX
  158. multiplier:1.0
  159. constant:0]];
  160. [self addConstraints:_constraints];
  161. }
  162. - (void)layoutSubviews
  163. {
  164. [super layoutSubviews];
  165. [self updateViewConstraints];
  166. }
  167. - (VLCPlaybackController *)playbackController
  168. {
  169. if (!_playbackController) {
  170. _playbackController = [VLCPlaybackController sharedInstance];
  171. }
  172. return _playbackController;
  173. }
  174. - (void)playPauseLongPress:(UILongPressGestureRecognizer *)recognizer
  175. {
  176. switch (recognizer.state) {
  177. case UIGestureRecognizerStateBegan:
  178. { UIImage *image = [UIImage imageNamed:@"stopIcon"];
  179. [_playPauseButton setImage:image forState:UIControlStateNormal];
  180. }
  181. break;
  182. case UIGestureRecognizerStateEnded:
  183. [self.playbackController stopPlayback];
  184. break;
  185. case UIGestureRecognizerStateCancelled:
  186. case UIGestureRecognizerStateFailed:
  187. [self updatePlayPauseButton];
  188. break;
  189. default:
  190. break;
  191. }
  192. }
  193. - (void)updateButtons
  194. {
  195. [self updatePlayPauseButton];
  196. self.trackSwitcherButton.hidden = !self.playbackController.currentMediaHasTrackToChooseFrom;
  197. self.videoFilterButton.hidden = self.playbackController.audioOnlyPlaybackSession;
  198. }
  199. - (void)updatePlayPauseButton
  200. {
  201. const BOOL isPlaying = self.playbackController.isPlaying;
  202. UIImage *playPauseImage = isPlaying ? [UIImage imageNamed:@"pauseIcon"] : [UIImage imageNamed:@"playIcon"];
  203. [_playPauseButton setImage:playPauseImage forState:UIControlStateNormal];
  204. }
  205. @end