Added convenience overloads to Rect and also, Collection conformance in the Playdate bindings target.
This commit is contained in:
@@ -56,3 +56,17 @@ extension Graphics {
|
||||
public var count: Int { info.count }
|
||||
}
|
||||
}
|
||||
|
||||
extension Graphics.BitmapTable: RandomAccessCollection {
|
||||
public var startIndex: Int { 0 }
|
||||
public var endIndex: Int { count }
|
||||
|
||||
/// The bitmap at `position`. The bitmap references storage owned by the
|
||||
/// table; keep the table alive while using it.
|
||||
public subscript(position: Int) -> Graphics.Bitmap {
|
||||
guard let bitmap = bitmap(at: position) else {
|
||||
preconditionFailure("bitmap table index out of range")
|
||||
}
|
||||
return bitmap
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,21 @@ extension Graphics {
|
||||
gfx.pointee.setClipRect.unsafelyUnwrapped(Int32(x), Int32(y), Int32(width), Int32(height))
|
||||
}
|
||||
|
||||
/// Sets the clip rect in world coordinates (affected by the draw offset).
|
||||
public static func setClipRect(_ rect: Rect) {
|
||||
setClipRect(x: rect.left, y: rect.top, width: rect.width, height: rect.height)
|
||||
}
|
||||
|
||||
/// Sets the clip rect in screen coordinates (unaffected by the draw offset).
|
||||
public static func setScreenClipRect(x: Int, y: Int, width: Int, height: Int) {
|
||||
gfx.pointee.setScreenClipRect.unsafelyUnwrapped(Int32(x), Int32(y), Int32(width), Int32(height))
|
||||
}
|
||||
|
||||
/// Sets the clip rect in screen coordinates (unaffected by the draw offset).
|
||||
public static func setScreenClipRect(_ rect: Rect) {
|
||||
setScreenClipRect(x: rect.left, y: rect.top, width: rect.width, height: rect.height)
|
||||
}
|
||||
|
||||
/// Clears the current clip rect.
|
||||
public static func clearClipRect() {
|
||||
gfx.pointee.clearClipRect.unsafelyUnwrapped()
|
||||
@@ -103,6 +113,11 @@ extension Graphics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws the outline of a rectangle, stroked inside its frame.
|
||||
public static func drawRect(_ rect: Rect, color: Color) {
|
||||
drawRect(x: rect.left, y: rect.top, width: rect.width, height: rect.height, color: color)
|
||||
}
|
||||
|
||||
/// Fills the rectangle with `color`.
|
||||
public static func fillRect(x: Int, y: Int, width: Int, height: Int, color: Color) {
|
||||
color.withLCDColor {
|
||||
@@ -110,6 +125,11 @@ extension Graphics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fills the rectangle with `color`.
|
||||
public static func fillRect(_ rect: Rect, color: Color) {
|
||||
fillRect(x: rect.left, y: rect.top, width: rect.width, height: rect.height, color: color)
|
||||
}
|
||||
|
||||
/// Draws the outline of a rectangle with rounded corners, stroked with
|
||||
/// `lineWidth`.
|
||||
public static func drawRoundRect(x: Int, y: Int, width: Int, height: Int, radius: Int,
|
||||
@@ -120,6 +140,13 @@ extension Graphics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws the outline of a rectangle with rounded corners, stroked with
|
||||
/// `lineWidth`.
|
||||
public static func drawRoundRect(_ rect: Rect, radius: Int, lineWidth: Int, color: Color) {
|
||||
drawRoundRect(x: rect.left, y: rect.top, width: rect.width, height: rect.height,
|
||||
radius: radius, lineWidth: lineWidth, color: color)
|
||||
}
|
||||
|
||||
/// Fills a rectangle with rounded corners.
|
||||
public static func fillRoundRect(x: Int, y: Int, width: Int, height: Int, radius: Int, color: Color) {
|
||||
color.withLCDColor {
|
||||
@@ -128,6 +155,12 @@ extension Graphics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fills a rectangle with rounded corners.
|
||||
public static func fillRoundRect(_ rect: Rect, radius: Int, color: Color) {
|
||||
fillRoundRect(x: rect.left, y: rect.top, width: rect.width, height: rect.height,
|
||||
radius: radius, color: color)
|
||||
}
|
||||
|
||||
/// Draws an ellipse stroked inside the rect. If the angles differ, draws
|
||||
/// an arc from `startAngle` to `endAngle` (clockwise degrees, 0 at top).
|
||||
public static func drawEllipse(x: Int, y: Int, width: Int, height: Int, lineWidth: Int,
|
||||
@@ -148,6 +181,22 @@ extension Graphics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws an ellipse stroked inside the rect. If the angles differ, draws
|
||||
/// an arc from `startAngle` to `endAngle` (clockwise degrees, 0 at top).
|
||||
public static func drawEllipse(in rect: Rect, lineWidth: Int,
|
||||
startAngle: Float = 0, endAngle: Float = 0, color: Color) {
|
||||
drawEllipse(x: rect.left, y: rect.top, width: rect.width, height: rect.height,
|
||||
lineWidth: lineWidth, startAngle: startAngle, endAngle: endAngle, color: color)
|
||||
}
|
||||
|
||||
/// Fills an ellipse inside the rect. If the angles differ, fills the
|
||||
/// wedge from `startAngle` to `endAngle` (clockwise degrees, 0 at top).
|
||||
public static func fillEllipse(in rect: Rect,
|
||||
startAngle: Float = 0, endAngle: Float = 0, color: Color) {
|
||||
fillEllipse(x: rect.left, y: rect.top, width: rect.width, height: rect.height,
|
||||
startAngle: startAngle, endAngle: endAngle, color: color)
|
||||
}
|
||||
|
||||
/// Fills the polygon described by the points, connecting the last point
|
||||
/// back to the first.
|
||||
public static func fillPolygon(points: [(x: Int, y: Int)], color: Color,
|
||||
@@ -205,6 +254,13 @@ extension Graphics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws `text` wrapped and aligned inside the given rectangle.
|
||||
public static func drawText(_ text: String, in rect: Rect,
|
||||
wrap: TextWrappingMode = .word, align: TextAlignment = .left) {
|
||||
drawText(text, x: rect.left, y: rect.top, width: rect.width, height: rect.height,
|
||||
wrap: wrap, align: align)
|
||||
}
|
||||
|
||||
/// Sets the font used by subsequent text drawing.
|
||||
public static func setFont(_ font: Font) {
|
||||
gfx.pointee.setFont.unsafelyUnwrapped(font.pointer)
|
||||
|
||||
@@ -33,6 +33,12 @@ extension Graphics {
|
||||
top: Int32(top), bottom: Int32(bottom))
|
||||
}
|
||||
|
||||
/// The rect's width.
|
||||
public var width: Int { right - left }
|
||||
|
||||
/// The rect's height.
|
||||
public var height: Int { bottom - top }
|
||||
|
||||
/// Returns the rect offset by (dx, dy).
|
||||
public func translated(dx: Int, dy: Int) -> Rect {
|
||||
Rect(left: left + dx, right: right + dx, top: top + dy, bottom: bottom + dy)
|
||||
|
||||
@@ -186,6 +186,12 @@ enum Mock {
|
||||
Mock.record("getTableBitmap(\(index))")
|
||||
return index == 0 ? Mock.fakePointer() : nil
|
||||
}
|
||||
gfxAPI.pointee.getBitmapTableInfo = { _, count, cellsWide in
|
||||
Mock.record("getBitmapTableInfo")
|
||||
// One bitmap, matching getTableBitmap vending index 0 only.
|
||||
count?.pointee = 1
|
||||
cellsWide?.pointee = 1
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Sprite
|
||||
|
||||
@@ -89,6 +89,16 @@ struct WrapperTests {
|
||||
#expect(Mock.eventCount("freeBitmapTable") == 1)
|
||||
}
|
||||
|
||||
@Test func bitmapTableIsACollection() {
|
||||
let table = Graphics.BitmapTable(count: 4, width: 8, height: 8)
|
||||
#expect(table.count == 1) // the mock reports a single bitmap
|
||||
#expect(table.first != nil)
|
||||
|
||||
var visited = 0
|
||||
for _ in table { visited += 1 }
|
||||
#expect(visited == 1)
|
||||
}
|
||||
|
||||
// MARK: Sprite
|
||||
|
||||
@Test func spriteUserdataRecoversWrapperInCallbacks() {
|
||||
|
||||
Reference in New Issue
Block a user