Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
VLC-iOS
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
311
Issues
311
List
Boards
Labels
Service Desk
Milestones
Merge Requests
6
Merge Requests
6
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
VideoLAN
VLC-iOS
Commits
6f5a9002
Commit
6f5a9002
authored
Feb 28, 2014
by
Carola Nitz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Folder functionality for the library
parent
79e1b498
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1156 additions
and
33 deletions
+1156
-33
Resources/About Contents.html
Resources/About Contents.html
+3
-0
Resources/audio@4x.png
Resources/audio@4x.png
+0
-0
Resources/blank@4x.png
Resources/blank@4x.png
+0
-0
Resources/en.lproj/Localizable.strings
Resources/en.lproj/Localizable.strings
+0
-0
Resources/folder@4x.png
Resources/folder@4x.png
+0
-0
Resources/movie@4x.png
Resources/movie@4x.png
+0
-0
Sources/VLCFolderCollectionViewFlowLayout.h
Sources/VLCFolderCollectionViewFlowLayout.h
+24
-0
Sources/VLCFolderCollectionViewFlowLayout.m
Sources/VLCFolderCollectionViewFlowLayout.m
+419
-0
Sources/VLCPlaylistCollectionViewCell.h
Sources/VLCPlaylistCollectionViewCell.h
+1
-0
Sources/VLCPlaylistCollectionViewCell.m
Sources/VLCPlaylistCollectionViewCell.m
+76
-2
Sources/VLCPlaylistTableViewCell.m
Sources/VLCPlaylistTableViewCell.m
+55
-2
Sources/VLCPlaylistViewController.h
Sources/VLCPlaylistViewController.h
+2
-1
Sources/VLCPlaylistViewController.m
Sources/VLCPlaylistViewController.m
+331
-19
VLC for iOS.xcodeproj/project.pbxproj
VLC for iOS.xcodeproj/project.pbxproj
+27
-8
VLCAlertView.h
VLCAlertView.h
+19
-0
VLCAlertView.m
VLCAlertView.m
+43
-0
compileVLCforiOS.sh
compileVLCforiOS.sh
+14
-1
patches/lxreorderablecollectionviewflowlayout/0001-conform-to-c99-to-compile.patch
...ectionviewflowlayout/0001-conform-to-c99-to-compile.patch
+84
-0
patches/lxreorderablecollectionviewflowlayout/0002-Added-a-delegate-method-to-remove-item-from-folder.patch
...-Added-a-delegate-method-to-remove-item-from-folder.patch
+58
-0
No files found.
Resources/About Contents.html
View file @
6f5a9002
...
...
@@ -63,6 +63,9 @@ Copyright © 2011-2013 Google Inc. - <a href="#apache2">Apache 2 License</a>
<a
href=
"http://www.inappsettingskit.com"
>
InAppSettingsKit
</a><br
/>
Copyright
©
2009-2013 Luc Vandal, Edovia Inc., Ortwin Gentz, FutureTap GmbH -
<a
href=
"#bsd2clause"
>
2-clause BSD License
</a><br
/>
<br
/>
<a
href=
"https://github.com/lxcid/LXReorderableCollectionViewFlowLayout"
>
LXReorderableCollectionViewFlowLayout
</a><br
/>
Copyright
©
2012 Stan Chang Khin Boon and contributors -
<a
href=
"#mit"
>
MIT License
</a><br
/>
<br
/>
<a
href=
"https://github.com/ole/OBSlider"
>
OBSlider
</a><br
/>
Copyright
©
2011 Ole Begemann and contributors -
<a
href=
"#mit"
>
MIT License
</a><br
/>
<br
/>
...
...
Resources/audio@4x.png
deleted
100644 → 0
View file @
79e1b498
1.56 KB
Resources/blank@4x.png
deleted
100644 → 0
View file @
79e1b498
946 Bytes
Resources/en.lproj/Localizable.strings
View file @
6f5a9002
B
"CHOOSE_AUDIO_TRACK"="Choose Audio Track";
...
...
Resources/folder@4x.png
deleted
100644 → 0
View file @
79e1b498
1.21 KB
Resources/movie@4x.png
deleted
100644 → 0
View file @
79e1b498
1.13 KB
Sources/VLCFolderCollectionViewFlowLayout.h
0 → 100755
View file @
6f5a9002
/*****************************************************************************
* VLCFolderCollectionViewFlowLayout.h
* VLC for iOS
*****************************************************************************
* Copyright (c) 2014 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Carola Nitz <nitz.carola # googlemail.com>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
@interface
VLCFolderCollectionViewFlowLayout
:
UICollectionViewFlowLayout
@property
(
assign
,
nonatomic
)
CGFloat
scrollingSpeed
;
@property
(
assign
,
nonatomic
)
UIEdgeInsets
scrollingTriggerEdgeInsets
;
@property
(
strong
,
nonatomic
,
readonly
)
UIPanGestureRecognizer
*
panGestureRecognizer
;
@end
@protocol
VLCFolderCollectionViewDelegateFlowLayout
<
UICollectionViewDelegateFlowLayout
>
-
(
void
)
collectionView
:(
UICollectionView
*
)
collectionView
requestToMoveItemAtIndexPath
:(
NSIndexPath
*
)
currentPath
intoFolderAtIndexPath
:(
NSIndexPath
*
)
newIndexPath
;
@end
\ No newline at end of file
Sources/VLCFolderCollectionViewFlowLayout.m
0 → 100755
View file @
6f5a9002
/*****************************************************************************
* VLCFolderCollectionViewFlowLayout.m
* VLC for iOS
*****************************************************************************
* Copyright (c) 2014 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Carola Nitz <nitz.carola # googlemail.com>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
#import "VLCFolderCollectionViewFlowLayout.h"
#import <objc/runtime.h>
#import "VLCPlaylistViewController.h"
//framrate were motion appears fluent
#define LX_FRAMES_PER_SECOND 60.0
#ifndef CGGEOMETRY_LXSUPPORT_H_
CG_INLINE
CGPoint
LXS_CGPointAdd
(
CGPoint
point1
,
CGPoint
point2
)
{
return
CGPointMake
(
point1
.
x
+
point2
.
x
,
point1
.
y
+
point2
.
y
);
}
#endif
typedef
NS_ENUM
(
NSInteger
,
LXScrollingDirection
)
{
LXScrollingDirectionUnknown
=
0
,
LXScrollingDirectionUp
,
LXScrollingDirectionDown
,
LXScrollingDirectionLeft
,
LXScrollingDirectionRight
};
static
NSString
*
const
kLXScrollingDirectionKey
=
@"LXScrollingDirection"
;
static
NSString
*
const
kLXCollectionViewKeyPath
=
@"collectionView"
;
@interface
CADisplayLink
(
LX_userInfo
)
@property
(
nonatomic
,
copy
)
NSDictionary
*
LX_userInfo
;
@end
@implementation
CADisplayLink
(
LX_userInfo
)
-
(
void
)
setLX_userInfo
:(
NSDictionary
*
)
LX_userInfo
{
objc_setAssociatedObject
(
self
,
"LX_userInfo"
,
LX_userInfo
,
OBJC_ASSOCIATION_COPY
);
}
-
(
NSDictionary
*
)
LX_userInfo
{
return
objc_getAssociatedObject
(
self
,
"LX_userInfo"
);
}
@end
@interface
UICollectionViewCell
(
VLCFolderCollectionViewLayout
)
-
(
UIImage
*
)
LX_rasterizedImage
;
@end
@implementation
UICollectionViewCell
(
VLCFolderCollectionViewLayout
)
-
(
UIImage
*
)
LX_rasterizedImage
{
UIGraphicsBeginImageContextWithOptions
(
self
.
bounds
.
size
,
self
.
isOpaque
,
0
.
0
f
);
[
self
.
layer
renderInContext
:
UIGraphicsGetCurrentContext
()];
UIImage
*
image
=
UIGraphicsGetImageFromCurrentImageContext
();
UIGraphicsEndImageContext
();
return
image
;
}
@end
@interface
VLCFolderCollectionViewFlowLayout
()
{
NSIndexPath
*
_selectedItemIndexPath
;
UIView
*
_currentView
;
CGPoint
_currentViewCenter
;
CGPoint
_panTranslationInCollectionView
;
CADisplayLink
*
_displayLink
;
UIView
*
_folderView
;
}
@end
@implementation
VLCFolderCollectionViewFlowLayout
-
(
void
)
setDefaults
{
_scrollingSpeed
=
300
.
0
f
;
_scrollingTriggerEdgeInsets
=
UIEdgeInsetsMake
(
50
.
0
f
,
50
.
0
f
,
50
.
0
f
,
50
.
0
f
);
}
-
(
void
)
setupCollectionView
{
_panGestureRecognizer
=
[[
UIPanGestureRecognizer
alloc
]
initWithTarget
:
self
action:
@selector
(
handlePanGesture
:)];
for
(
UIGestureRecognizer
*
gestureRecognizer
in
self
.
collectionView
.
gestureRecognizers
)
{
if
([
gestureRecognizer
isKindOfClass
:[
UIPanGestureRecognizer
class
]])
[
gestureRecognizer
requireGestureRecognizerToFail
:
_panGestureRecognizer
];
}
[
self
.
collectionView
addGestureRecognizer
:
_panGestureRecognizer
];
// Useful in multiple scenarios: one common scenario being when the Notification Center drawer is pulled down
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(
handleApplicationWillResignActive
:
)
name
:
UIApplicationWillResignActiveNotification
object
:
nil
];
}
-
(
id
)
init
{
self
=
[
super
init
];
if
(
self
)
{
[
self
setDefaults
];
[
self
addObserver
:
self
forKeyPath
:
kLXCollectionViewKeyPath
options
:
NSKeyValueObservingOptionNew
context
:
nil
];
}
return
self
;
}
-
(
id
)
initWithCoder
:(
NSCoder
*
)
aDecoder
{
self
=
[
super
initWithCoder
:
aDecoder
];
if
(
self
)
{
[
self
setDefaults
];
[
self
addObserver
:
self
forKeyPath
:
kLXCollectionViewKeyPath
options
:
NSKeyValueObservingOptionNew
context
:
nil
];
}
return
self
;
}
-
(
void
)
dealloc
{
[
self
invalidatesScrollTimer
];
[
self
removeObserver
:
self
forKeyPath
:
kLXCollectionViewKeyPath
];
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
name
:
UIApplicationWillResignActiveNotification
object
:
nil
];
}
-
(
void
)
applyLayoutAttributes
:(
UICollectionViewLayoutAttributes
*
)
layoutAttributes
{
if
([
layoutAttributes
.
indexPath
isEqual
:
_selectedItemIndexPath
])
layoutAttributes
.
hidden
=
YES
;
}
-
(
id
<
VLCFolderCollectionViewDelegateFlowLayout
>
)
delegate
{
return
(
id
<
VLCFolderCollectionViewDelegateFlowLayout
>
)
self
.
collectionView
.
delegate
;
}
-
(
void
)
invalidateLayoutIfNecessary
{
NSIndexPath
*
newIndexPath
=
[
self
.
collectionView
indexPathForItemAtPoint
:
_currentView
.
center
];
NSIndexPath
*
previousIndexPath
=
_selectedItemIndexPath
;
if
((
newIndexPath
==
nil
)
||
[
newIndexPath
isEqual
:
previousIndexPath
])
{
_currentView
.
transform
=
CGAffineTransformMakeScale
(
1
.
1
f
,
1
.
1
f
);
[
_folderView
removeFromSuperview
];
return
;
}
UICollectionViewCell
*
cell
=
[
self
.
collectionView
.
dataSource
collectionView
:
self
.
collectionView
cellForItemAtIndexPath
:
newIndexPath
];
if
(
!
_folderView
)
{
_folderView
=
[[
UIView
alloc
]
initWithFrame
:
cell
.
frame
];
_folderView
.
backgroundColor
=
[
UIColor
colorWithRed
:(
236
.
0
f
/
255
.
0
f
)
green
:(
111
.
0
f
/
255
.
0
f
)
blue
:
0
.
0
f
alpha
:
1
.
f
];
_folderView
.
layer
.
cornerRadius
=
8
;
}
[
self
.
collectionView
insertSubview
:
_folderView
atIndex
:
0
];
if
(
!
CGPointEqualToPoint
(
_folderView
.
center
,
cell
.
center
))
_folderView
.
frame
=
cell
.
frame
;
[
UIView
animateWithDuration:
0
.
3
delay:
0
.
0
options:
UIViewAnimationOptionBeginFromCurrentState
animations:
^
{
_currentView
.
transform
=
CGAffineTransformMakeScale
(
1
.
0
f
,
1
.
0
f
);
}
completion
:
nil
];
}
-
(
void
)
invalidatesScrollTimer
{
if
(
!
_displayLink
.
paused
)
[
_displayLink
invalidate
];
_displayLink
=
nil
;
}
-
(
void
)
setupScrollTimerInDirection
:(
LXScrollingDirection
)
direction
{
if
(
!
_displayLink
.
paused
)
{
LXScrollingDirection
oldDirection
=
[
_displayLink
.
LX_userInfo
[
kLXScrollingDirectionKey
]
integerValue
];
if
(
direction
==
oldDirection
)
return
;
}
[
self
invalidatesScrollTimer
];
_displayLink
=
[
CADisplayLink
displayLinkWithTarget
:
self
selector
:
@selector
(
handleScroll
:
)];
_displayLink
.
LX_userInfo
=
@{
kLXScrollingDirectionKey
:
@
(
direction
)
};
[
_displayLink
addToRunLoop
:[
NSRunLoop
mainRunLoop
]
forMode
:
NSRunLoopCommonModes
];
}
#pragma mark - Target/Action methods
// Tight loop, allocate memory sparely, even if they are stack allocation.
-
(
void
)
handleScroll
:(
CADisplayLink
*
)
displayLink
{
LXScrollingDirection
direction
=
(
LXScrollingDirection
)[
displayLink
.
LX_userInfo
[
kLXScrollingDirectionKey
]
integerValue
];
if
(
direction
==
LXScrollingDirectionUnknown
)
return
;
CGSize
frameSize
=
self
.
collectionView
.
bounds
.
size
;
CGSize
contentSize
=
self
.
collectionView
.
contentSize
;
CGPoint
contentOffset
=
self
.
collectionView
.
contentOffset
;
// Important to have an integer `distance` as the `contentOffset` property automatically gets rounded
// and it would diverge from the view's center resulting in a "cell is slipping away under finger"-bug.
CGFloat
distance
=
rint
(
self
.
scrollingSpeed
/
LX_FRAMES_PER_SECOND
);
CGPoint
translation
=
CGPointZero
;
switch
(
direction
)
{
case
LXScrollingDirectionUp
:
{
distance
=
-
distance
;
CGFloat
minY
=
0
.
0
f
;
if
((
contentOffset
.
y
+
distance
)
<=
minY
)
distance
=
-
contentOffset
.
y
;
translation
=
CGPointMake
(
0
.
0
f
,
distance
);
}
break
;
case
LXScrollingDirectionDown
:
{
CGFloat
maxY
=
MAX
(
contentSize
.
height
,
frameSize
.
height
)
-
frameSize
.
height
;
if
((
contentOffset
.
y
+
distance
)
>=
maxY
)
distance
=
maxY
-
contentOffset
.
y
;
translation
=
CGPointMake
(
0
.
0
f
,
distance
);
}
break
;
case
LXScrollingDirectionLeft
:
{
distance
=
-
distance
;
CGFloat
minX
=
0
.
0
f
;
if
((
contentOffset
.
x
+
distance
)
<=
minX
)
distance
=
-
contentOffset
.
x
;
translation
=
CGPointMake
(
distance
,
0
.
0
f
);
}
break
;
case
LXScrollingDirectionRight
:
{
CGFloat
maxX
=
MAX
(
contentSize
.
width
,
frameSize
.
width
)
-
frameSize
.
width
;
if
((
contentOffset
.
x
+
distance
)
>=
maxX
)
distance
=
maxX
-
contentOffset
.
x
;
translation
=
CGPointMake
(
distance
,
0
.
0
f
);
}
break
;
default:
{
// Do nothing...
}
break
;
}
_currentViewCenter
=
LXS_CGPointAdd
(
_currentViewCenter
,
translation
);
_currentView
.
center
=
LXS_CGPointAdd
(
_currentViewCenter
,
_panTranslationInCollectionView
);
self
.
collectionView
.
contentOffset
=
LXS_CGPointAdd
(
contentOffset
,
translation
);
}
-
(
void
)
handlePanGesture
:(
UIPanGestureRecognizer
*
)
gestureRecognizer
{
//keeps the controller from dragging while not in editmode
if
(
!
((
VLCPlaylistViewController
*
)
self
.
delegate
).
isEditing
)
return
;
switch
(
gestureRecognizer
.
state
)
{
case
UIGestureRecognizerStateBegan
:
{
NSIndexPath
*
currentIndexPath
=
[
self
.
collectionView
indexPathForItemAtPoint
:[
gestureRecognizer
locationInView
:
self
.
collectionView
]];
_selectedItemIndexPath
=
currentIndexPath
;
UICollectionViewCell
*
collectionViewCell
=
[
self
.
collectionView
cellForItemAtIndexPath
:
_selectedItemIndexPath
];
_currentView
=
[[
UIView
alloc
]
initWithFrame
:
collectionViewCell
.
frame
];
collectionViewCell
.
highlighted
=
YES
;
UIImageView
*
highlightedImageView
=
[[
UIImageView
alloc
]
initWithImage
:[
collectionViewCell
LX_rasterizedImage
]];
highlightedImageView
.
autoresizingMask
=
UIViewAutoresizingFlexibleWidth
|
UIViewAutoresizingFlexibleHeight
;
highlightedImageView
.
alpha
=
1
.
0
f
;
collectionViewCell
.
highlighted
=
NO
;
UIImageView
*
imageView
=
[[
UIImageView
alloc
]
initWithImage
:[
collectionViewCell
LX_rasterizedImage
]];
imageView
.
autoresizingMask
=
UIViewAutoresizingFlexibleWidth
|
UIViewAutoresizingFlexibleHeight
;
imageView
.
alpha
=
0
.
0
f
;
[
_currentView
addSubview
:
imageView
];
[
_currentView
addSubview
:
highlightedImageView
];
[
self
.
collectionView
addSubview
:
_currentView
];
_currentViewCenter
=
_currentView
.
center
;
[
UIView
animateWithDuration:
0
.
3
delay:
0
.
0
options:
UIViewAnimationOptionBeginFromCurrentState
animations:
^
{
_currentView
.
transform
=
CGAffineTransformMakeScale
(
1
.
1
f
,
1
.
1
f
);
highlightedImageView
.
alpha
=
0
.
0
f
;
imageView
.
alpha
=
1
.
0
f
;
}
completion:
^
(
BOOL
finished
)
{
[
highlightedImageView
removeFromSuperview
];
}];
[
self
invalidateLayout
];
break
;
}
case
UIGestureRecognizerStateChanged
:
{
_panTranslationInCollectionView
=
[
gestureRecognizer
translationInView
:
self
.
collectionView
];
CGPoint
viewCenter
=
_currentView
.
center
=
LXS_CGPointAdd
(
_currentViewCenter
,
_panTranslationInCollectionView
);
[
self
invalidateLayoutIfNecessary
];
switch
(
self
.
scrollDirection
)
{
case
UICollectionViewScrollDirectionVertical
:
{
if
(
viewCenter
.
y
<
(
CGRectGetMinY
(
self
.
collectionView
.
bounds
)
+
self
.
scrollingTriggerEdgeInsets
.
top
))
{
[
self
setupScrollTimerInDirection
:
LXScrollingDirectionUp
];
}
else
{
if
(
viewCenter
.
y
>
(
CGRectGetMaxY
(
self
.
collectionView
.
bounds
)
-
self
.
scrollingTriggerEdgeInsets
.
bottom
))
{
[
self
setupScrollTimerInDirection
:
LXScrollingDirectionDown
];
}
else
{
[
self
invalidatesScrollTimer
];
}
}
}
break
;
case
UICollectionViewScrollDirectionHorizontal
:
{
if
(
viewCenter
.
x
<
(
CGRectGetMinX
(
self
.
collectionView
.
bounds
)
+
self
.
scrollingTriggerEdgeInsets
.
left
))
{
[
self
setupScrollTimerInDirection
:
LXScrollingDirectionLeft
];
}
else
{
if
(
viewCenter
.
x
>
(
CGRectGetMaxX
(
self
.
collectionView
.
bounds
)
-
self
.
scrollingTriggerEdgeInsets
.
right
))
{
[
self
setupScrollTimerInDirection
:
LXScrollingDirectionRight
];
}
else
{
[
self
invalidatesScrollTimer
];
}
}
}
break
;
}
}
break
;
case
UIGestureRecognizerStateCancelled
:
case
UIGestureRecognizerStateEnded
:
{
[
_folderView
removeFromSuperview
];
_folderView
=
nil
;
NSIndexPath
*
newIndexPath
=
[
self
.
collectionView
indexPathForItemAtPoint
:
_currentView
.
center
];
NSIndexPath
*
currentIndexPath
=
_selectedItemIndexPath
;
if
(
newIndexPath
!=
nil
&&
!
[
currentIndexPath
isEqual
:
newIndexPath
])
{
[
UIView
animateWithDuration
:
0
.
3
delay
:
0
.
0
options
:
UIViewAnimationOptionBeginFromCurrentState
animations
:^
{
_currentView
.
transform
=
CGAffineTransformMakeScale
(
0
.
1
f
,
0
.
1
f
);
_currentView
.
center
=
[
self
layoutAttributesForItemAtIndexPath
:
newIndexPath
].
center
;
}
completion
:^
(
BOOL
finished
)
{
[
self
.
delegate
collectionView
:
self
.
collectionView
requestToMoveItemAtIndexPath
:
currentIndexPath
intoFolderAtIndexPath
:
newIndexPath
];
_selectedItemIndexPath
=
nil
;
_currentViewCenter
=
CGPointZero
;
[
_currentView
removeFromSuperview
];
_currentView
=
nil
;
}];
}
else
if
(
currentIndexPath
)
{
[
UIView
animateWithDuration
:
0
.
3
delay
:
0
.
0
options
:
UIViewAnimationOptionBeginFromCurrentState
animations
:^
{
_currentView
.
center
=
[
self
layoutAttributesForItemAtIndexPath
:
currentIndexPath
].
center
;
}
completion
:^
(
BOOL
finished
)
{
_selectedItemIndexPath
=
nil
;
_currentViewCenter
=
CGPointZero
;
[
_currentView
removeFromSuperview
];
_currentView
=
nil
;
[
self
invalidateLayout
];
}];
}
[
self
invalidatesScrollTimer
];
}
break
;
default:
{
// Do nothing...
}
break
;
}
}
#pragma mark - UICollectionViewLayout overridden methods
-
(
NSArray
*
)
layoutAttributesForElementsInRect
:(
CGRect
)
rect
{
NSArray
*
layoutAttributesForElementsInRect
=
[
super
layoutAttributesForElementsInRect
:
rect
];
for
(
UICollectionViewLayoutAttributes
*
layoutAttributes
in
layoutAttributesForElementsInRect
)
{
switch
(
layoutAttributes
.
representedElementCategory
)
{
case
UICollectionElementCategoryCell
:
{
[
self
applyLayoutAttributes
:
layoutAttributes
];
}
break
;
default:
{
// Do nothing...
}
break
;
}
}
return
layoutAttributesForElementsInRect
;
}
-
(
UICollectionViewLayoutAttributes
*
)
layoutAttributesForItemAtIndexPath
:(
NSIndexPath
*
)
indexPath
{
UICollectionViewLayoutAttributes
*
layoutAttributes
=
[
super
layoutAttributesForItemAtIndexPath
:
indexPath
];
switch
(
layoutAttributes
.
representedElementCategory
)
{
case
UICollectionElementCategoryCell
:
{
[
self
applyLayoutAttributes
:
layoutAttributes
];
}
break
;
default:
{
// Do nothing...
}
break
;
}
return
layoutAttributes
;
}
#pragma mark - Key-Value Observing methods
-
(
void
)
observeValueForKeyPath
:(
NSString
*
)
keyPath
ofObject
:(
id
)
object
change
:(
NSDictionary
*
)
change
context
:(
void
*
)
context
{
if
([
keyPath
isEqualToString
:
kLXCollectionViewKeyPath
])
{
if
(
self
.
collectionView
!=
nil
)
{
[
self
setupCollectionView
];
}
else
{
[
self
invalidatesScrollTimer
];
}
}
}
#pragma mark - Notifications
-
(
void
)
handleApplicationWillResignActive
:(
NSNotification
*
)
notification
{
self
.
panGestureRecognizer
.
enabled
=
NO
;
self
.
panGestureRecognizer
.
enabled
=
YES
;
}
@end
Sources/VLCPlaylistCollectionViewCell.h
View file @
6f5a9002
...
...
@@ -30,5 +30,6 @@
-
(
void
)
setEditing
:(
BOOL
)
editing
animated
:(
BOOL
)
animated
;
-
(
void
)
selectionUpdate
;
-
(
void
)
shake
:(
BOOL
)
shake
;
@end
Sources/VLCPlaylistCollectionViewCell.m
View file @
6f5a9002
...
...
@@ -8,6 +8,7 @@
* Authors: Felix Paul Kühne <fkuehne # videolan.org>
* Tamas Timar <ttimar.vlc # gmail.com>
* Gleb Pinigin <gpinigin # gmail.com>
* Carola Nitz <nitz.carola # googlemail.com>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
...
...
@@ -40,6 +41,8 @@
-
(
void
)
setEditing
:(
BOOL
)
editing
animated
:(
BOOL
)
animated
{
self
.
isSelectedView
.
hidden
=
!
editing
;
if
([
_mediaObject
isKindOfClass
:[
MLLabel
class
]]
||
[
_mediaObject
.
labels
count
]
==
0
)
[
self
shake
:
editing
];
[
self
selectionUpdate
];
[
self
_updatedDisplayedInformationForKeyPath
:
@"editing"
];
}
...
...
@@ -52,6 +55,32 @@
self
.
isSelectedView
.
image
=
_checkboxEmptyImage
;
}
-
(
void
)
shake
:(
BOOL
)
shake
{
if
(
shake
)
{
[
UIView
animateWithDuration
:
0
.
3
animations
:
^
{
self
.
contentView
.
transform
=
CGAffineTransformMakeScale
(
0
.
9
f
,
0
.
9
f
);
}];
CAKeyframeAnimation
*
animation
=
[
CAKeyframeAnimation
animationWithKeyPath
:
@"transform.rotation.z"
];
CGFloat
shakeAngle
=
0
.
02
f
;
animation
.
values
=
@[
@
(
-
shakeAngle
),
@
(
shakeAngle
)];
animation
.
autoreverses
=
YES
;
animation
.
duration
=
0
.
125
;
animation
.
repeatCount
=
HUGE_VALF
;
[[
self
layer
]
addAnimation
:
animation
forKey
:
@"shakeAnimation"
];
self
.
contentView
.
layer
.
cornerRadius
=
10
.
0
;
self
.
contentView
.
clipsToBounds
=
YES
;
}
else
{
[
UIView
animateWithDuration
:
0
.
3
animations
:
^
{
self
.
contentView
.
transform
=
CGAffineTransformMakeScale
(
1
.
0
f
,
1
.
0
f
);
self
.
contentView
.
layer
.
cornerRadius
=
0
.
0
;
self
.
contentView
.
clipsToBounds
=
NO
;
}];
[[
self
layer
]
removeAnimationForKey
:
@"shakeAnimation"
];
}
}
-
(
void
)
observeValueForKeyPath
:(
NSString
*
)
keyPath
ofObject
:(
id
)
object
change
:(
NSDictionary
*
)
change
context
:(
void
*
)
context
{
[
self
_updatedDisplayedInformationForKeyPath
:
keyPath
];
...
...
@@ -97,12 +126,50 @@
-
(
void
)
_updatedDisplayedInformationForKeyPath
:(
NSString
*
)
keyPath
{
BOOL
isFolder
=
[
self
.
mediaObject
isKindOfClass
:[
MLLabel
class
]];
self
.
thumbnailView
.
contentMode
=
isFolder
?
UIViewContentModeScaleAspectFit
:
UIViewContentModeScaleAspectFill
;
if
([
self
.
mediaObject
isKindOfClass
:[
MLFile
class
]])
{
MLFile
*
mediaObject
=
self
.
mediaObject
;
[
self
_configureForMLFile
:
mediaObject
];
if
(([
keyPath
isEqualToString
:
@"computedThumbnail"
]
||
!
keyPath
)
||
(
!
self
.
thumbnailView
.
image
&&
[
keyPath
isEqualToString
:
@"editing"
]))
self
.
thumbnailView
.
image
=
[
VLCThumbnailsCache
thumbnailForMediaFile
:
mediaObject
];
}
else
if
([
self
.
mediaObject
isKindOfClass
:[
MLLabel
class
]])
{
MLLabel
*
mediaObject
=
(
MLLabel
*
)
self
.
mediaObject
;
[
self
_configureForFolder
:
mediaObject
];
if
(([
keyPath
isEqualToString
:
@"computedThumbnail"
]
||
!
keyPath
)
||
(
!
self
.
thumbnailView
.
image
&&
[
keyPath
isEqualToString
:
@"editing"
]))
{
NSUInteger
fileNumber
=
[
mediaObject
.
files
count
]
>
3
?
3
:
[
mediaObject
.
files
count
];
if
(
fileNumber
==
0
)
{
self
.
thumbnailView
.
image
=
[
UIImage
imageNamed
:
@"folderIcon"
];
}
else
{
NSArray
*
files
=
[
mediaObject
.
files
allObjects
];
CGSize
frameSize
=
self
.
thumbnailView
.
frame
.
size
;
UIImage
*
displayedImage
;
UIGraphicsBeginImageContext
(
frameSize
);
for
(
NSUInteger
i
=
0
;
i
<
fileNumber
;
i
++
)
{
MLFile
*
file
=
[
files
objectAtIndex
:
i
];
displayedImage
=
[
VLCThumbnailsCache
thumbnailForMediaFile
:
file
];
CGContextRef
context
=
UIGraphicsGetCurrentContext
();
CGFloat
imagePartWidth
=
(
frameSize
.
width
/
fileNumber
);
//the rect in which the image should be drawn
CGRect
clippingRect
=
CGRectMake
(
imagePartWidth
*
i
,
0
,
imagePartWidth
,
frameSize
.
height
);
CGContextSaveGState
(
context
);
CGContextClipToRect
(
context
,
clippingRect
);
//take the center of the clippingRect and calculate the offset from the original center
CGFloat
centerOffset
=
(
imagePartWidth
*
i
+
imagePartWidth
/
2
)
-
frameSize
.
width
/
2
;
//shift the rect to draw the middle of the image in the clippingrect
CGRect
drawingRect
=
CGRectMake
(
centerOffset
,
0
,
frameSize
.
width
,
frameSize
.
height
);
[
displayedImage
drawInRect
:
drawingRect
];
//get rid of the old clippingRect
CGContextRestoreGState
(
context
);
}
displayedImage
=
UIGraphicsGetImageFromCurrentImageContext
();
UIGraphicsEndImageContext
();
self
.
thumbnailView
.
image
=
displayedImage
;
}
}
}
else
if
([
self
.
mediaObject
isKindOfClass
:[
MLAlbum
class
]])
{
MLAlbum
*
mediaObject
=
(
MLAlbum
*
)
self
.
mediaObject
;
[
self
_configureForAlbum
:
mediaObject
];
...
...
@@ -174,7 +241,6 @@
self
.
subtitleLabel
.
text
=
[
NSString
stringWithFormat
:
@"%@"
,
[
VLCTime
timeWithNumber
:[
anyFileFromEpisode
duration
]]];
}
else
self
.
subtitleLabel
.
text
=
[
NSString
stringWithFormat
:
@"S%02dE%02d — %@"
,
showEpisode
.
seasonNumber
.
intValue
,
showEpisode
.
episodeNumber
.
intValue
,
[
VLCTime
timeWithNumber
:[
anyFileFromEpisode
duration
]]];
[
self
_showPositionOfItem
:
anyFileFromEpisode
];
}
...
...
@@ -196,6 +262,15 @@
self
.
progressView
.
hidden
=
YES
;
}
-
(
void
)
_configureForFolder
:(
MLLabel
*
)
label
{
self
.
titleLabel
.
text
=
label
.
name
;
NSUInteger
count
=
label
.
files
.
count
;
self
.
subtitleLabel
.
text
=
[
NSString
stringWithFormat
:(
count
==
1
)
?
NSLocalizedString
(
@"LIBRARY_TRACKS"
,
@""
)
:
NSLocalizedString
(
@"LIBRARY_SINGLE_TRACK"
,
@""
),
count
];
self
.
mediaIsUnreadView
.
hidden
=
YES
;
self
.
progressView
.
hidden
=
YES
;
}
-
(
void
)
_configureForMLFile
:(
MLFile
*
)
mediaFile
{
if
(
mediaFile
.
isAlbumTrack
)
{
...
...
@@ -221,7 +296,6 @@
self
.
subtitleLabel
.
text
=
[
self
.
subtitleLabel
.
text
stringByAppendingFormat
:
@" — %@x%@"
,
width
,
height
];
}
}
[
self
_showPositionOfItem
:
mediaFile
];
}
...
...
Sources/VLCPlaylistTableViewCell.m
View file @
6f5a9002
...
...
@@ -7,6 +7,7 @@
*
* Authors: Felix Paul Kühne <fkuehne # videolan.org>
* Gleb Pinigin <gpinigin # gmail.com>
* Carola Nitz <nitz.carola #googlemail.com>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
...
...
@@ -84,12 +85,57 @@