Skip to content

Instantly share code, notes, and snippets.

@wiomoc
Last active June 10, 2021 19:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wiomoc/a8baca742da32b983200d879506bade0 to your computer and use it in GitHub Desktop.
Save wiomoc/a8baca742da32b983200d879506bade0 to your computer and use it in GitHub Desktop.
GemPuzzle Screensaver for macOS Preview: https://imgur.com/a/s8mRh
//
// GemPuzzleView.swift
// GemPuzzle
//
// Created by Christoph Walcher on 12.01.18.
// Copyright © 2018 Christoph Walcher. All rights reserved.
//
import ScreenSaver
import Foundation
@objc(GemPuzzleView)
class GemPuzzleView: ScreenSaverView {
static let COLUMNS = 24
static let ROWS = 15
var grid = [[NSImageView]]()
var prevRow = 0
var prevColumn = 0
public override init?(frame: NSRect, isPreview: Bool) {
super.init(frame: frame, isPreview: isPreview)
self.animationTimeInterval = 0.1
}
required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
}
func screenshot() -> CGImage {
let windows = CGWindowListCopyWindowInfo(CGWindowListOption.optionOnScreenOnly, kCGNullWindowID) as! [[String: Any]]
let loginwindow = windows.first(where: { (element) -> Bool in
return element[kCGWindowOwnerName as String] as! String == "loginwindow"
})
let loginwindowID = (loginwindow != nil) ? CGWindowID(loginwindow![kCGWindowNumber as String] as! Int) : kCGNullWindowID
return CGWindowListCreateImage(CGDisplayBounds(self.window?.screen?.deviceDescription["NSScreenNumber"] as! CGDirectDisplayID),
CGWindowListOption.optionOnScreenBelowWindow, loginwindowID, CGWindowImageOption.nominalResolution)!
}
override func startAnimation() {
var image = screenshot()
let context = CGContext(data: nil, width: Int(frame.width), height: Int(frame.height), bitsPerComponent: image.bitsPerComponent, bytesPerRow: image.bytesPerRow, space: image.colorSpace!, bitmapInfo: image.alphaInfo.rawValue)!
context.interpolationQuality = .high
context.draw(image, in: CGRect(x: 0, y: 0, width: Int(frame.width), height: Int(frame.height)))
image = context.makeImage()!
let tilesize = CGSize(width: Double(self.frame.width) / Double(GemPuzzleView.COLUMNS),
height: Double(self.frame.height) / Double(GemPuzzleView.ROWS))
for row in 0..<GemPuzzleView.ROWS {
var rowgrid = [NSImageView]()
for column in 0..<GemPuzzleView.COLUMNS {
let tile = image.cropping(to: CGRect(origin:
CGPoint.init(
x: tilesize.width.multiplied(by: CGFloat(column)),
y: tilesize.height.multiplied(by: CGFloat(row))
), size: tilesize))!
let imageView = NSImageView(frame: NSRect(origin: CGPoint.init(), size: tilesize))
imageView.image = NSImage(cgImage: tile, size: tilesize)
rowgrid.append(imageView)
}
grid.append(rowgrid)
}
let gridView = NSGridView(views: self.grid)
gridView.rowSpacing = 0
gridView.columnSpacing = 0
gridView.frame = self.frame
addSubview(gridView)
super.startAnimation()
}
override func hasConfigureSheet() -> Bool {
return false
}
override func animateOneFrame() {
let row0 = Int(arc4random_uniform(UInt32(GemPuzzleView.ROWS)))
let row1 = Int(arc4random_uniform(UInt32(GemPuzzleView.ROWS)))
let column0 = Int(arc4random_uniform(UInt32(GemPuzzleView.COLUMNS)))
let column1 = Int(arc4random_uniform(UInt32(GemPuzzleView.COLUMNS)))
let tmp = self.grid[row0][column0].image!
self.grid[row0][column0].image = self.grid[row1][column1].image!
self.grid[row1][column1].image = tmp
super.animateOneFrame()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment