Skip to content

Commit

Permalink
feat: customizable row count
Browse files Browse the repository at this point in the history
  • Loading branch information
ejbills committed Dec 27, 2024
1 parent eab4666 commit 49f578b
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 14 deletions.
21 changes: 21 additions & 0 deletions DockDoor/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,15 @@
}
}
}
},
"• When hovering over the Dock at the bottom, windows flow in rows from left to right" : {

},
"• When hovering over the Dock on the sides, windows flow in columns from top to bottom" : {

},
"• When using ⌘⇥ Window Switcher, windows always flow in rows from left to right" : {

},
"1. Select \"Command (⌘)\" as the initialization key." : {
"localizations" : {
Expand Down Expand Up @@ -16954,6 +16963,9 @@
}
}
}
},
"Maximum Horizontal Rows" : {

},
"Maximum number of colors (%lld) reached." : {
"localizations" : {
Expand Down Expand Up @@ -17132,6 +17144,9 @@
}
}
}
},
"Maximum Vertical Columns" : {

},
"Medium" : {
"comment" : "Window size option",
Expand Down Expand Up @@ -28553,6 +28568,9 @@
}
}
}
},
"Set to 0 for unlimited" : {

},
"Shadowed" : {
"comment" : "Preview title style option",
Expand Down Expand Up @@ -37478,6 +37496,9 @@
}
}
}
},
"Window Preview Layout Limits" : {

},
"Window Preview Size" : {
"localizations" : {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Cocoa
import Defaults

// Handles calculating rows and columns for flow container
extension WindowPreviewHoverContainer {
Expand All @@ -20,20 +21,23 @@ extension WindowPreviewHoverContainer {
let rowHeight = maxWindowDimension.y + 16 // Single row height including spacing
var hasExceededWidth = false

// Calculate maximum allowed rows considering user defaults
let calculatedMaxRows = max(1, Int(maxHeight / rowHeight))
let userMaxRows = Defaults[.maxRows]
let effectiveMaxRows = userMaxRows > 0 ? min(Int(userMaxRows), calculatedMaxRows) : calculatedMaxRows

for windowIndex in 0 ..< activeWindowCount {
let windowWidth = windowDimensions[windowIndex]?.size.width ?? 0
let newWidth = currentRowWidth + windowWidth + 16

// Check if adding a row would exceed total available height
// Check if adding a window would exceed width or max rows
if newWidth > maxWidth {
if hasExceededWidth {
let newRowCount = currentRowIndex + 2 // Current + new one we'd need
let totalHeightNeeded = CGFloat(newRowCount) * rowHeight
let newRowCount = currentRowIndex + 2

if totalHeightNeeded > maxHeight {
// If we can't fit another row, redistribute across available height
let optimalRows = max(1, Int(maxHeight / rowHeight))
return redistributeEvenly(windowCount: activeWindowCount, divisions: optimalRows)
// If we would exceed max rows, redistribute
if newRowCount > effectiveMaxRows {
return redistributeEvenly(windowCount: activeWindowCount, divisions: effectiveMaxRows)
}

// Start new row
Expand Down Expand Up @@ -72,19 +76,22 @@ extension WindowPreviewHoverContainer {
let columnWidth = maxWindowDimension.x + 16
var hasExceededHeight = false

// Calculate maximum allowed columns considering user defaults
let calculatedMaxColumns = max(1, Int(maxWidth / columnWidth))
let userMaxColumns = Defaults[.maxColumns]
let effectiveMaxColumns = userMaxColumns > 0 ? min(Int(userMaxColumns), calculatedMaxColumns) : calculatedMaxColumns

for windowIndex in 0 ..< activeWindowCount {
let windowHeight = (windowDimensions[windowIndex]?.size.height ?? 0) + 16
let newHeight = columnHeights[currentColumnIndex] + windowHeight

if newHeight > maxHeight {
if hasExceededHeight {
// Check if adding a new column would exceed screen width
let totalColumns = currentColumnIndex + 2
let totalWidthNeeded = CGFloat(totalColumns) * columnWidth
let newColumnCount = currentColumnIndex + 2

if totalWidthNeeded > maxWidth {
let optimalColumns = max(1, Int(maxWidth / columnWidth))
return redistributeEvenly(windowCount: activeWindowCount, divisions: optimalColumns)
// If we would exceed max columns, redistribute
if newColumnCount > effectiveMaxColumns {
return redistributeEvenly(windowCount: activeWindowCount, divisions: effectiveMaxColumns)
}

// Start new column
Expand Down
41 changes: 40 additions & 1 deletion DockDoor/Views/Settings/AppearanceSettingsView.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Defaults
import LaunchAtLogin
import SwiftUI

struct AppearanceSettingsView: View {
Expand All @@ -14,6 +13,8 @@ struct AppearanceSettingsView: View {
@Default(.trafficLightButtonsVisibility) var trafficLightButtonsVisibility
@Default(.trafficLightButtonsPosition) var trafficLightButtonsPosition
@Default(.selectionOpacity) var selectionOpacity
@Default(.maxRows) var maxRows
@Default(.maxColumns) var maxColumns

@State private var previousTrafficLightButtonsPosition: TrafficLightButtonsPosition
@State private var previousWindowTitlePosition: WindowTitlePosition
Expand All @@ -40,6 +41,44 @@ struct AppearanceSettingsView: View {
unit: "",
formatter: NumberFormatter.percentFormatter)

Divider()

Text("Window Preview Layout Limits")
.font(.headline)

VStack(alignment: .leading, spacing: 4) {
Text("Set to 0 for unlimited")
.font(.caption)
.foregroundColor(.secondary)

Text("• When hovering over the Dock at the bottom, windows flow in rows from left to right")
.font(.caption)
.foregroundColor(.secondary)

Text("• When hovering over the Dock on the sides, windows flow in columns from top to bottom")
.font(.caption)
.foregroundColor(.secondary)

Text("• When using the Window Switcher, windows always flow in rows from left to right")
.font(.caption)
.foregroundColor(.secondary)
}
.padding(.bottom, 4)

sliderSetting(title: String(localized: "Maximum Horizontal Rows"),
value: $maxRows,
range: 0 ... 10,
step: 1,
unit: "")

sliderSetting(title: String(localized: "Maximum Vertical Columns"),
value: $maxColumns,
range: 0 ... 10,
step: 1,
unit: "")

Divider()

Picker("Traffic Light Buttons Visibility", selection: $trafficLightButtonsVisibility) {
ForEach(TrafficLightButtonsVisibility.allCases, id: \.self) { visibility in
Text(visibility.localizedName)
Expand Down
3 changes: 3 additions & 0 deletions DockDoor/consts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ extension Defaults.Keys {
static let fadeOutDuration = Key<CGFloat>("fadeOutDuration", default: 0.4)
static let previewHoverAction = Key<PreviewHoverAction>("previewHoverAction", default: .none)

static let maxColumns = Key<CGFloat>("maxColumns", default: 0)
static let maxRows = Key<CGFloat>("maxRows", default: 0)

static let showAnimations = Key<Bool>("showAnimations", default: true)
static let gradientColorPalette = Key<GradientColorPaletteSettings>("gradientColorPalette", default: .init())
static let enableWindowSwitcher = Key<Bool>("enableWindowSwitcher", default: true)
Expand Down

0 comments on commit 49f578b

Please sign in to comment.