Skip to content

Commit 017a590

Browse files
committed
Prettier Inspector UI window chrome
1 parent f579cf7 commit 017a590

File tree

3 files changed

+91
-38
lines changed

3 files changed

+91
-38
lines changed

Sources/LayoutInspector/DebugLayoutImpl.swift

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,34 @@ struct InspectLayout: ViewModifier {
2525
}
2626
}
2727
.overlay(alignment: .topLeading) {
28-
LogEntriesGrid(logEntries: logStore.log, highlight: $selectedView)
29-
.safeAreaInset(edge: .bottom) {
30-
toolbar
31-
}
32-
.resizableAndDraggable(
33-
frame: $inspectorFrame,
34-
coordinateSpace: .named(Self.coordSpaceName)
35-
)
36-
.background {
37-
Rectangle().fill(.thickMaterial)
38-
.shadow(radius: 5)
39-
}
28+
inspectorUI
4029
.frame(width: inspectorFrame.width, height: inspectorFrame.height)
4130
.offset(x: inspectorFrame.minX, y: inspectorFrame.minY)
4231
.coordinateSpace(name: Self.coordSpaceName)
4332
}
4433
.environmentObject(logStore)
4534
}
4635

36+
@ViewBuilder private var inspectorUI: some View {
37+
LogEntriesGrid(logEntries: logStore.log, highlight: $selectedView)
38+
.safeAreaInset(edge: .bottom) {
39+
toolbar
40+
}
41+
.resizableAndDraggable(
42+
frame: $inspectorFrame,
43+
coordinateSpace: .named(Self.coordSpaceName)
44+
)
45+
.background {
46+
Rectangle().fill(.thickMaterial)
47+
.shadow(radius: 5)
48+
}
49+
.cornerRadius(4)
50+
.overlay {
51+
RoundedRectangle(cornerRadius: 4)
52+
.strokeBorder(.quaternary)
53+
}
54+
}
55+
4756
@ViewBuilder private var toolbar: some View {
4857
HStack {
4958
Button("Reset layout cache") {

Sources/LayoutInspector/Geometry.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import CoreGraphics
2+
import SwiftUI
23

34
extension CGPoint {
45
static func + (lhs: CGPoint, rhs: CGPoint) -> CGSize {
@@ -64,4 +65,11 @@ extension CGRect {
6465
self = self.standardized
6566
}
6667
}
68+
69+
func unitPoint(_ unitPoint: UnitPoint) -> CGPoint {
70+
CGPoint(
71+
x: minX + (maxX - minX) * unitPoint.x,
72+
y: minY + (maxY - minY) * unitPoint.y
73+
)
74+
}
6775
}

Sources/LayoutInspector/ResizableAndDraggableView.swift

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,77 @@ struct ResizableAndDraggableFrame: ViewModifier {
2525
.padding(.top, Self.titleBarHeight)
2626
.overlay {
2727
ZStack(alignment: .top) {
28-
Rectangle()
29-
.frame(height: Self.titleBarHeight)
30-
.foregroundStyle(.tertiary)
31-
.draggable(point: $frame.origin, coordinateSpace: coordinateSpace)
32-
33-
let resizeHandle = ResizeHandle()
34-
.fill(.secondary)
35-
.frame(width: 20, height: 20)
36-
resizeHandle
37-
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
38-
.draggable(point: $frame.topLeading, coordinateSpace: coordinateSpace)
39-
resizeHandle
40-
.rotationEffect(.degrees(90))
41-
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
42-
.draggable(point: $frame.topTrailing, coordinateSpace: coordinateSpace)
43-
resizeHandle
44-
.rotationEffect(.degrees(-90))
45-
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomLeading)
46-
.draggable(point: $frame.bottomLeading, coordinateSpace: coordinateSpace)
47-
resizeHandle
48-
.rotationEffect(.degrees(180))
49-
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomTrailing)
50-
.draggable(point: $frame.bottomTrailing, coordinateSpace: coordinateSpace)
28+
titleBar
29+
resizeHandles
5130
}
5231
}
5332
}
33+
34+
@ViewBuilder private var titleBar: some View {
35+
Rectangle()
36+
.frame(height: Self.titleBarHeight)
37+
.foregroundStyle(.ultraThinMaterial)
38+
.overlay {
39+
Text("Layout Inspector")
40+
.font(.footnote)
41+
}
42+
.overlay(alignment: .bottom) {
43+
Rectangle()
44+
.foregroundStyle(.quaternary)
45+
.frame(height: 1)
46+
}
47+
.draggable(point: $frame.origin, coordinateSpace: coordinateSpace)
48+
.help("Move")
49+
}
50+
51+
@ViewBuilder private var resizeHandles: some View {
52+
let resizeHandle = TriangleStripes()
53+
.fill(Color(white: 0.5).opacity(0.5))
54+
.frame(width: 15, height: 15)
55+
.frame(width: Self.titleBarHeight, height: Self.titleBarHeight, alignment: .topLeading)
56+
.contentShape(Rectangle())
57+
.help("Resize")
58+
resizeHandle
59+
.draggable(point: $frame.topLeading, coordinateSpace: coordinateSpace)
60+
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
61+
resizeHandle
62+
.rotationEffect(.degrees(90))
63+
.draggable(point: $frame.topTrailing, coordinateSpace: coordinateSpace)
64+
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
65+
resizeHandle
66+
.rotationEffect(.degrees(-90))
67+
.draggable(point: $frame.bottomLeading, coordinateSpace: coordinateSpace)
68+
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomLeading)
69+
resizeHandle
70+
.rotationEffect(.degrees(180))
71+
.draggable(point: $frame.bottomTrailing, coordinateSpace: coordinateSpace)
72+
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomTrailing)
73+
}
5474
}
5575

56-
struct ResizeHandle: Shape {
76+
struct TriangleStripes: Shape {
5777
func path(in rect: CGRect) -> Path {
78+
let stripeCount = 4
79+
let spacing: CGFloat = 0.15 // in unit points
80+
let stripeWidth = (1 - CGFloat(stripeCount - 1) * spacing) / CGFloat(stripeCount)
81+
5882
var path = Path()
83+
// First stripe is special
5984
path.move(to: rect.topLeading)
60-
path.addLine(to: rect.topTrailing)
61-
path.addLine(to: rect.bottomLeading)
85+
path.addLine(to: rect.unitPoint(.init(x: stripeWidth, y: 0)))
86+
path.addLine(to: rect.unitPoint(.init(x: 0, y: stripeWidth)))
6287
path.closeSubpath()
88+
89+
for stripe in 1..<stripeCount {
90+
let start = CGFloat(stripe) * (stripeWidth + spacing)
91+
let end = start + stripeWidth
92+
path.move(to: rect.unitPoint(.init(x: start, y: 0)))
93+
path.addLine(to: rect.unitPoint(.init(x: end, y: 0)))
94+
path.addLine(to: rect.unitPoint(.init(x: 0, y: end)))
95+
path.addLine(to: rect.unitPoint(.init(x: 0, y: start)))
96+
path.closeSubpath()
97+
}
98+
6399
return path
64100
}
65101
}

0 commit comments

Comments
 (0)