OSDN Git Service

swiftlint 'legacy_constructor' の警告を修正
[kcd/KCD.git] / KCD / ImageView.swift
1 //
2 //  ImageView.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/02.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 class ImageView: NSView {
12     var images: [NSImage] = [] {
13         didSet { needsDisplay = true }
14     }
15     var imageRect: NSRect {
16         if images.isEmpty { return .zero }
17         let bounds = self.bounds
18         let offset = NSWidth(bounds) * 0.1 / 2 / 3
19         let border = offset * 3
20         let rect = NSInsetRect(bounds, border, border)
21         let size = images[0].size
22         let ratioX = NSHeight(rect) / size.height
23         let ratioY = NSWidth(rect) / size.width
24         let ratio = ratioX > ratioY ? ratioY : ratioX
25         let drawSize = NSSize(width: size.width * ratio, height: size.height * ratio)
26         return NSRect(
27             x: NSMinX(rect) + (NSWidth(rect) - drawSize.width) / 2,
28             y: NSMinY(rect) + (NSHeight(rect) - drawSize.height) / 2,
29             width: drawSize.width,
30             height: drawSize.height)
31     }
32     private var internalImageShadow: NSShadow?
33     private var imageShadow: NSShadow {
34         if let s = internalImageShadow { return s }
35         let s = NSShadow()
36         s.shadowOffset = NSSize(width: 2, height: -2)
37         s.shadowBlurRadius = 4
38         s.shadowColor = NSColor.darkGray
39         internalImageShadow = s
40         return s
41     }
42     
43     override func draw(_ dirtyRect: NSRect) {
44         let bounds = self.bounds
45         NSColor.controlBackgroundColor.set()
46         NSBezierPath.stroke(bounds)
47         
48         NSColor.black.set()
49         NSBezierPath.setDefaultLineWidth(1.0)
50         NSBezierPath.stroke(bounds)
51         
52         NSBezierPath.clip(NSInsetRect(bounds, 1, 1))
53         
54         imageShadow.set()
55         
56         let count = images.count
57         
58         let alphaFactor = 0.7
59         var alpha = pow(alphaFactor, Double(count - 1))
60         
61         let offset = NSWidth(bounds) * 0.1 / 2 / 3
62         let border = offset * 3
63         let rect = NSInsetRect(bounds, border, border)
64         
65         images
66             .enumerated()
67             .reversed()
68             .forEach {
69                 let offsetRect = NSOffsetRect(rect, offset * CGFloat($0.offset), offset * CGFloat($0.offset))
70                 let drawRect = imageRect(with: offsetRect, imageSize: $0.element.size)
71                 $0.element.draw(in: drawRect, from: .zero, operation: NSCompositeSourceOver, fraction: CGFloat(alpha))
72                 alpha /= alphaFactor
73         }
74     }
75
76     private func imageRect(with rect: NSRect, imageSize: NSSize) -> NSRect {
77         let ratioX = NSHeight(rect) / imageSize.height
78         let ratioY = NSWidth(rect) / imageSize.width
79         let ratio = ratioX > ratioY ? ratioY : ratioX
80         let drawSize = NSSize(width: imageSize.width * ratio,
81                               height: imageSize.height * ratio)
82         return NSRect(
83             x: NSMinX(rect) + (NSWidth(rect) - drawSize.width) / 2,
84             y: NSMinY(rect) + (NSHeight(rect) - drawSize.height) / 2,
85             width: drawSize.width,
86             height: drawSize.height)
87     }
88 }