Skip to content

Commit

Permalink
feat: smarter padding around thumbnails (closes #126)
Browse files Browse the repository at this point in the history
  • Loading branch information
lwouis committed May 7, 2020
1 parent a60750c commit a94582f
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 61 deletions.
4 changes: 3 additions & 1 deletion src/logic/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ class Application: NSObject {
private func addWindows(_ axWindows: [AXUIElement]) {
let windows = axWindows.map { Window($0, self) }
Windows.list.insertAndScaleRecycledPool(windows, at: 0)
Windows.cycleFocusedWindowIndex(windows.count)
if App.app.appIsBeingUsed {
Windows.cycleFocusedWindowIndex(windows.count)
}
App.app.refreshOpenUi(windows)
}

Expand Down
6 changes: 3 additions & 3 deletions src/logic/Preferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Preferences {
// not exposed as preferences now but may be in the future, probably through macro preferences
static var windowMaterial: NSVisualEffectView.Material { .dark }
static var fontColor: NSColor { .white }
static var windowPadding: CGFloat { 23 }
static var windowPadding: CGFloat { 18 }
static var interCellPadding: CGFloat { 5 }
static var intraCellPadding: CGFloat { 5 }
static var fontIconSize: CGFloat { 20 }
Expand Down Expand Up @@ -223,8 +223,8 @@ enum ThemePreference: String, CaseIterable, MacroPreference {

var themeParameters: ThemeParameters {
switch self {
case .macOs: return ThemeParameters(label: self.localizedString, cellBorderWidth: 0, cellCornerRadius: 5, windowCornerRadius: 20, highlightBorderColor: .clear, highlightBackgroundColor: NSColor(red: 0, green: 0, blue: 0, alpha: 0.4))
case .windows10: return ThemeParameters(label: self.localizedString, cellBorderWidth: 2, cellCornerRadius: 0, windowCornerRadius: 0, highlightBorderColor: .white, highlightBackgroundColor: .clear)
case .macOs: return ThemeParameters(label: localizedString, cellBorderWidth: 0, cellCornerRadius: 10, windowCornerRadius: 23, highlightBorderColor: .clear, highlightBackgroundColor: NSColor(red: 0, green: 0, blue: 0, alpha: 0.4))
case .windows10: return ThemeParameters(label: localizedString, cellBorderWidth: 2, cellCornerRadius: 0, windowCornerRadius: 0, highlightBorderColor: .white, highlightBackgroundColor: .clear)
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/logic/Windows.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ class Windows {
static var windowsInSubscriptionRetryLoop = [String]()

static func updateFocusedWindowIndex(_ newIndex: Int) {
previousFocusedWindowIndex = focusedWindowIndex
focusedWindowIndex = newIndex
let focusedView = ThumbnailsView.recycledViews[focusedWindowIndex]
ThumbnailsPanel.highlightCell(ThumbnailsView.recycledViews[previousFocusedWindowIndex], focusedView)
App.app.thumbnailsPanel.thumbnailsView.scrollView.contentView.scrollToVisible(focusedView.frame)
if newIndex != focusedWindowIndex {
previousFocusedWindowIndex = focusedWindowIndex
focusedWindowIndex = newIndex
let focusedView = ThumbnailsView.recycledViews[focusedWindowIndex]
ThumbnailsView.recycledViews[previousFocusedWindowIndex].highlight(false)
focusedView.highlight(true)
App.app.thumbnailsPanel.thumbnailsView.scrollView.contentView.scrollToVisible(focusedView.frame)
}
}

static func focusedWindow() -> Window? {
Expand Down
73 changes: 43 additions & 30 deletions src/ui/main-window/ThumbnailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,55 @@ class ThumbnailView: NSStackView {
var minimizedIcon = ThumbnailFontIconView(ThumbnailFontIconView.sfSymbolCircledMinusSign, Preferences.fontIconSize, .white)
var hiddenIcon = ThumbnailFontIconView(ThumbnailFontIconView.sfSymbolCircledDotSign, Preferences.fontIconSize, .white)
var spaceIcon = ThumbnailFontIconView(ThumbnailFontIconView.sfSymbolCircledNumber0, Preferences.fontIconSize, .white)
var hStackView: NSStackView!
var mouseDownCallback: (() -> Void)!
var mouseMovedCallback: (() -> Void)!
var dragAndDropTimer: Timer?
var isHighlighted = false

convenience init() {
self.init(frame: .zero)
let hStackView = makeHStackView()
setupView(hStackView)
setupView()
observeDragAndDrop()
}

private func setupView() {
wantsLayer = true
layer!.backgroundColor = .clear
layer!.borderColor = .clear
layer!.cornerRadius = Preferences.cellCornerRadius
layer!.borderWidth = Preferences.cellBorderWidth
edgeInsets = NSEdgeInsets(top: Preferences.intraCellPadding, left: Preferences.intraCellPadding, bottom: Preferences.intraCellPadding, right: Preferences.intraCellPadding)
orientation = .vertical
spacing = Preferences.intraCellPadding
let shadow = ThumbnailView.makeShadow(.gray)
thumbnail.shadow = shadow
appIcon.shadow = shadow
observeDragAndDrop()
hStackView = NSStackView(views: [appIcon, label, hiddenIcon, minimizedIcon, spaceIcon])
hStackView.spacing = Preferences.intraCellPadding
setViews([hStackView, thumbnail], in: .leading)
}

func highlight(_ highlight: Bool) {
if isHighlighted != highlight {
isHighlighted = highlight
if frame != NSRect.zero {
highlightOrNot()
}
}
}

func highlightOrNot() {
layer!.backgroundColor = isHighlighted ? Preferences.highlightBackgroundColor.cgColor : .clear
layer!.borderColor = isHighlighted ? Preferences.highlightBorderColor.cgColor : .clear
let frameInset: CGFloat = Preferences.intraCellPadding * (isHighlighted ? -1 : 1)
frame = frame.insetBy(dx: frameInset, dy: frameInset)
let edgeInsets_: CGFloat = Preferences.intraCellPadding * (isHighlighted ? 2 : 1)
edgeInsets.top = edgeInsets_
edgeInsets.right = edgeInsets_
edgeInsets.bottom = edgeInsets_
edgeInsets.left = edgeInsets_
debugPrint("louis", isHighlighted, frame.width, label.string)
}

func updateRecycledCellWithNewContent(_ element: Window, _ index: Int, _ newHeight: CGFloat, _ screen: NSScreen) {
Expand Down Expand Up @@ -123,19 +160,15 @@ class ThumbnailView: NSStackView {
}

static func widthMax(_ screen: NSScreen) -> CGFloat {
return ThumbnailsPanel.widthMax(screen) / Preferences.minCellsPerRow - Preferences.interCellPadding
return (ThumbnailsPanel.widthMax(screen) - Preferences.interCellPadding) / Preferences.minCellsPerRow - Preferences.interCellPadding
}

static func widthMin(_ screen: NSScreen) -> CGFloat {
return ThumbnailsPanel.widthMax(screen) / Preferences.maxCellsPerRow - Preferences.interCellPadding
return (ThumbnailsPanel.widthMax(screen) - Preferences.interCellPadding) / Preferences.maxCellsPerRow - Preferences.interCellPadding
}

static func height(_ screen: NSScreen) -> CGFloat {
return ThumbnailsPanel.heightMax(screen) / Preferences.rowsCount - Preferences.interCellPadding
}

static func width(_ image: NSImage?, _ screen: NSScreen) -> CGFloat {
return max(thumbnailSize(image, screen).0 + Preferences.intraCellPadding * 2, ThumbnailView.widthMin(screen))
return (ThumbnailsPanel.heightMax(screen) - Preferences.interCellPadding) / Preferences.rowsCount - Preferences.interCellPadding
}

static func thumbnailSize(_ image: NSImage?, _ screen: NSScreen) -> (CGFloat, CGFloat) {
Expand All @@ -151,24 +184,4 @@ class ThumbnailView: NSStackView {
}
return (thumbnailWidth, image.size.height * thumbnailWidth / image.size.width)
}

private func makeHStackView() -> NSStackView {
let hStackView = NSStackView()
hStackView.spacing = Preferences.intraCellPadding
hStackView.setViews([appIcon, label, hiddenIcon, minimizedIcon, spaceIcon], in: .leading)
return hStackView
}

private func setupView(_ hStackView: NSStackView) {
wantsLayer = true
layer!.backgroundColor = .clear
layer!.cornerRadius = Preferences.cellCornerRadius
layer!.borderWidth = Preferences.cellBorderWidth
layer!.borderColor = .clear
edgeInsets = NSEdgeInsets(top: Preferences.intraCellPadding, left: Preferences.intraCellPadding, bottom: Preferences.intraCellPadding, right: Preferences.intraCellPadding)
orientation = .vertical
spacing = Preferences.intraCellPadding
setViews([hStackView, thumbnail], in: .leading)
}
}

7 changes: 0 additions & 7 deletions src/ui/main-window/ThumbnailsPanel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ class ThumbnailsPanel: NSPanel {
thumbnailsView.scrollView.flashScrollers()
}

static func highlightCell(_ previousView: NSView, _ newView: NSView) {
previousView.layer!.backgroundColor = .clear
previousView.layer!.borderColor = .clear
newView.layer!.backgroundColor = Preferences.highlightBackgroundColor.cgColor
newView.layer!.borderColor = Preferences.highlightBorderColor.cgColor
}

static func widthMax(_ screen: NSScreen) -> CGFloat {
return screen.frame.width * Preferences.maxScreenUsage - Preferences.windowPadding * 2
}
Expand Down
34 changes: 19 additions & 15 deletions src/ui/main-window/ThumbnailsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ class ThumbnailsView: NSVisualEffectView {
let widthMax = ThumbnailsPanel.widthMax(screen).rounded()
let heightMax = ThumbnailsPanel.heightMax(screen).rounded()
let height = ThumbnailView.height(screen).rounded(.down)
var currentX = CGFloat(0)
var currentY = CGFloat(0)
var currentX = Preferences.interCellPadding
var currentY = Preferences.interCellPadding
var maxX = CGFloat(0)
var maxY = height
var maxY = currentY + height + Preferences.interCellPadding
var newViews = [ThumbnailView]()
rows.removeAll()
rows.append([ThumbnailView]())
Expand All @@ -53,13 +53,13 @@ class ThumbnailsView: NSVisualEffectView {
let view = ThumbnailsView.recycledViews[index]
view.updateRecycledCellWithNewContent(window, index, height, screen)
let width = view.frame.size.width
if (currentX + width).rounded(.down) > widthMax {
currentX = CGFloat(0)
currentY = (currentY + Preferences.interCellPadding + height).rounded(.down)
maxY = max(currentY + height, maxY)
if (currentX + width + Preferences.interCellPadding).rounded(.down) > widthMax {
currentX = Preferences.interCellPadding
currentY = (currentY + height + Preferences.interCellPadding).rounded(.down)
maxY = max(currentY + height + Preferences.interCellPadding, maxY)
rows.append([ThumbnailView]())
} else {
maxX = max(currentX + width, maxX)
maxX = max(currentX + width + Preferences.interCellPadding, maxX)
}
view.frame.origin = CGPoint(x: currentX, y: currentY)
currentX = (currentX + Preferences.interCellPadding + width).rounded(.down)
Expand All @@ -76,23 +76,27 @@ class ThumbnailsView: NSVisualEffectView {
if Preferences.alignThumbnails == .center {
centerRows(maxX)
}
Windows.list.enumerated().first { (index, _) in
let view = ThumbnailsView.recycledViews[index]
if view.isHighlighted {
view.highlightOrNot()
}
return view.isHighlighted
}
}

func centerRows(_ maxX: CGFloat) {
var rowStartIndex = 0
var rowWidth = CGFloat(0)
var rowY = CGFloat(0)
var rowWidth = Preferences.interCellPadding
var rowY = Preferences.interCellPadding
for (index, _) in Windows.list.enumerated() {
let view = ThumbnailsView.recycledViews[index]
if view.frame.origin.y == rowY {
rowWidth += Preferences.interCellPadding + view.frame.size.width
rowWidth += view.frame.size.width + Preferences.interCellPadding
} else {
if rowStartIndex == 0 {
rowWidth -= Preferences.interCellPadding // first row has 1 extra padding
}
shiftRow(maxX, rowWidth, rowStartIndex, index)
rowStartIndex = index
rowWidth = view.frame.size.width
rowWidth = Preferences.interCellPadding + view.frame.size.width + Preferences.interCellPadding
rowY = view.frame.origin.y
}
}
Expand Down

0 comments on commit a94582f

Please sign in to comment.