Skip to content

Commit

Permalink
Initial padding
Browse files Browse the repository at this point in the history
  • Loading branch information
danielctull committed Dec 13, 2024
1 parent 1bb173e commit 62b4f35
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 18 deletions.
7 changes: 1 addition & 6 deletions Sources/TerminalUI Demo/Demo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ import TerminalUI
struct Demo: App {

var body: some View {
Text("daniel")
.bold()
.italic()
.underline()
.blinking()
.inverse()
Color.red.padding(top: 5, leading: 2, bottom: 10, trailing: 8)
}
}
44 changes: 32 additions & 12 deletions Sources/TerminalUI/Rendering/Dimensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,44 @@
// MARK: Horizontal

/// A measurement of the horizontal dimension.
struct Horizontal: Equatable, Hashable {
public struct Horizontal: Equatable, Hashable {
fileprivate let value: Int
}

extension Horizontal: AdditiveArithmetic {
public static func + (lhs: Horizontal, rhs: Horizontal) -> Horizontal {
Horizontal(value: lhs.value + rhs.value)
}

public static func - (lhs: Horizontal, rhs: Horizontal) -> Horizontal {
Horizontal(value: lhs.value - rhs.value)
}
}

extension Horizontal: Comparable {
static func < (lhs: Horizontal, rhs: Horizontal) -> Bool {
public static func < (lhs: Horizontal, rhs: Horizontal) -> Bool {
lhs.value < rhs.value
}
}

extension Horizontal: CustomStringConvertible {
var description: String {
public var description: String {
value.description
}
}

extension Horizontal: ExpressibleByIntegerLiteral {
init(integerLiteral value: Int) {
public init(integerLiteral value: Int) {
self.init(value: value)
}
}

extension Horizontal: Strideable {
func advanced(by n: Int) -> Horizontal {
public func advanced(by n: Int) -> Horizontal {
Horizontal(value: value + n)
}

func distance(to other: Horizontal) -> Int {
public func distance(to other: Horizontal) -> Int {
value - other.value
}
}
Expand All @@ -43,34 +53,44 @@ extension Horizontal {
// MARK: - Vertical

/// A measurement of the vertical dimension.
struct Vertical: Equatable, Hashable {
public struct Vertical: Equatable, Hashable {
fileprivate let value: Int
}

extension Vertical: AdditiveArithmetic {
public static func + (lhs: Vertical, rhs: Vertical) -> Vertical {
Vertical(value: lhs.value + rhs.value)
}

public static func - (lhs: Vertical, rhs: Vertical) -> Vertical {
Vertical(value: lhs.value - rhs.value)
}
}

extension Vertical: Comparable {
static func < (lhs: Vertical, rhs: Vertical) -> Bool {
public static func < (lhs: Vertical, rhs: Vertical) -> Bool {
lhs.value < rhs.value
}
}

extension Vertical: CustomStringConvertible {
var description: String {
public var description: String {
value.description
}
}

extension Vertical: ExpressibleByIntegerLiteral {
init(integerLiteral value: Int) {
public init(integerLiteral value: Int) {
self.init(value: value)
}
}

extension Vertical: Strideable {
func advanced(by n: Int) -> Vertical {
public func advanced(by n: Int) -> Vertical {
Vertical(value: value + n)
}

func distance(to other: Vertical) -> Int {
public func distance(to other: Vertical) -> Int {
value - other.value
}
}
Expand Down
99 changes: 99 additions & 0 deletions Sources/TerminalUI/ViewModifiers/Padding.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@

extension View {

public func padding(_ length: Int) -> some View {
padding(.all(length))
}

public func padding(
top: Vertical = 0,
leading: Horizontal = 0,
bottom: Vertical = 0,
trailing: Horizontal = 0
) -> some View {
padding(EdgeInsets(
top: top,
leading: leading,
bottom: bottom,
trailing: trailing
))
}

public func padding(_ edgeInsets: EdgeInsets) -> some View {
Padding(content: self, edgeInsets: edgeInsets)
}
}

private struct Padding<Content: View>: Builtin, View {

let content: Content
let edgeInsets: EdgeInsets

func render(in canvas: any Canvas, size: Size, environment: EnvironmentValues) {
content.render(
in: canvas.inset(edgeInsets),
size: size.inset(edgeInsets),
environment: environment
)
}
}

extension Canvas {
func inset(_ insets: EdgeInsets) -> Canvas {
InsetCanvas(base: self, insets: insets)
}
}

private struct InsetCanvas<Base: Canvas>: Canvas {
let base: Base
let insets: EdgeInsets

func draw(_ pixel: Pixel, at position: Position) {
base.draw(pixel, at: position.offset(by: insets))
}
}

extension Position {
func offset(by edgeInsets: EdgeInsets) -> Position {
Position(x: x + edgeInsets.leading, y: y + edgeInsets.top)
}
}

extension Size {
func inset(_ edgeInsets: EdgeInsets) -> Size {
Size(
width: width - edgeInsets.leading - edgeInsets.trailing,
height: height - edgeInsets.top - edgeInsets.bottom
)
}
}

public struct EdgeInsets {
let top: Vertical
let leading: Horizontal
let bottom: Vertical
let trailing: Horizontal

public init(
top: Vertical,
leading: Horizontal,
bottom: Vertical,
trailing: Horizontal
) {
self.top = top
self.leading = leading
self.bottom = bottom
self.trailing = trailing
}
}

extension EdgeInsets {
static func all(_ length: Int) -> EdgeInsets {
EdgeInsets(
top: Vertical(length),
leading: Horizontal(length),
bottom: Vertical(length),
trailing: Horizontal(length)
)
}
}

0 comments on commit 62b4f35

Please sign in to comment.