feat: split max screen size preference into width/height (closes #579)
This commit is contained in:
1 parent
af5ed9b213
commit
6e2e5b47fc
5 files changed
+54
-29
No files matched your search
+18
-17
@@ -5,11 +5,10 @@ import ShortcutRecorder
|
||||
let defaults = UserDefaults.standard
|
||||
|
||||
class Preferences {
|
||||
static var defaultsDependingOnScreenRatio_ = defaultsDependingOnScreenRatio()
|
||||
|
||||
// default values
|
||||
static var defaultValues: [String: String] = [
|
||||
"maxScreenUsage": "80",
|
||||
"maxWidthOnScreen": "80",
|
||||
"maxHeightOnScreen": "80",
|
||||
"iconSize": "32",
|
||||
"fontHeight": "15",
|
||||
"holdShortcut": "⌥",
|
||||
@@ -73,9 +72,10 @@ class Preferences {
|
||||
static var intraCellPadding: CGFloat { 5 }
|
||||
|
||||
// persisted values
|
||||
static var maxScreenUsage: CGFloat { defaults.cgfloat("maxScreenUsage") / CGFloat(100) }
|
||||
static var minCellsPerRow: CGFloat { defaults.cgfloat("minCellsPerRow") }
|
||||
static var maxCellsPerRow: CGFloat { defaults.cgfloat("maxCellsPerRow") }
|
||||
static var maxWidthOnScreen: CGFloat { defaults.cgfloat("maxWidthOnScreen") / CGFloat(100) }
|
||||
static var maxHeightOnScreen: CGFloat { defaults.cgfloat("maxHeightOnScreen") / CGFloat(100) }
|
||||
static var windowMaxWidthInRow: CGFloat { defaults.cgfloat("windowMaxWidthInRow") / CGFloat(100) }
|
||||
static var windowMinWidthInRow: CGFloat { defaults.cgfloat("windowMinWidthInRow") / CGFloat(100) }
|
||||
static var rowsCount: CGFloat { defaults.cgfloat("rowsCount") }
|
||||
static var iconSize: CGFloat { defaults.cgfloat("iconSize") }
|
||||
static var fontHeight: CGFloat { defaults.cgfloat("fontHeight") }
|
||||
@@ -188,6 +188,13 @@ class Preferences {
|
||||
defaults.set(App.version, forKey: preferencesVersion)
|
||||
}
|
||||
|
||||
private static func migrateMaxSizeOnScreenToWidthAndHeight() {
|
||||
if let old = defaults.string(forKey: "maxScreenUsage") {
|
||||
defaults.set(old, forKey: "maxWidthOnScreen")
|
||||
defaults.set(old, forKey: "maxHeightOnScreen")
|
||||
}
|
||||
}
|
||||
|
||||
// dropdowns preferences used to store English text; now they store indexes
|
||||
static func migrateDropdownMenuPreference(_ preference: String, _ oldAndNew: [String: String]) {
|
||||
if let old = defaults.string(forKey: preference),
|
||||
@@ -206,19 +213,13 @@ class Preferences {
|
||||
}
|
||||
}
|
||||
|
||||
static func defaultsDependingOnScreenRatio() -> [String: String] {
|
||||
let ratio = Screen.mainScreenRatio()
|
||||
// landscape
|
||||
if ratio > 1 {
|
||||
// 15/10 and wider; tested with 16/10 and 16/9
|
||||
if ratio > (15 / 10) {
|
||||
return ["rowsCount": "4", "minCellsPerRow": "4", "maxCellsPerRow": "7"]
|
||||
}
|
||||
// narrower than 15/10; tested with 4/3
|
||||
return ["rowsCount": "3", "minCellsPerRow": "4", "maxCellsPerRow": "7"]
|
||||
static func rowCountDependingOnScreenRatio() -> String {
|
||||
// landscape; tested with 4/3, 16/10, 16/9
|
||||
if Screen.mainScreenRatio() > 1 {
|
||||
return "4"
|
||||
}
|
||||
// vertical; tested with 10/16
|
||||
return ["rowsCount": "6", "minCellsPerRow": "3", "maxCellsPerRow": "4"]
|
||||
return "6"
|
||||
}
|
||||
|
||||
static func keyAboveTabDependingOnInputSource() -> String {
|
||||
|
||||
@@ -145,7 +145,7 @@ class ThumbnailView: NSStackView {
|
||||
}
|
||||
dockLabelIcon.setFrameOrigin(NSPoint(x: appIcon.frame.maxX - dockLabelIcon.fittingSize.width - 1, y: appIcon.frame.maxY - dockLabelIcon.fittingSize.height + 4))
|
||||
}
|
||||
assignIfDifferent(&frame.size.width, max((Preferences.hideThumbnails ? hStackView.fittingSize.width : thumbnail.frame.size.width) + Preferences.intraCellPadding * 2, ThumbnailView.widthMin(screen)))
|
||||
assignIfDifferent(&frame.size.width, max((Preferences.hideThumbnails ? hStackView.fittingSize.width : thumbnail.frame.size.width) + Preferences.intraCellPadding * 2, ThumbnailView.widthMin(screen)).rounded())
|
||||
assignIfDifferent(&frame.size.height, newHeight)
|
||||
let fontIconWidth = CGFloat([fullscreenIcon, minimizedIcon, hiddenIcon, spaceIcon].filter { !$0.isHidden }.count) * (Preferences.fontHeight + Preferences.intraCellPadding)
|
||||
assignIfDifferent(&label.textContainer!.size.width, frame.width - Preferences.iconSize - Preferences.intraCellPadding * 3 - fontIconWidth)
|
||||
@@ -249,11 +249,11 @@ class ThumbnailView: NSStackView {
|
||||
}
|
||||
|
||||
static func widthMax(_ screen: NSScreen) -> CGFloat {
|
||||
return (ThumbnailsPanel.widthMax(screen) - Preferences.interCellPadding) / Preferences.minCellsPerRow - Preferences.interCellPadding
|
||||
return ThumbnailsPanel.widthMax(screen) * Preferences.windowMaxWidthInRow - Preferences.interCellPadding * 2
|
||||
}
|
||||
|
||||
static func widthMin(_ screen: NSScreen) -> CGFloat {
|
||||
return (ThumbnailsPanel.widthMax(screen) - Preferences.interCellPadding) / Preferences.maxCellsPerRow - Preferences.interCellPadding
|
||||
return ThumbnailsPanel.widthMax(screen) * Preferences.windowMinWidthInRow - Preferences.interCellPadding * 2
|
||||
}
|
||||
|
||||
static func height(_ screen: NSScreen) -> CGFloat {
|
||||
|
||||
@@ -33,10 +33,10 @@ class ThumbnailsPanel: NSPanel {
|
||||
}
|
||||
|
||||
static func widthMax(_ screen: NSScreen) -> CGFloat {
|
||||
return screen.frame.width * Preferences.maxScreenUsage - Preferences.windowPadding * 2
|
||||
return screen.frame.width * Preferences.maxWidthOnScreen - Preferences.windowPadding * 2
|
||||
}
|
||||
|
||||
static func heightMax(_ screen: NSScreen) -> CGFloat {
|
||||
return screen.frame.height * Preferences.maxScreenUsage - Preferences.windowPadding * 2
|
||||
return screen.frame.height * Preferences.maxHeightOnScreen - Preferences.windowPadding * 2
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ class LabelAndControl: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
static func makeLabelWithSlider(_ labelText: String, _ rawName: String, _ minValue: Double, _ maxValue: Double, _ numberOfTickMarks: Int, _ allowsTickMarkValuesOnly: Bool, _ unitText: String = "") -> [NSView] {
|
||||
static func makeLabelWithSlider(_ labelText: String, _ rawName: String, _ minValue: Double, _ maxValue: Double, _ numberOfTickMarks: Int, _ allowsTickMarkValuesOnly: Bool, _ unitText: String = "", extraAction: ActionClosure? = nil) -> [NSView] {
|
||||
let value = Preferences.getString(rawName)!
|
||||
let suffixText = MeasurementFormatter().string(from: Measurement(value: Double(value)!, unit: Unit(symbol: unitText)))
|
||||
let slider = NSSlider()
|
||||
@@ -71,7 +71,7 @@ class LabelAndControl: NSObject {
|
||||
slider.maxValue = maxValue
|
||||
slider.stringValue = value
|
||||
slider.isContinuous = true
|
||||
return makeLabelWithProvidedControl(labelText, rawName, slider, suffixText)
|
||||
return makeLabelWithProvidedControl(labelText, rawName, slider, suffixText, extraAction: extraAction)
|
||||
}
|
||||
|
||||
static func makeLabelWithProvidedControl(_ labelText: String, _ rawName: String, _ control: NSControl, _ suffixText: String? = nil, _ suffixUrl: String? = nil, labelPosition: LabelPosition = .leftWithSeparator, extraAction: ActionClosure? = nil) -> [NSView] {
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
import Cocoa
|
||||
|
||||
class AppearanceTab {
|
||||
static var rowsCount: [NSView]!
|
||||
static var minWidthInRow: [NSView]!
|
||||
static var maxWidthInRow: [NSView]!
|
||||
|
||||
static func initTab() -> NSView {
|
||||
rowsCount = LabelAndControl.makeLabelWithSlider(NSLocalizedString("Rows of thumbnails:", comment: ""), "rowsCount", 1, 20, 20, true)
|
||||
minWidthInRow = LabelAndControl.makeLabelWithSlider(NSLocalizedString("Window min width in row:", comment: ""), "windowMinWidthInRow", 0, 100, 10, true, "%", extraAction: { _ in capMinMaxWidthInRow() })
|
||||
maxWidthInRow = LabelAndControl.makeLabelWithSlider(NSLocalizedString("Window max width in row:", comment: ""), "windowMaxWidthInRow", 0, 100, 10, true, "%", extraAction: { _ in capMinMaxWidthInRow() })
|
||||
|
||||
let grid = GridView([
|
||||
LabelAndControl.makeLabelWithDropdown(NSLocalizedString("Theme:", comment: ""), "theme", ThemePreference.allCases),
|
||||
LabelAndControl.makeLabelWithDropdown(NSLocalizedString("Align windows:", comment: ""), "alignThumbnails", AlignThumbnailsPreference.allCases),
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Max size on screen:", comment: ""), "maxScreenUsage", 10, 100, 10, true, "%"),
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Rows of windows:", comment: ""), "rowsCount", 1, 20, 20, true),
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Min windows per row:", comment: ""), "minCellsPerRow", 1, 20, 20, true),
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Max windows per row:", comment: ""), "maxCellsPerRow", 1, 40, 20, true),
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Max width on screen:", comment: ""), "maxWidthOnScreen", 10, 100, 10, true, "%"),
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Max height on screen:", comment: ""), "maxHeightOnScreen", 10, 100, 10, true, "%"),
|
||||
LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hide window thumbnails:", comment: ""), "hideThumbnails", extraAction: { _ in toggleRowsCount() }),
|
||||
rowsCount,
|
||||
minWidthInRow,
|
||||
maxWidthInRow,
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Window app icon size:", comment: ""), "iconSize", 0, 128, 11, false, "px"),
|
||||
LabelAndControl.makeLabelWithSlider(NSLocalizedString("Window title font size:", comment: ""), "fontHeight", 0, 64, 11, false, "px"),
|
||||
LabelAndControl.makeLabelWithDropdown(NSLocalizedString("Window title truncation:", comment: ""), "titleTruncation", TitleTruncationPreference.allCases),
|
||||
@@ -21,12 +31,26 @@ class AppearanceTab {
|
||||
LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hide colored circles on mouse hover:", comment: ""), "hideColoredCircles"),
|
||||
LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hide app badges:", comment: ""), "hideAppBadges"),
|
||||
LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hide apps with no open window:", comment: ""), "hideWindowlessApps"),
|
||||
LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hide window thumbnails:", comment: ""), "hideThumbnails"),
|
||||
])
|
||||
grid.column(at: 0).xPlacement = .trailing
|
||||
grid.rowAlignment = .lastBaseline
|
||||
grid.fit()
|
||||
|
||||
toggleRowsCount()
|
||||
capMinMaxWidthInRow()
|
||||
|
||||
return grid
|
||||
}
|
||||
|
||||
static func capMinMaxWidthInRow() {
|
||||
let minSlider = minWidthInRow[1] as! NSSlider
|
||||
let maxSlider = maxWidthInRow[1] as! NSSlider
|
||||
maxSlider.minValue = minSlider.doubleValue
|
||||
debugPrint(maxSlider.minValue, maxSlider.doubleValue)
|
||||
LabelAndControl.controlWasChanged(maxSlider, "windowMaxWidthInRow")
|
||||
}
|
||||
|
||||
static func toggleRowsCount() {
|
||||
(rowsCount[1] as! NSSlider).isEnabled = !Preferences.hideThumbnails
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user