marinofaggiana 5 年之前
父节点
当前提交
da73d56173

+ 0 - 24
Nextcloud.xcodeproj/project.pbxproj

@@ -364,10 +364,6 @@
 		F769454822E9F20D000A798A /* NCShareNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F769454722E9F20D000A798A /* NCShareNetworking.swift */; };
 		F76B3CCE1EAE01BD00921AC9 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; };
 		F76B3CCF1EAE01BD00921AC9 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; };
-		F76FA86D2406B9F90003D339 /* NCViewerPhotoTileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76FA8692406B9F90003D339 /* NCViewerPhotoTileManager.swift */; };
-		F76FA86E2406B9F90003D339 /* NCViewerPhotoTilingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76FA86A2406B9F90003D339 /* NCViewerPhotoTilingView.swift */; };
-		F76FA86F2406B9F90003D339 /* NCViewerPhotoImageScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76FA86B2406B9F90003D339 /* NCViewerPhotoImageScrollView.swift */; };
-		F76FA8712406BE910003D339 /* NCViewerPhotoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76FA8702406BE910003D339 /* NCViewerPhotoView.swift */; };
 		F771E3D320E2392D00AFB62D /* FileProviderExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F771E3D220E2392D00AFB62D /* FileProviderExtension.swift */; };
 		F771E3D520E2392D00AFB62D /* FileProviderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F771E3D420E2392D00AFB62D /* FileProviderItem.swift */; };
 		F771E3D720E2392D00AFB62D /* FileProviderEnumerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F771E3D620E2392D00AFB62D /* FileProviderEnumerator.swift */; };
@@ -1068,10 +1064,6 @@
 		F76C3B881C638A4C00DC4301 /* CCError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCError.m; sourceTree = "<group>"; };
 		F76E71E42244DF6900690001 /* Zip.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Zip.framework; path = Carthage/Build/iOS/Zip.framework; sourceTree = "<group>"; };
 		F76F23321ED4600700C40023 /* Share-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Share-Bridging-Header.h"; sourceTree = "<group>"; };
-		F76FA8692406B9F90003D339 /* NCViewerPhotoTileManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerPhotoTileManager.swift; sourceTree = "<group>"; };
-		F76FA86A2406B9F90003D339 /* NCViewerPhotoTilingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerPhotoTilingView.swift; sourceTree = "<group>"; };
-		F76FA86B2406B9F90003D339 /* NCViewerPhotoImageScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerPhotoImageScrollView.swift; sourceTree = "<group>"; };
-		F76FA8702406BE910003D339 /* NCViewerPhotoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerPhotoView.swift; sourceTree = "<group>"; };
 		F771E3D020E2392D00AFB62D /* File Provider Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "File Provider Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
 		F771E3D220E2392D00AFB62D /* FileProviderExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderExtension.swift; sourceTree = "<group>"; };
 		F771E3D420E2392D00AFB62D /* FileProviderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderItem.swift; sourceTree = "<group>"; };
@@ -2097,17 +2089,6 @@
 			path = Section;
 			sourceTree = "<group>";
 		};
-		F76FA8672406B9F90003D339 /* NCViewerPhoto */ = {
-			isa = PBXGroup;
-			children = (
-				F76FA8702406BE910003D339 /* NCViewerPhotoView.swift */,
-				F76FA8692406B9F90003D339 /* NCViewerPhotoTileManager.swift */,
-				F76FA86A2406B9F90003D339 /* NCViewerPhotoTilingView.swift */,
-				F76FA86B2406B9F90003D339 /* NCViewerPhotoImageScrollView.swift */,
-			);
-			path = NCViewerPhoto;
-			sourceTree = "<group>";
-		};
 		F771E3D120E2392D00AFB62D /* File Provider Extension */ = {
 			isa = PBXGroup;
 			children = (
@@ -2187,7 +2168,6 @@
 		F79630EC215526B60015EEA5 /* Viewer */ = {
 			isa = PBXGroup;
 			children = (
-				F76FA8672406B9F90003D339 /* NCViewerPhoto */,
 				F72D404823D2082500A97FD0 /* NCViewerNextcloudText.swift */,
 				F710D1F42405770F00A6033D /* NCViewerPDF.swift */,
 				F790110D21415BF600D7B136 /* NCViewerRichdocument.swift */,
@@ -3406,7 +3386,6 @@
 				F762CB001EACB66200B38484 /* XLFormSegmentedCell.m in Sources */,
 				F732BA061D76CE1500E9878B /* CCNetworking.m in Sources */,
 				F762CB061EACB66200B38484 /* XLFormTextViewCell.m in Sources */,
-				F76FA86F2406B9F90003D339 /* NCViewerPhotoImageScrollView.swift in Sources */,
 				F78ACD4221903CE00088454D /* NCListCell.swift in Sources */,
 				F78ACD4F2190440D0088454D /* NCLayout.swift in Sources */,
 				F760F79C21F21F61006B1A73 /* GradientView.swift in Sources */,
@@ -3561,7 +3540,6 @@
 				F7B7504B2397D38F004E13EC /* UIImage+fixedOrientation.swift in Sources */,
 				F77B0EA61D118A16002130FE /* NSString+TruncateToWidth.m in Sources */,
 				F70022C21EC4C9100080073F /* OCNotifications.m in Sources */,
-				F76FA86D2406B9F90003D339 /* NCViewerPhotoTileManager.swift in Sources */,
 				F70022BF1EC4C9100080073F /* OCFileDto.m in Sources */,
 				F7CA1ED020E7E3FE002CC65E /* UIImage+PKDownloadButton.m in Sources */,
 				F7D2D127230804E000FD3ED7 /* NCXMLListParser.m in Sources */,
@@ -3593,7 +3571,6 @@
 				F73B4F0C1F470D9100BBEE4B /* nsHebrewProber.cpp in Sources */,
 				F762CAFB1EACB66200B38484 /* XLFormDatePickerCell.m in Sources */,
 				F762CB0F1EACB66200B38484 /* NSObject+XLFormAdditions.m in Sources */,
-				F76FA8712406BE910003D339 /* NCViewerPhotoView.swift in Sources */,
 				F7B2DEF01F976854007CF4D2 /* NYMnemonic.m in Sources */,
 				F707C26521A2DC5200F6181E /* NCStoreReview.swift in Sources */,
 				F73B4EFF1F470D9100BBEE4B /* LangRussianModel.cpp in Sources */,
@@ -3623,7 +3600,6 @@
 				F762CB091EACB66200B38484 /* XLFormViewController.m in Sources */,
 				F760F79621F21F61006B1A73 /* PhotoEditorViewController.swift in Sources */,
 				F762CB161EACB66200B38484 /* XLFormTextView.m in Sources */,
-				F76FA86E2406B9F90003D339 /* NCViewerPhotoTilingView.swift in Sources */,
 				F70CEF5623E9C7E50007035B /* UIColor+adjust.swift in Sources */,
 				F75AC2431F1F62450073EC19 /* NCManageAutoUploadFileName.swift in Sources */,
 				F79630EE215527D40015EEA5 /* NCViewerMedia.swift in Sources */,

+ 1 - 7
iOSClient/Main/NCDetailViewController.swift

@@ -33,7 +33,6 @@ class NCDetailViewController: UIViewController {
     @objc var selector: String?
     
     private let appDelegate = UIApplication.shared.delegate as! AppDelegate
-    private var viewerPhotoView: NCViewerPhotoView?
     
     required init?(coder: NSCoder) {
         super.init(coder: coder)
@@ -67,11 +66,8 @@ class NCDetailViewController: UIViewController {
     
     override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
         super.viewWillTransition(to: size, with: coordinator)
-        
-        viewerPhotoView?.saveCurrentStatesForRotation()
-        
+                
         coordinator.animate(alongsideTransition: nil) { _ in
-            self.viewerPhotoView?.restoreStatesForRotation(in: size)
         }
     }
     
@@ -117,8 +113,6 @@ class NCDetailViewController: UIViewController {
         
         // IMAGE
         if metadata.typeFile == k_metadataTypeFile_image {
-            viewerPhotoView = NCViewerPhotoView.init(frame: backgroundView.frame)
-            viewerPhotoView?.setup(metadata: metadata, view: backgroundView)
             return
         }
         

+ 0 - 243
iOSClient/Viewer/NCViewerPhoto/NCViewerPhotoImageScrollView.swift

@@ -1,243 +0,0 @@
-import UIKit
-
-class NCViewerPhotoImageScrollView: UIScrollView, UIScrollViewDelegate {
-	
-	var index: Int!
-	var zoomView: UIImageView!
-	var tilingView: NCViewerPhotoTilingView?
-	
-	lazy var zoomingTap: UITapGestureRecognizer = {
-		let zoomingTap = UITapGestureRecognizer(target: self, action: #selector(handleZoomingTap(_:)))
-		zoomingTap.numberOfTapsRequired = 2
-		
-		return zoomingTap
-	}()
-
-	override init(frame: CGRect) {
-		super.init(frame: frame)
-		
-		self.showsHorizontalScrollIndicator = false
-		self.showsVerticalScrollIndicator = false
-        self.decelerationRate = UIScrollView.DecelerationRate.fast
-		self.delegate = self
-	}
-	
-	required init?(coder aDecoder: NSCoder) {
-		fatalError("init(coder:) has not been implemented")
-	}
-	
-	override func layoutSubviews() {
-		super.layoutSubviews()
-		self.centerImage()
-	}
-	
-	//MARK: - Configure scrollView to display new image
-	func display(_ image: UIImage) {
-		
-		//1. clear the previous image
-		zoomView?.removeFromSuperview()
-		zoomView = nil
-				
-		//2. make a new UIImageView for the new image
-		zoomView = UIImageView(image: image)
-		
-		self.addSubview(zoomView)
-		
-		self.configureFor(image.size)
-	}
-	
-	func displayTiledImage(in url: URL, size imageSize: CGSize) {
-		
-		// clear views for the previous image
-		zoomView?.removeFromSuperview()
-		zoomView = nil
-		tilingView = nil
-		
-		// make views to display the new image
-		zoomView = UIImageView(frame: CGRect(origin: CGPoint.zero, size: imageSize))
-		let image = placeholderImage(in: url)
-		zoomView.image = image
-		self.addSubview(zoomView)
-		
-		self.tilingView = NCViewerPhotoTilingView(in: url, size: imageSize)
-		self.zoomView?.addSubview(self.tilingView!)
-		
-		self.configureFor(imageSize)
-	}
-
-	
-	func configureFor(_ imageSize: CGSize) {
-		self.contentSize = imageSize
-		self.setMaxMinZoomScaleForCurrentBounds()
-		self.zoomScale = self.minimumZoomScale
-		
-		//Enable zoom tap
-		self.zoomView.addGestureRecognizer(self.zoomingTap)
-		self.zoomView.isUserInteractionEnabled = true
-	}
-	
-	func setMaxMinZoomScaleForCurrentBounds() {
-		let boundsSize = self.bounds.size
-		let imageSize = zoomView.bounds.size
-		
-		//1. calculate minimumZoomscale
-		let xScale =  boundsSize.width  / imageSize.width    // the scale needed to perfectly fit the image width-wise
-		let yScale = boundsSize.height / imageSize.height  // the scale needed to perfectly fit the image height-wise
-		
-		let minScale = min(xScale, yScale)                 // use minimum of these to allow the image to become fully visible
-		
-		//2. calculate maximumZoomscale
-		var maxScale: CGFloat = 1.0
-		
-		if minScale < 0.1 {
-			maxScale = 0.3
-		}
-		
-		if minScale >= 0.1 && minScale < 0.5 {
-			maxScale = 0.7
-		}
-		
-		if minScale >= 0.5 {
-			maxScale = max(1.0, minScale)
-		}
-		
-		
-		self.maximumZoomScale = maxScale
-		self.minimumZoomScale = minScale
-	}
-	
-	func centerImage() {
-		// center the zoom view as it becomes smaller than the size of the screen
-		let boundsSize = self.bounds.size
-		var frameToCenter = zoomView?.frame ?? CGRect.zero
-		
-		// center horizontally
-		if frameToCenter.size.width < boundsSize.width {
-			frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width)/2
-		}
-		else {
-			frameToCenter.origin.x = 0
-		}
-		
-		// center vertically
-		if frameToCenter.size.height < boundsSize.height {
-			frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height)/2
-		}
-		else {
-			frameToCenter.origin.y = 0
-		}
-		
-		zoomView?.frame = frameToCenter
-	}
-
-	//MARK: - UIScrollView Delegate Methods
-	
-	func viewForZooming(in scrollView: UIScrollView) -> UIView? {
-		return self.zoomView
-	}
-	
-	func scrollViewDidZoom(_ scrollView: UIScrollView) {
-		self.centerImage()
-	}
-	
-	//MARK: - Methods called during rotation to preserve the zoomScale and the visible portion of the image
-	
-	// returns the center point, in image coordinate space, to try restore after rotation.
-	func pointToCenterAfterRotation() -> CGPoint {
-		let boundsCenter = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
-		return self.convert(boundsCenter, to: zoomView)
-	}
-	
-	// returns the zoom scale to attempt to restore after rotation.
-	func scaleToRestoreAfterRotation() -> CGFloat {
-		var contentScale = self.zoomScale
-		
-		// If we're at the minimum zoom scale, preserve that by returning 0, which will be converted to the minimum
-		// allowable scale when the scale is restored.
-		if contentScale <= self.minimumZoomScale + CGFloat.ulpOfOne {
-			contentScale = 0
-		}
-		
-		return contentScale
-	}
-	
-	func maximumContentOffset() -> CGPoint {
-		let contentSize = self.contentSize
-		let boundSize = self.bounds.size
-		return CGPoint(x: contentSize.width - boundSize.width, y: contentSize.height - boundSize.height)
-	}
-	
-	func minimumContentOffset() -> CGPoint {
-		
-		return CGPoint.zero
-	}
-	
-	func restoreCenterPoint(to oldCenter: CGPoint, oldScale: CGFloat) {
-		
-		// Step 1: restore zoom scale, first making sure it is within the allowable range.
-		self.zoomScale = min(self.maximumZoomScale, max(self.minimumZoomScale, oldScale))
-		
-		
-		// Step 2: restore center point, first making sure it is within the allowable range.
-		
-		// 2a: convert our desired center point back to our own coordinate space
-		let boundsCenter = self.convert(oldCenter, from: zoomView)
-		// 2b: calculate the content offset that would yield that center point
-		var offset = CGPoint(x: boundsCenter.x - self.bounds.size.width/2.0, y: boundsCenter.y - self.bounds.size.height/2.0)
-		// 2c: restore offset, adjusted to be within the allowable range
-		let maxOffset = self.maximumContentOffset()
-		let minOffset = self.minimumContentOffset()
-		offset.x = max(minOffset.x, min(maxOffset.x, offset.x))
-		offset.y = max(minOffset.y, min(maxOffset.y, offset.y))
-		self.contentOffset = offset
-	}
-
-	//MARK: - Handle ZoomTap
-	
-	@objc func handleZoomingTap(_ sender: UITapGestureRecognizer) {
-		let location = sender.location(in: sender.view)
-		self.zoom(to: location, animated: true)
-	}
-	
-	func zoom(to point: CGPoint, animated: Bool) {
-		let currentScale = self.zoomScale
-		let minScale = self.minimumZoomScale
-		let maxScale = self.maximumZoomScale
-		
-		if (minScale == maxScale && minScale > 1) {
-			return;
-		}
-		
-		let toScale = maxScale
-		let finalScale = (currentScale == minScale) ? toScale : minScale
-		let zoomRect = self.zoomRect(for: finalScale, withCenter: point)
-		self.zoom(to: zoomRect, animated: animated)
-	}
-	
-	
-	// The center should be in the imageView's coordinates
-	func zoomRect(for scale: CGFloat, withCenter center: CGPoint) -> CGRect {
-		var zoomRect = CGRect.zero
-		let bounds = self.bounds
-		
-		// the zoom rect is in the content view's coordinates.
-		//At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
-		//As the zoom scale decreases, so more content is visible, the size of the rect grows.
-		zoomRect.size.width = bounds.size.width / scale
-		zoomRect.size.height = bounds.size.height / scale
-		
-		// choose an origin so as to get the right center.
-		zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0)
-		zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0)
-		
-		return zoomRect
-	}
-	
-	func placeholderImage(in url: URL) -> UIImage? {
-		let name = url.deletingPathExtension().lastPathComponent
-		let imageName = "\(name)_Placeholder.jpg"
-		let url = url.appendingPathComponent(imageName)
-		return UIImage(contentsOfFile: url.path)
-	}
-
-}

+ 0 - 758
iOSClient/Viewer/NCViewerPhoto/NCViewerPhotoTileManager.swift

@@ -1,758 +0,0 @@
-
-import Foundation
-import UIKit
-
-public struct NCViewerPhotoTileManager {
-	
-	private enum TileMakerError: Error {
-		case destinationContextFailedToMakeImage
-		case inputImageNotFound
-		case failedToCreateTheOutputBitmapContext
-	}
-	
-	private let destImageSizeMB: Int // The resulting image will be (x)MB of uncompressed image data.
-	private let sourceImageTileSizeMB: Int // The tile size will be (x)MB of uncompressed image data.
-	private let tileSize: Int
-	
-	/* Constants for all other iOS devices are left to be defined by the developer.
-	The purpose of this sample is to illustrate that device specific constants can
-	and should be created by you the developer, versus iterating a complete list. */
-	
-	private let bytesPerMB: Int = 1048576
-	private let bytesPerPixel: Int = 4
-	
-	
-	private var pixelsPerMB: Int {
-		return ( bytesPerMB / bytesPerPixel ) // 262144 pixels, for 4 bytes per pixel.
-	}
-	
-	private var destTotalPixels: Int {
-		return destImageSizeMB * pixelsPerMB
-	}
-	
-	private var tileTotalPixels: Int {
-		return sourceImageTileSizeMB * pixelsPerMB
-	}
-	
-	private let destSeamOverlap: Float = 2 // the numbers of pixels to overlap the seams where tiles meet.
-	
-	private let fileManager = FileManager.default
-	
-	/**
-		A Boolean value that controls whether the sourceimage will be down sized or not.
-	
-		If the value of this property is true, the source image be down sized.
-		The default value is true.
-	*/
-	public  var downSizeSourceImage: Bool = true
-
-	
-	/**
-	Initializes and returns a newly struct with the specified parameters.
-	The methods of this struct uses to manage tiles.
-	
-	 - Parameters:
-	   - destImageSize:
-			The maximum size of destination image in MB when uncomperessed in memory.
-			The value should be smaller than uncompressed size of source image in memory.
-			If you set a value bigger than the original size of source image for this parameter,
-			the original size of image uses for tiling. To know how is the size of source image
-			when uncomperessed in memory use **totalMBForImage(in url: URL)** method.
-			The default value of this parameter is 60.
-	
-	   - sourceImageDownSizingTileSize:
-			The size of tiles for down sizing the source image in MB,  if you want to down size of source image.
-			This argument is  because of that, we do not want to down size whole of source image instantly,
-			because that needs to load whole of source image in memory and it occupies a lot of memory.
-			Instead we shrink the source image to some small tiles and down size these tiles in order.
-			You should be careful about setting value of this parameter. Setting very small value causes high cpu
-			usage and setting very large value causes high memory usage. The default value of this parameter is 20.
-	
-	   - tileSize:
-			The size of each tile used for CATiledLayer. The default value is 256.
-	
-	- Returns:
-		An initialized struct.
-	*/
-
-	public init(destImageSize: Int = 60, sourceImageDownSizingTileSize: Int = 20, tileSize: Int = 256) {
-		self.destImageSizeMB = destImageSize
-		self.sourceImageTileSizeMB = sourceImageDownSizingTileSize
-		self.tileSize = tileSize
-	}
-	
-	/**
-	A method for getting the url of tiles for each tiled image.
-	This method returns a directory url.
-	- Parameter imageName: name of image that needs its tiles url
-	- Returns: url of tiles respect to name of image passed.
-	*/
-	public func urlOfTiledImage(named imageName: String) -> URL {
-		
-		let destinationURL = fileManager.temporaryDirectory.appendingPathComponent("TileManager", isDirectory: true).appendingPathComponent(imageName, isDirectory: true)
-		if !fileManager.fileExists(atPath: destinationURL.path) {
-			
-			do {
-				
-				try fileManager.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)
-				
-			}
-			catch let error {
-				fatalError("cant create directory at \(destinationURL), cause error: \(error)")
-			}
-			
-		}
-		
-		return destinationURL
-	}
-	
-	/**
-	A method for getting placeholder image of each tiled image.
-	This placeholder is created the first time the tiles of each image being created.
-	- Parameter imageName: name of image that needs its placeholder image url
-	- Returns: url of placeholder image respect to name of image passed.
-	*/
-	public func urlOfPlaceholderOfImage(named imageName: String) -> URL? {
-		let directoryURL = urlOfTiledImage(named: imageName)
-		let imageName = "\(imageName)_Placeholder.jpg"
-		let url = directoryURL.appendingPathComponent(imageName)
-		if fileManager.fileExists(atPath: url.path) {
-			return url
-		}
-		return nil
-	}
-	
-	/**
-	Removes directory of tiles respect to each tiled image if exist.
-	- Parameter imageName: name of image that needs to remove its tiles.
-	*/
-	public func removeTilesForImage(named imageName: String) {
-		let url = urlOfTiledImage(named: imageName)
-		do {
-			try self.fileManager.removeItem(at: url)
-		}
-		catch {
-			print(error)
-		}
-	}
-	
-	/**
-	Removes directory of whole tiles that created for this app.
-	*/
-	public func clearCache() {
-		let tileManagerURL = fileManager.temporaryDirectory.appendingPathComponent("TileManager", isDirectory: true)
-		do {
-			try self.fileManager.removeItem(at: tileManagerURL)
-		}
-		catch {
-			print(error)
-		}
-	}
-	
-	/**
-	Checks whether it is needed to make tiles for the image that passed its url.
-	This method compares resolution of passed url's image with phone screen resolution
-	- Parameter url: The url of image that want to check its need to tiling.
-	- Returns: Returns true if image resolution is bigger than phone screen resolution otherwise
-			   returns false
-	*/
-	public func needsTilingImage(in url: URL) -> Bool {
-		do {
-			
-			let sourceResolution = try resolutionForImage(in: url)
-			
-			let sourceMaximumEdge: CGFloat = sourceResolution.width > sourceResolution.height ? sourceResolution.width : sourceResolution.height
-			
-			let screenTotalSize = UIScreen.main.bounds.size
-			let screenScale = UIScreen.main.scale
-			
-			let screenMinimumEdge: CGFloat = screenTotalSize.width < screenTotalSize.height ? screenTotalSize.width : screenTotalSize.height
-			
-			return sourceMaximumEdge > screenMinimumEdge*screenScale
-			
-		} catch {
-			print(error)
-		}
-		
-		return false
-	}
-
-	/**
-	Checks whether tiles made for the image that passed its url.
-	- Parameter imageName: name of image that needs to check.
-	- Returns: Returns true if tiles are exist for image that passed its url.
-	*/
-	public func tilesMadeForImage(named imageName: String) -> Bool {
-		 return urlOfImageInfoForImage(named: imageName) != nil
-	}
-	
-	/**
-	- Parameter imageName: name of image that needs its size.
-	- Returns: Returns the resolution size of image that its tiles are made. This value is saved in a **plist** file next to the tiles.
-	*/
-	public func sizeOfTiledImage(named imageName: String) -> CGSize? {
-		if let url = urlOfImageInfoForImage(named: imageName) {
-			let plist = NSArray(contentsOf: url)
-			if let dic = plist!.firstObject as? [String: Any] {
-				let width = dic["width"] as? CGFloat ?? 0
-				let height = dic["height"] as? CGFloat ?? 0
-				let size = CGSize(width: width, height: height)
-				return size
-			}
-		}
-		return nil
-	}
-	
-	
-	/**
-	- Parameter url: url of image that needs its resolution size.
-	- Returns: Returns the resolution size of image that passed its url.
-	*/
-	public func resolutionForImage(in url: URL) throws -> CGSize {
-		// create an image from the image filename constant. Note this
-		//  doesn't actually read any pixel information from disk, as that
-		// is actually done at draw time.
-		let path = url.path
-		
-		// The input image file
-		var sourceImage: UIImage?
-		sourceImage = UIImage(contentsOfFile: path)
-		guard  sourceImage != nil else {
-			throw TileMakerError.inputImageNotFound
-		}
-		
-		// get the width and height of the input image using
-		// core graphics image helper functions.
-		let sourceResolution = CGSize(width: CGFloat(sourceImage!.cgImage!.width), height: CGFloat(sourceImage!.cgImage!.height))
-		
-		return sourceResolution
-	}
-	
-	
-	/**
-	This method calculate that how would be the resolution of image that passed its url if it being down sized with the parameter of initializer.
-	- Parameter url: url of image that needs its resolution size.
-	- Returns: Returns the destination resolution size of image that passed its url.
-	*/
-	public func destinationResolutionForImage(in url: URL) throws -> CGSize {
-		do {
-			// get the width and height of the input image using
-			// core graphics image helper functions.
-			let sourceResolution = try self.resolutionForImage(in: url)
-			
-			// use the width and height to calculate the total number of pixels
-			// in the input image.
-			let sourceTotalPixels = sourceResolution.width * sourceResolution.height
-			
-			// determine the scale ratio to apply to the input image
-			// that results in an output image of the defined size.
-			// see destImageSizeMB, and how it relates to destTotalPixels.
-			
-			let imageScale: CGFloat = self.downSizeSourceImage ? CGFloat(self.destTotalPixels) / sourceTotalPixels : 1.0
-			
-			// use the image scale to calcualte the output image width, height
-			let destResolution = CGSize(width: sourceResolution.width * imageScale, height: sourceResolution.height * imageScale)
-			
-			return destResolution
-			
-		} catch let error {
-			
-			throw error
-		}
-	}
-	
-	/**
-	This method calculate that total size (in megabyte) of image that passed its url when it is uncompressed and loaded in memory.
-	- Parameter url: url of image that needs its total megabyte size in memory.
-	- Returns: Returns total megabyte size of image in memory.
-	*/
-	public func totalMBForImage(in url: URL) throws -> CGFloat {
-		do {
-			
-			// get the width and height of the input image using
-			// core graphics image helper functions.
-			let sourceResolution = try self.resolutionForImage(in: url)
-			
-			// use the width and height to calculate the total number of pixels
-			// in the input image.
-			let sourceTotalPixels = sourceResolution.width * sourceResolution.height
-			
-			// calculate the number of MB that would be required to store
-			// this image uncompressed in memory.
-			let sourceTotalMB = sourceTotalPixels / CGFloat(self.pixelsPerMB)
-			
-			return sourceTotalMB
-			
-		} catch let error {
-			
-			throw error
-		}
-	}
-	
-    /**
-	Down sizes, makes placeholder and Tiles for given image url.
-	
-	- Parameters:
-		- url: url of image that needs to make tiles for it
-		- placeholderCompletion:
-			A block to be executed when the making of placeholder ends. This block has no return value and takes url argument of created placeholder image and error argument for creating placholder. url may be nil if an error occurs about making placeholder. Error will be nil if no error occurs.
-	
-		- tilingCompletion:
-			A block to be executed when the making of tiles ends. This block has no return value and takes
-			three argument. An String and CGSize as name and size of tiled image, an error if some errors happened.
-			If an error occurs, String and CGSize arguments may be nil. If no error occurs, Error will be nil.
-	*/
-	public func makeTiledImage(for url: URL, placeholderCompletion: @escaping (URL?, Error?) -> Swift.Void, tilingCompletion: @escaping (String?, CGSize?, Error?) -> Swift.Void) {
-		// create an image from the image filename constant. Note this
-		// doesn't actually read any pixel information from disk, as that
-		// is actually done at draw time.
-		
-		// The input image file
-		guard let sourceImage = UIImage(contentsOfFile: url.path) else {
-			print("error: input image not found!")
-			DispatchQueue.main.async {
-				tilingCompletion(nil, nil, TileMakerError.inputImageNotFound)
-			}
-			return
-		}
-		
-		let imageNamePrefix = url.deletingPathExtension().lastPathComponent
-		
-		let destinationURL = self.urlOfTiledImage(named: imageNamePrefix)
-		
-		self.makePlaceholder(for: sourceImage.cgImage!, to: destinationURL, usingPrefix: imageNamePrefix) { (url, error) in
-			if error != nil {
-				DispatchQueue.main.async {
-					tilingCompletion(nil, nil, error)
-				}
-				return
-			}
-			else {
-				DispatchQueue.main.async {
-					placeholderCompletion(url, error)
-				}
-			}
-		}
-
-		self.downSize(sourceImage, completion: { (image, error) in
-			guard error == nil else {
-				DispatchQueue.main.async {
-					tilingCompletion(nil, nil, error)
-				}
-				return
-			}
-			
-			self.makeTiles(for: image!, to: destinationURL, usingPrefix: imageNamePrefix, tilingCompletion: { (imageName, imageSize, error) in
-				
-				DispatchQueue.main.async {
-					tilingCompletion(imageName, imageSize, error)
-				}
-			})
-			
-		})
-		
-	}
-	
-	/**
-	A method for getting url of **imageInfo.plist** that contains name, width and height of each tiled image.
-	This file is created the first time the tiles of each image being created.
-	- Parameter imageName: name of image that needs its imageInfo.plist file url
-	- Returns: url of imageInfo.plist respect to name of image passed.
-	*/
-	private func urlOfImageInfoForImage(named imageName: String) -> URL? {
-		let directoryURL = urlOfTiledImage(named: imageName)
-		print(directoryURL.path)
-		
-		let url = directoryURL.appendingPathComponent("imageInfo.plist")
-		return fileManager.fileExists(atPath: url.path) ? url : nil
-	}
-	
-	/**
-	Down size given image to an image with the size of megabyte that specified in initializer.
-	
-	- Parameters:
-	 	- sourceImage: The imgae want to downsize it
-	 	- completion:  A block to be executed when the down sizing ends. I takes two argument. the downsized image as CGImage and error. If an error occurs the CGImage may be nil. if no error occurs, Error will be nil.
-	*/
-	private func downSize(_ sourceImage: UIImage, completion: @escaping (CGImage?, Error?) -> ()) {
-		
-		/* the temporary container used to hold the resulting output image pixel
-		data, as it is being assembled. */
-		var destContext: CGContext!
-		
-		
-		DispatchQueue.global().async {
-			
-			autoreleasepool {
-				
-//				guard let sourceImage = UIImage(contentsOfFile: path) else {
-//					print("error: input image not found!")
-//					completion(nil, TileMakerError.inputImageNotFound)
-//					return
-//				}
-				
-				// get the width and height of the input image using
-				// core graphics image helper functions.
-				let sourceResolution = CGSize(width: CGFloat(sourceImage.cgImage!.width), height: CGFloat(sourceImage.cgImage!.height))
-				
-				// use the width and height to calculate the total number of pixels
-				// in the input image.
-				let sourceTotalPixels = sourceResolution.width * sourceResolution.height
-				
-				// calculate the number of MB that would be required to store
-				// this image uncompressed in memory.
-				let sourceTotalMB = sourceTotalPixels / CGFloat(self.pixelsPerMB)
-
-				// determine the scale ratio to apply to the input image
-				// that results in an output image of the defined size.
-				// see destImageSizeMB, and how it relates to destTotalPixels.
-				var imageScale: CGFloat = self.downSizeSourceImage ? CGFloat(self.destTotalPixels) / sourceTotalPixels : 1.0
-				
-				if Int(sourceTotalMB) <= self.destImageSizeMB {
-					imageScale = 1.0
-				}
-				
-				// use the image scale to calcualte the output image width, height
-				let destResolution = CGSize(width: sourceResolution.width * imageScale, height: sourceResolution.height * imageScale)
-				
-				// create an offscreen bitmap context that will hold the output image
-				// pixel data, as it becomes available by the downscaling routine.
-				// use the RGB colorspace as this is the colorspace iOS GPU is optimized for.
-				let colorSpace = CGColorSpaceCreateDeviceRGB()
-				let bytesPerRow = self.bytesPerPixel * Int(destResolution.width)
-				
-				
-				// create the output bitmap context
-				destContext = CGContext(data: nil, width: Int(destResolution.width), height: Int(destResolution.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
-				
-				// remember CFTypes assign/check for NULL. NSObjects assign/check for nil.
-				if destContext == nil {
-					completion(nil, TileMakerError.failedToCreateTheOutputBitmapContext)
-					print("error: failed to create the output bitmap context!")
-					return
-				}
-				
-				// flip the output graphics context so that it aligns with the
-				// cocoa style orientation of the input document. this is needed
-				// because we used cocoa's UIImage -imageNamed to open the input file.
-				destContext.translateBy(x: 0, y: destResolution.height)
-				destContext.scaleBy(x: 1, y: -1)
-				
-				// now define the size of the rectangle to be used for the
-				// incremental blits from the input image to the output image.
-				// we use a source tile width equal to the width of the source
-				// image due to the way that iOS retrieves image data from disk.
-				// iOS must decode an image from disk in full width 'bands', even
-				// if current graphics context is clipped to a subrect within that
-				// band. Therefore we fully utilize all of the pixel data that results
-				// from a decoding opertion by anchoring our tile size to the full
-				// width of the input image.
-				var sourceTile = CGRect.zero
-				sourceTile.size.width = sourceResolution.width
-				
-				// the source tile height is dynamic. Since we specified the size
-				// of the source tile in MB, see how many rows of pixels height
-				// can be given the input image width.
-				sourceTile.size.height = floor(CGFloat(self.tileTotalPixels) / sourceTile.size.width)
-				print("source tile size: \(sourceTile.size.width) x \(sourceTile.size.height)")
-				//			sourceTile.origin.x = 0.0
-				
-				// the output tile is the same proportions as the input tile, but
-				// scaled to image scale.
-				var destTile = CGRect.zero
-				destTile.size.width = destResolution.width
-				destTile.size.height = sourceTile.size.height * imageScale
-				//			destTile.origin.x = 0.0
-				
-				print("source tile size: \(sourceTile.size.width) x \(sourceTile.size.height)")
-				
-				// the SeamOverlap is the number of pixels to overlap tiles as they are assembled.
-				// the source seam overlap is proportionate to the destination seam overlap.
-				// this is the amount of pixels to overlap each tile as we assemble the ouput image.
-				let sourceSeamOverlap = floor((CGFloat(self.destSeamOverlap) / destResolution.height) * sourceResolution.height)
-				print("dest seam overlap: \(self.destSeamOverlap), source seam overlap: \(sourceSeamOverlap)")
-				
-				var sourceTileImage: CGImage!
-				
-				// calculate the number of read/write opertions required to assemble the
-				// output image.
-				var iterations = Int(sourceResolution.height / sourceTile.height)
-				
-				// if tile height doesn't divide the image height evenly, add another iteration
-				// to account for the remaining pixels.
-				let remainder = Int(sourceResolution.height.truncatingRemainder(dividingBy: sourceTile.size.height))
-				if remainder != 0 {
-					iterations += 1
-				}
-				
-				// add seam overlaps to the tiles, but save the original tile height for y coordinate calculations.
-				let sourceTileHeightMinusOverlap = sourceTile.size.height
-				sourceTile.size.height += sourceSeamOverlap
-				destTile.size.height += CGFloat(self.destSeamOverlap)
-				
-				//				print("beginning downsize. iterations: \(iterations), tile height: \(sourceTile.size.height), remainder height: \(remainder)")
-				
-				for y in 0..<iterations {
-					
-					// create an autorelease pool to catch calls to -autorelease made within the downsize loop.
-					autoreleasepool {
-						
-						//						print("iteration \(y+1) of \(iterations)")
-						
-						sourceTile.origin.y = CGFloat(y) * sourceTileHeightMinusOverlap + CGFloat(sourceSeamOverlap)
-						destTile.origin.y = (destResolution.height ) - ( ( CGFloat(y) + 1 ) * sourceTileHeightMinusOverlap * imageScale + CGFloat(self.destSeamOverlap))
-						
-						// create a reference to the source image with its context clipped to the argument rect.
-						sourceTileImage = sourceImage.cgImage?.cropping(to: sourceTile)
-						
-						// if this is the last tile, it's size may be smaller than the source tile height.
-						// adjust the dest tile size to account for that difference.
-						if y == iterations - 1 && remainder != 0 {
-							var dify = destTile.size.height
-							destTile.size.height = CGFloat(sourceTileImage.height) * imageScale
-							dify -= destTile.size.height
-							destTile.origin.y += dify
-						}
-						
-						// read and write a tile sized portion of pixels from the input image to the output image.
-						destContext.draw(sourceTileImage, in: destTile)
-					}
-				}
-				
-				//				print("downsize complete.")
-				
-				if let image = destContext.makeImage() {
-					completion(image, nil)
-				}
-				else {
-					completion(nil, TileMakerError.destinationContextFailedToMakeImage)
-				}
-				
-			}
-		}
-	}
-	
-	
-	/**
-	  Make tiles in 4 diferent scale for given image and save tiles in given directory url. The scales are 0.125, 0.25, 0.5, 1.0 .
-	
-	  - Parameters:
-		   - image: image that wants make tiles for it
-		   - directoryURL: destination url want tiles save there.
-		   - prefix: The name that uses for naming tiles of image.
-		   - tilingCompletion:
-				A block to be executed when the making of tiles ends. This block has no return value and takes
-				three argument. An String and CGSize as name and size of tiled image, an error if some errors happened.
-				If an error occurs, String and CGSize arguments may be nil. If no error occurs, Error will be nil.
-	*/
-	private func makeTiles(for image: CGImage, to directoryURL: URL, usingPrefix prefix: String, tilingCompletion: @escaping (String?, CGSize?, Error?) -> ()) {
-		DispatchQueue.global().async {
-			
-			var scale: CGFloat = 0.125
-			var iterations: Int = 4
-			let imageMaxEdge = image.width > image.height ? image.width : image.height
-			let screenSize = CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
-			let screenMinEdge = screenSize.width > screenSize.height ? screenSize.width : screenSize.height
-			let screenScale = UIScreen.main.scale
-			let ratio = (screenMinEdge*screenScale*0.2)/CGFloat(imageMaxEdge)
-			
-			if ratio > 0.125, ratio <= 0.25 {
-				scale = 0.25
-				iterations = 3
-			}
-			if ratio > 0.25, ratio <= 0.5 {
-				scale = 0.5
-				iterations = 2
-			}
-			if ratio > 0.5 {
-				scale = 1
-				iterations = 1
-			}
-			
-			
-			DispatchQueue.concurrentPerform(iterations: iterations, execute: { (count) in
-				print("scale is", scale*pow(2, CGFloat(count)))
-				self.makeTiles(for: image, inScale: scale*pow(2, CGFloat(count)), to: directoryURL, usingPrefix: prefix) { (error) in
-					if error != nil {
-						tilingCompletion(nil, nil, error)
-						return
-					}
-				}
-				
-			})
-			
-			let imageWidth = CGFloat(image.width)
-			let imageHeight = CGFloat(image.height)
-			let imageSize = CGSize(width: imageWidth, height: imageHeight)
-			self.add(imageName: prefix, with: imageSize, toPropertyListAt: directoryURL) { (error) in
-				if error != nil {
-					tilingCompletion(nil, nil, error)
-				}
-				else {
-					tilingCompletion(prefix, imageSize, nil)
-					
-				}
-			}
-		}
-	}
-	
-	/**
-	Make tiles in 4 diferent scale for given image and save tiles in given directory url. The scales are 0.125, 0.25, 0.5, 1.0 .
-	
-	- Parameters:
-		- imageName: Name of image that wants to save its information in its info propertylist
-		- size: size of image that wants to save its information in its info propertylist
-		- propertyListURL: destination url want tiles save there.
-		- completion:
-		A block to be executed when saving information to propertyList ends. This block has no return value and takes
-		one argument. An error if some errors happened. If no error occurs, Error will be nil.
-	*/
-	private func add(imageName:String, with size: CGSize, toPropertyListAt propertyListURL: URL, completion: (Error?) -> ()) {
-		let dic: [String: Any] = ["name": imageName, "width": size.width, "height": size.height]
-		
-		let fileManager = FileManager.default
-		let url = propertyListURL.appendingPathComponent("imageInfo.plist")
-		
-        if fileManager.fileExists(atPath: url.path) {
-            let plistArray = NSMutableArray(contentsOf: url)
-            plistArray?.add(dic)
-            plistArray?.write(to: url, atomically: true)
-            completion(nil)
-        } else {
-            NSArray(array: [dic]).write(to: url, atomically: true)
-            completion(nil)
-        }
-	}
-	
-	/**
-	Make placeholder for given image and save it in given directory url.
-	
-	- Parameters:
-		- image: image that wants make placeholder for it
-		- directoryURL: destination url want placeholder save there.
-		- prefix: The name that uses for naming placeholder of image.
-		- completion:
-		A block to be executed when the making of tiles ends. This block has no return value and takes
-		two argument. A URL and Error as url of placeholder, and error if some errors happened.
-		If an error occurs, url may be nil. If no error occurs, Error will be nil.
-	*/
-	private func makePlaceholder(for image: CGImage, to directoryURL: URL, usingPrefix prefix: String, completion: @escaping (URL?, Error?) -> ()) {
-		let imageWidth = CGFloat(image.width)
-		let imageHeight = CGFloat(image.height)
-		
-		let scale = UIScreen.main.bounds.width/imageWidth
-		let imageRect = CGRect(origin: .zero, size: CGSize(width: imageWidth*scale, height: imageHeight*scale))
-		
-		DispatchQueue.global().async {
-
-			UIGraphicsBeginImageContext(imageRect.size)
-			let context = UIGraphicsGetCurrentContext()
-			
-			context?.saveGState()
-			context?.translateBy(x: 0, y: imageRect.size.height)
-			context?.scaleBy(x: 1, y: -1)
-			
-			context?.draw(image, in: imageRect)
-			context?.restoreGState()
-			let lowQImage = context?.makeImage()
-			UIGraphicsEndImageContext()
-            let imageData = UIImage(cgImage: lowQImage!).pngData()
-			
-			let imageName = "\(prefix)_Placeholder.jpg"
-			let url = directoryURL.appendingPathComponent(imageName)
-			do {
-				try imageData!.write(to: url)
-			}
-			catch let error {
-				completion(nil, error)
-			}
-			completion(url, nil)
-		}
-	}
-	
-	/**
-	Make tiles in given scale for given image and save tiles in given directory url.
-	
-	- Parameters:
-		- size: Size that wants make tiles in that size. Default is nil and uses the size specified with initializer
-		- image: Image that wants make tiles for it.
-		- scale: Scale that wants make tiles for that scale.
-		- directoryURL: destination url want tiles save there.
-		- prefix: The name that uses for naming tiles of image.
-		- completion:
-		A block to be executed when saving information to propertyList ends. This block has no return value and takes
-		one argument. An error if some errors happened. If no error occurs, Error will be nil.
-	*/
-	private func makeTiles( in size: CGSize? = nil, for image: CGImage, inScale scale: CGFloat, to directoryURL: URL, usingPrefix prefix: String, completion: (Error?) -> ()) {
-		let size = size ?? CGSize(width: self.tileSize, height: self.tileSize)
-		
-		var image: CGImage! = image
-		
-		let imageWidth = CGFloat(image.width)
-		let imageHeight = CGFloat(image.height)
-		
-		let imageRect = CGRect(origin: .zero, size: CGSize(width: imageWidth*scale, height: imageHeight*scale))
-		var context: CGContext!
-		if scale != 2 {
-			UIGraphicsBeginImageContext(imageRect.size)
-			context = UIGraphicsGetCurrentContext()
-			
-			context?.saveGState()
-			
-			context?.draw(image!, in: imageRect)
-			context?.restoreGState()
-			image = context.makeImage()
-			UIGraphicsEndImageContext()
-		}
-		
-		let cols = imageRect.width/size.width
-		let rows = imageRect.height/size.height
-		
-		var fullColomns = floor(cols)
-		var fullRows = floor(rows)
-		
-		let remainderWidth = imageRect.width - fullColomns*size.width
-		let remainderHeight = imageRect.height - fullRows*size.height
-		
-		if cols > fullColomns { fullColomns += 1 }
-		if rows > fullRows { fullRows += 1 }
-		
-		let fullImage = image!
-		
-		for row in 0..<Int(fullRows) {
-			for col in 0..<Int(fullColomns ){
-				var tileSize = size
-				if col + 1 == Int(fullColomns) && remainderWidth > 0 {
-					// Last Column
-					tileSize.width = remainderWidth
-				}
-				if row + 1 == Int(fullRows) && remainderHeight > 0 {
-					// Last Row
-					tileSize.height = remainderHeight
-				}
-				
-				autoreleasepool {
-					
-					let tileImage = fullImage.cropping(to: CGRect(origin: CGPoint(x: CGFloat(col)*size.width, y: CGFloat(row)*size.height), size: tileSize))!
-                    let imageData = UIImage(cgImage: tileImage).pngData()
-					
-					let tileName = "\(prefix)_\(Int(scale*1000))_\(col)_\(row).png"
-					let url = directoryURL.appendingPathComponent(tileName)
-					do {
-						try imageData!.write(to: url)
-					}
-					catch {
-						print(error)
-						completion(error)
-						return
-					}
-					
-				}
-				
-			}
-		}
-		context = nil
-		completion(nil)
-	}
-
-}

+ 0 - 107
iOSClient/Viewer/NCViewerPhoto/NCViewerPhotoTilingView.swift

@@ -1,107 +0,0 @@
-import UIKit
-
-class NCViewerPhotoTilingView: UIView {
-	
-	var imageName: String
-	var url: URL
-	var tilingView: NCViewerPhotoTilingView?
-
-	// We use these two properties to avoid accessing tiledLayer from bg thread:
-	var storedTileSize: CGSize!
-	var storedBounds: CGRect!
-	
-	override class var layerClass: AnyClass {
-		return CATiledLayer.self
-	}
-
-	// returns layer property as CATiledLayer
-	var tiledLayer: CATiledLayer {
-		return self.layer as! CATiledLayer
-	}
-
-	/*
-	Force contentScaleFactor of 1, even on retina displays For the CATiledLayer
-	to handle the interaction between CATiledLayer and high resolution screens, we need to manually set the
-	tiling view's contentScaleFactor to 1.0. (If we omitted this, it would be 2.0 on high resolution screens,
-	which would cause the CATiledLayer to ask us for tiles of the wrong scales.)
-	*/
-	override var contentScaleFactor: CGFloat {
-		didSet {
-			super.contentScaleFactor = 1
-		}
-	}
-	
-	init(in url: URL, size: CGSize) {
-		self.url = url
-		self.imageName = url.deletingPathExtension().lastPathComponent
-		
-		super.init(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
-		tiledLayer.levelsOfDetail = 4
-		
-		storedTileSize = tiledLayer.tileSize
-		storedBounds = self.bounds
-	}
-	
-	required init?(coder aDecoder: NSCoder) {
-		fatalError("init(coder:) has not been implemented")
-	}
-	
-    // Only override draw() if you perform custom drawing.
-    // An empty implementation adversely affects performance during animation.
-    override func draw(_ rect: CGRect) {
-		
-		let context = UIGraphicsGetCurrentContext()!
-		// get the scale from the context by getting the current transform matrix, then asking for
-		// its "a" component, which is one of the two scale components. We need to also ask for the "d" component as it might not be precisely the same as the "a" component, even at the "same" scale.
-		let scaleX: CGFloat = context.ctm.a
-		let scaleY: CGFloat = context.ctm.d
-
-		var tileSize = self.storedTileSize!
-		
-		// Even at scales lower than 100%, we are drawing into a rect in the coordinate system of the full
-		// image. One tile at 50% covers the width (in original image coordinates) of two tiles at 100%.
-		// So at 50% we need to stretch our tiles to double the width and height; at 25% we need to stretch
-		// them to quadruple the width and height; and so on.
-		// (Note that this means that we are drawing very blurry images as the scale gets low. At 12.5%,
-		// our lowest scale, we are stretching about 6 small tiles to fill the entire original image area.
-		// But this is okay, because the big blurry image we're drawing here will be scaled way down before
-		// it is displayed.)
-		
-		tileSize.width /= scaleX
-		tileSize.height /= -scaleY
-
-		// calculate the rows and columns of tiles that intersect the rect we have been asked to draw
-		let firstCol: Int = Int(floor(rect.minX/tileSize.width))
-		let lastCol: Int = Int(floor((rect.maxX-1)/tileSize.width))
-		let firstRow: Int = Int(floor(rect.minY/tileSize.height))
-		let lastRow: Int = Int(floor((rect.maxY-1)/tileSize.height))
-
-		for row in firstRow...lastRow {
-			for col in firstCol...lastCol {
-				guard let tile = tileFor(scale: scaleX, row: row, col: col) else {
-					return
-				}
-				var tileRect = CGRect(x: tileSize.width*CGFloat(col), y: tileSize.height*CGFloat(row), width: tileSize.width, height: tileSize.height)
-				
-				// if the tile would stick outside of our bounds, we need to truncate it so as
-				// to avoid stretching out the partial tiles at the right and bottom edges
-				tileRect = self.storedBounds.intersection(tileRect)
-				tile.draw(in: tileRect)
-			}
-		}
-
-    }
-	
-	func tileFor(scale: CGFloat, row: Int, col: Int) -> UIImage? {
-		//this accounts for a bug somewhere upstream that returns the scale as a floating point number just below the required value: 0.249... instead of 0.2500
-		let scale = scale < 1.0 ? Int(1/CGFloat(Int(1/scale))*1000) : Int(scale*1000)
-		
-		// we use "UIImage(contentsOfFile:)" instead of "UIImage(named:)" here because we don't
-		// want UIImage to cache our tiles
-		let tileName = "\(self.imageName)_\(scale)_\(col)_\(row).png"
-		
-		let path = url.appendingPathComponent(tileName).path
-		let image = UIImage(contentsOfFile: path)
-		return image
-	}
-}

+ 0 - 287
iOSClient/Viewer/NCViewerPhoto/NCViewerPhotoView.swift

@@ -1,287 +0,0 @@
-import UIKit
-
-class NCViewerPhotoView: UIScrollView, UIScrollViewDelegate {
-	
-	let pagePadding: CGFloat = 10
-	var recycledPages: Set<NCViewerPhotoImageScrollView> = []
-	var visiblePages: Set<NCViewerPhotoImageScrollView> = []
-	var firstVisiblePageIndexBeforeRotation: Int!
-	var singleTap: UITapGestureRecognizer!
-	var inTilingProcess: Set<String> = []
-	var currentImageName: String = ""
-    
-    var metadata = tableMetadata()
-    var metadatas = [tableMetadata]()
-    
-    required init?(coder: NSCoder) {
-        super.init(coder: coder)
-    }
-    
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        NotificationCenter.default.addObserver(self, selector: #selector(self.changeTheming), name: NSNotification.Name(rawValue: "changeTheming"), object: nil)
-    }
-    
-    @objc func setup(metadata: tableMetadata, view: UIView) {
-        
-        self.metadata = metadata
-        if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND typeFile == %@", metadata.account, metadata.serverUrl, k_metadataTypeFile_image), sorted: "fileName", ascending: true) {
-            self.metadatas = metadatas
-        }
-        
-        // single tap to show or hide navigation bar
-        singleTap = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
-        addGestureRecognizer(self.singleTap)
-        
-        showsVerticalScrollIndicator = false
-        showsHorizontalScrollIndicator = false
-        isPagingEnabled = true
-        contentSize = self.contentSizeForPagingScrollView()
-        delegate = self
-        view.addSubview(self)
-        
-        tilePages()
-    }
-   
-    @objc func changeTheming() {
-        backgroundColor = NCBrandColor.sharedInstance.backgroundView
-    }
-    
-	//MARK: - Tiling and page configuration
-	
-	func tilePages() {
-		// Calculate which pages should now be visible
-		let visibleBounds = self.bounds
-		
-		var firstNeededPageIndex: Int = Int(floor(visibleBounds.minX/visibleBounds.width))
-		var lastNeededPageIndex: Int = Int(floor((visibleBounds.maxX - 1)/visibleBounds.width))
-		firstNeededPageIndex = max(firstNeededPageIndex, 0)
-        lastNeededPageIndex = min(lastNeededPageIndex, metadatas.count - 1)
-		
-		//Recycle no longer needs pages
-		for page in self.visiblePages {
-			if page.index < firstNeededPageIndex || page.index > lastNeededPageIndex {
-				self.recycledPages.insert(page)
-				page.removeFromSuperview()
-			}
-		}
-		self.visiblePages.subtract(self.recycledPages)
-		
-		//add missing pages
-		for index in firstNeededPageIndex...lastNeededPageIndex {
-			if !self.isDisplayingPage(forIndex: index) {
-				let page = self.dequeueRecycledPage() ?? NCViewerPhotoImageScrollView()
-				
-				self.configure(page, for: index)
-				self.addSubview(page)
-				self.visiblePages.insert(page)
-			}
-		}
-	}
-	
-	func dequeueRecycledPage() -> NCViewerPhotoImageScrollView? {
-		if let page = self.recycledPages.first {
-			self.recycledPages.removeFirst()
-			return page
-		}
-		return nil
-	}
-	
-	func isDisplayingPage(forIndex index: Int) -> Bool {
-		for page in self.visiblePages {
-			if page.index == index {
-				return true
-			}
-		}
-		return false
-	}
-	
-	func configure(_ page: NCViewerPhotoImageScrollView, for index: Int) {
-		self.singleTap.require(toFail: page.zoomingTap)
-		page.backgroundColor = self.backgroundColor
-
-		page.index = index
-		page.frame = self.frameForPage(at: index)
-		self.displayImage(at: index, in: page)
-	}
-	
-	func displayImage(at index: Int, in page: NCViewerPhotoImageScrollView) {
-        let metadata = metadatas[index]
-        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) == false {
-            return
-        }
-        let imagePath = CCUtility.getDirectoryProviderStorageOcId(metadatas[index].ocId, fileNameView: metadatas[index].fileNameView)!
-		let tileManager = NCViewerPhotoTileManager()
-
-		if !tileManager.needsTilingImage(in: URL(fileURLWithPath: imagePath)) {
-			let image: UIImage! = UIImage(contentsOfFile: imagePath)
-			page.display(image)
-			return
-		}
-
-        /*
-		if tileManager.tilesMadeForImage(named: imageFileName) {
-			let size = tileManager.sizeOfTiledImage(named: imageFileName)!
-			let url = tileManager.urlOfTiledImage(named: imageFileName)
-			page.displayTiledImage(in: url, size: size)
-		}
-		else {
-			
-			if self.inTilingProcess.contains(imageFileName) {
-				if let placeholderURL = tileManager.urlOfPlaceholderOfImage(named: imageFileName) {
-					let image: UIImage! = UIImage(contentsOfFile: placeholderURL.path)
-					page.display(image)
-				}
-				return
-			}
-			else {
-				self.inTilingProcess.insert(imageFileName)
-			}
-
-			tileManager.makeTiledImage(for: imageURL, placeholderCompletion: { (url, error) in
-				if error == nil {
-					let image: UIImage! = UIImage(contentsOfFile: url!.path)
-					page.display(image)
-				}
-				
-			}, tilingCompletion: { (imageName, imageSize, error) in
-				if error == nil, imageName == self.currentImageName {
-					let url = tileManager.urlOfTiledImage(named: imageName!)
-					page.displayTiledImage(in: url, size: imageSize!)
-					
-					if self.inTilingProcess.contains(imageName!) {
-						self.inTilingProcess.remove(imageName!)
-					}
-					
-				}
-				else {
-					if error != nil {
-						print(error!)
-					}
-				}
-			})
-		}
-        */
-	}
-	
-	//MARK: - ScrollView delegate methods
-	
-	func scrollViewDidScroll(_ scrollView: UIScrollView) {
-		self.tilePages()
-	}
-	
-	//MARK: - Frame calculations
-	
-	func frameForPagingScrollView(in size: CGSize? = nil) -> CGRect {
-        var frame = self.bounds
-		
-		if size != nil {
-			frame.size = size!
-		}
-		
-		frame.origin.x -= pagePadding
-		frame.size.width += 2*pagePadding
-		return frame
-	}
-	
-	func contentSizeForPagingScrollView() -> CGSize {
-		let bounds = self.bounds
-        return CGSize(width: bounds.size.width*CGFloat(metadatas.count), height: bounds.size.height)
-	}
-	
-	func frameForPage(at index: Int) -> CGRect {
-		
-		let bounds = self.bounds
-		var pageFrame = bounds
-		pageFrame.size.width -= 2*pagePadding
-		pageFrame.origin.x = (bounds.size.width*CGFloat(index)) + pagePadding
-		
-		return pageFrame
-	}
-	
-	func saveCurrentStatesForRotation() {
-        let visibleBounds = self.bounds
-		firstVisiblePageIndexBeforeRotation = Int(floor(visibleBounds.minX/visibleBounds.width))
-	}
-	
-	func restoreStatesForRotation(in size: CGSize) {
-		// recalculate contentSize based on current orientation
-		let pagingScrollViewFrame = self.frameForPagingScrollView(in: size)
-		self.frame = pagingScrollViewFrame
-		self.contentSize = self.contentSizeForPagingScrollView()
-		
-		// adjust frames and configuration of each visible page
-		for page in visiblePages {
-			let restorePoint = page.pointToCenterAfterRotation()
-			let restoreScale = page.scaleToRestoreAfterRotation()
-			page.frame = self.frameForPage(at: page.index)
-			page.setMaxMinZoomScaleForCurrentBounds()
-			page.restoreCenterPoint(to: restorePoint, oldScale: restoreScale)
-		}
-		
-		// adjust contentOffset to preserve page location based on values collected prior to location
-		var contentOffset = CGPoint.zero
-		
-		let pageWidth = self.bounds.size.width
-		contentOffset.x = (CGFloat(firstVisiblePageIndexBeforeRotation) * pageWidth)
-		
-		self.contentOffset = contentOffset
-		
-	}
-	
-	//MARK: - Handle Tap
-	
-	/// Single tap action which hides navigationBar by default implementation
-	@objc func handleSingleTap() {
-        /*
-        let duration: TimeInterval = 0.2
-         
-		if self.navigationController != nil {
-			
-			if !self.navigationBarIsHidden {
-				
-				self.navigationBarIsHidden = true
-				UIView.animate(withDuration: duration, animations: {
-					self.navigationController!.navigationBar.alpha = 0
-					self.updateBackgroundColor()
-
-				}, completion: { (finished) in
-					self.navigationController!.navigationBar.isHidden = true
-				})
-				
-			}
-			else {
-				self.navigationBarIsHidden = false
-				UIView.animate(withDuration: duration) {
-					self.navigationController!.navigationBar.alpha = 1
-					self.navigationController!.navigationBar.isHidden = false
-					self.updateBackgroundColor()
-				}
-			}
-		}
-        */
-	}
-    
-	/// Update background color. Default is white / black.
-    /*
-	func updateBackgroundColor() {
-		if  !self.navigationBarIsHidden {
-			self.updateBackground(to: .white)
-		}
-		else {
-			self.updateBackground(to: .black)
-		}
-	}
-	*/
-    
-    /*
-	func updateBackground(to color: UIColor) {
-		self.view.backgroundColor = color
-		pagingScrollView?.backgroundColor = color
-		
-		for page in visiblePages {
-			page.backgroundColor = color
-		}
-	}
-	*/
-}