Files
2024-06-28 14:29:41 -03:00

225 lines
6.6 KiB
Swift

//
// System.swift
// TGUIKit
//
// Created by keepcoder on 08/09/16.
// Copyright © 2016 Telegram. All rights reserved.
//
import Cocoa
import SwiftSignalKit
import AVFoundation
public weak var mw:Window?
public var mainWindow:Window {
if let window = NSApp.keyWindow as? Window {
return window
} else if let window = NSApp.mainWindow as? Window {
return window
} else if let mw = mw {
return mw
}
fatalError("window not found")
}
public struct System {
public static var legacyMenu: Bool = true
private static var scaleFactor: Atomic<CGFloat> = Atomic(value: 2.0)
private static var safeScaleFactor: CGFloat = 2.0
public static func updateScaleFactor(_ value: CGFloat) {
_ = scaleFactor.modify { _ in
safeScaleFactor = value
return value
}
}
public static var batterylevel: Float {
let device = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPMPowerSource"))
let batteryLevel: AnyObject? = IORegistryEntryCreateCFProperty(device, "Current Capacity" as CFString, kCFAllocatorDefault, 0).takeRetainedValue()
IOObjectRelease(device)
return batteryLevel as! Float
}
public static var isRetina:Bool {
get {
return safeScaleFactor >= 2.0
}
}
public static var backingScale:CGFloat {
return safeScaleFactor
}
public static var pixel:CGFloat {
return 1 / safeScaleFactor
}
public static var aspectRatio: CGFloat {
let frame = NSScreen.main?.frame ?? .zero
let preferredAspectRatio = CGFloat(frame.width / frame.height)
return preferredAspectRatio
}
public static var cameraAspectRatio: CGFloat {
let device = AVCaptureDevice.default(for: .video)
let description = device?.activeFormat.formatDescription
if let description = description {
let dimension = CMVideoFormatDescriptionGetDimensions(description)
return CGFloat(dimension.width) / CGFloat(dimension.height)
}
return aspectRatio
}
public static var drawAsync:Bool {
return false
}
public static var isScrollInverted: Bool {
if UserDefaults.standard.value(forKey: "com.apple.swipescrolldirection") != nil {
return UserDefaults.standard.bool(forKey: "com.apple.swipescrolldirection")
} else {
return true
}
}
public static var supportsTransparentFontDrawing: Bool {
if #available(OSX 10.15, *) {
return true
} else {
return System.backingScale > 1.0
}
}
}
public var uiLocalizationFunc:((String)->String)?
public func localizedString(_ key:String) -> String {
if let uiLocalizationFunc = uiLocalizationFunc {
return uiLocalizationFunc(key)
} else {
return NSLocalizedString(key, comment: "")
}
}
//public func localizedString(_ key:String, countable:Int = 0, apply:Bool = true) -> String {
// let suffix:String
// if countable == 1 {
// suffix = ".singular"
// } else if countable > 1 {
// suffix = ".pluar"
// } else {
// suffix = ".zero"
// }
// if apply {
// return String(format: localizedString(key + suffix), countable)
// } else {
// return localizedString(key + suffix)
// }
//}
public func reverseIndexList<T>(_ list:[(Int,T,Int?)], _ previousCount:Int, _ updateCount:Int) -> [(Int,T,Int?)] {
var reversed:[(Int,T,Int?)] = []
for (int1,obj,int2) in list.reversed() {
if let s = int2 {
reversed.append((updateCount - int1 - 1,obj, previousCount - s - 1))
} else {
reversed.append((updateCount - int1 - 1,obj, nil))
}
}
return reversed
}
public func reverseIndexList<T>(_ list:[(Int,T)], _ previousCount:Int, _ updateCount:Int) -> [(Int,T)] {
var reversed:[(Int,T)] = []
for (int1,obj) in list.reversed() {
reversed.append((updateCount - int1 - 1,obj))
}
return reversed
}
public func reverseIndexList<T>(_ list:[(Int,T,Int)], _ previousCount:Int, _ updateCount:Int) -> [(Int,T,Int)] {
var reversed:[(Int,T,Int)] = []
for (int1,obj,int2) in list.reversed() {
reversed.append((updateCount - int1 - 1,obj, previousCount - int2 - 1))
}
return reversed
}
public func reverseIndexList(_ list:[Int], _ count:Int) -> [Int] {
var reversed:[(Int)] = []
for int1 in list.reversed() {
reversed.append(count - int1 - 1)
}
return reversed
}
public func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
public func delay(_ delay:Double, onQueue queue: DispatchQueue, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
queue.asyncAfter(deadline: when, execute: closure)
}
public func delaySignal(_ value:Double) -> Signal<NoValue, NoError> {
return .complete() |> delay(value, queue: .mainQueue())
}
public func link(path:String?, ext:String) -> String? {
var realPath:String? = path
if let path = path, path.nsstring.pathExtension.length == 0 && FileManager.default.fileExists(atPath: path) {
let path = path.nsstring.appendingPathExtension(ext)!
if !FileManager.default.fileExists(atPath: path) {
try? FileManager.default.removeItem(atPath: path)
try? FileManager.default.createSymbolicLink(atPath: path, withDestinationPath: realPath!)
}
realPath = path
}
return realPath
}
public func copyToTemp(path:String?, ext:String) -> String? {
var realPath:String? = path
if let path = path, path.nsstring.pathExtension.length == 0 && FileManager.default.fileExists(atPath: path) {
let new = NSTemporaryDirectory() + path.nsstring.lastPathComponent.nsstring.appendingPathExtension(ext)!
try? FileManager.default.copyItem(atPath: path, toPath: new)
realPath = new
}
return realPath
}
public func fs(_ path:String) -> Int32? {
if var attrs = try? FileManager.default.attributesOfItem(atPath: path) as NSDictionary {
if attrs["NSFileType"] as? String == "NSFileTypeSymbolicLink" {
if let path = try? FileManager.default.destinationOfSymbolicLink(atPath: path) {
attrs = (try? FileManager.default.attributesOfItem(atPath: path) as NSDictionary) ?? attrs
}
}
let size = attrs.fileSize()
if size > UInt64(INT32_MAX) {
return INT32_MAX
}
return Int32(size)
}
return nil
}