Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SliverPinnedHeader and SliverGroup #8

Merged
merged 2 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/onevcat/Rainbow",
"state" : {
"revision" : "0c627a4f8a39ef37eadec1ceec02e4a7f55561ac",
"version" : "4.1.0"
"revision" : "e0dada9cd44e3fa7ec3b867e49a8ddbf543e3df3",
"version" : "4.0.1"
}
},
{
Expand Down
450 changes: 450 additions & 0 deletions Sources/Shaft/Rendering/RenderSliverGroup.swift

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Sources/Shaft/Rendering/RenderViewport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,9 @@ public class RenderViewportBase<ParentDataType: SliverContainerParentData>: Rend
/// * [cacheExtentStyle], which controls the units of the [cacheExtent].
public var cacheExtent: Float? {
didSet {
if cacheExtent == nil {
cacheExtent = defaultCacheExtent
}
if cacheExtent != oldValue {
markNeedsLayout()
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Shaft/Rendering/ViewportOffset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ extension ViewportOffset {
/// like [ScrollPosition] handle it by adjusting [to] to prevent over or
/// underscroll.
public func moveTo(
to: Float,
_ to: Float,
duration: Duration? = nil,
curve: Curve? = nil,
clamp: Bool? = nil
Expand Down
62 changes: 30 additions & 32 deletions Sources/Shaft/Widgets/Framework/Framework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2508,26 +2508,26 @@ public class ComponentElement: Element {
}

/// An [Element] that uses a [StatelessWidget] as its configuration.
class StatelessElement: ComponentElement {
override init(_ widget: Widget) {
public class StatelessElement: ComponentElement {
public override init(_ widget: Widget) {
assert(widget is StatelessWidget)
super.init(widget)
}

override func update(_ newWidget: Widget) {
public override func update(_ newWidget: Widget) {
super.update(newWidget)
assert(widget === newWidget)
rebuild(force: true)
}

override func build() -> Widget {
public override func build() -> Widget {
return (widget as! StatelessWidget).build(context: self)
}
}

/// An [Element] that uses a [StatefulWidget] as its configuration.
class StatefulElement<T: StatefulWidget>: ComponentElement {
init(_ widget: T) {
public class StatefulElement<T: StatefulWidget>: ComponentElement {
public init(_ widget: T) {
super.init(widget)
state = widget.createState()
assert(state.element == nil)
Expand All @@ -2541,13 +2541,13 @@ class StatefulElement<T: StatefulWidget>: ComponentElement {
/// There is a one-to-one relationship between [State] objects and the
/// [StatefulElement] objects that hold them. The [State] objects are created
/// by [StatefulElement] in [mount].
var state: State<T>!
public private(set) var state: State<T>!

override func build() -> Widget {
public override func build() -> Widget {
state.build(context: self)
}

override func firstBuild() {
public override func firstBuild() {
assert {
state.debugLifecycleState = .created
return true
Expand All @@ -2565,15 +2565,15 @@ class StatefulElement<T: StatefulWidget>: ComponentElement {
super.firstBuild()
}

override func performRebuild() {
public override func performRebuild() {
if _didChangeDependencies {
state.didChangeDependencies()
_didChangeDependencies = false
}
super.performRebuild()
}

override func update(_ newWidget: Widget) {
public override func update(_ newWidget: Widget) {
super.update(newWidget)
assert(widget === newWidget)
let oldWidget = state.widget!
Expand All @@ -2582,24 +2582,22 @@ class StatefulElement<T: StatefulWidget>: ComponentElement {
rebuild(force: true)
}

// @override
// void activate() {
// super.activate();
// state.activate();
// // Since the State could have observed the deactivate() and thus disposed of
// // resources allocated in the build method, we have to rebuild the widget
// // so that its State can reallocate its resources.
// assert(_lifecycleState == _ElementLifecycle.active); // otherwise markNeedsBuild is a no-op
// markNeedsBuild();
// }
public override func activate() {
super.activate()
state.activate()
// Since the State could have observed the deactivate() and thus disposed of
// resources allocated in the build method, we have to rebuild the widget
// so that its State can reallocate its resources.
assert(lifecycleState == .active)
markNeedsBuild()
}

// @override
// void deactivate() {
// state.deactivate();
// super.deactivate();
// }
public override func deactivate() {
state.deactivate()
super.deactivate()
}

override func unmount() {
public override func unmount() {
super.unmount()
state.dispose()
assert(state.debugLifecycleState == .defunct)
Expand All @@ -2620,24 +2618,24 @@ class StatefulElement<T: StatefulWidget>: ComponentElement {
/// to [didChangeDependencies] set it to true.
private var _didChangeDependencies = false

override func didChangeDependencies() {
public override func didChangeDependencies() {
super.didChangeDependencies()
_didChangeDependencies = true
}
}

/// An [Element] that uses a [ProxyWidget] as its configuration.
public class ProxyElement: ComponentElement {
override init(_ widget: Widget) {
public override init(_ widget: Widget) {
assert(widget is ProxyWidget)
super.init(widget)
}

override public func build() -> Widget {
public override func build() -> Widget {
return (widget as! ProxyWidget).child
}

override public func update(_ newWidget: Widget) {
public override func update(_ newWidget: Widget) {
let oldWidget = widget as! ProxyWidget
assert(widget !== newWidget)
super.update(newWidget)
Expand Down Expand Up @@ -2715,7 +2713,7 @@ public class ParentDataElement: ProxyElement {
applyParentData(newWidget)
}

override public func notifyClients(_ oldWidget: ProxyWidget) {
public override func notifyClients(_ oldWidget: ProxyWidget) {
let widget = widget as! any ParentDataWidget
applyParentData(widget)
}
Expand Down
20 changes: 16 additions & 4 deletions Sources/Shaft/Widgets/Scroll/ScrollPositionWithSingleContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/// single [ScrollContext], such as a [Scrollable]. An instance of this class
/// manages [ScrollActivity] instances, which change what content is visible in
/// the [Scrollable]'s [Viewport].
class ScrollPositionWithSingleContext: ScrollPosition {
public class ScrollPositionWithSingleContext: ScrollPosition {
public init(
physics: ScrollPhysics,
context: ScrollContext,
Expand Down Expand Up @@ -68,7 +68,7 @@ class ScrollPositionWithSingleContext: ScrollPosition {
}

private var _userScrollDirection: ScrollDirection = .idle
override var userScrollDirection: ScrollDirection {
public override var userScrollDirection: ScrollDirection {
_userScrollDirection
}

Expand All @@ -83,7 +83,19 @@ class ScrollPositionWithSingleContext: ScrollPosition {
// didUpdateScrollDirection(value)
}

override func pointerScroll(_ delta: Float) {
public override func jumpTo(_ value: Float) {
goIdle()
if pixels != value {
// let oldPixels = pixels
forcePixels(value)
// didStartScroll()
// didUpdateScrollPositionBy(pixels - oldPixels)
// didEndScroll()
}
goBallistic(0.0)
}

public override func pointerScroll(_ delta: Float) {
// If an update is made to pointer scrolling here, consider if the same
// (or similar) change should be made in
// _NestedScrollCoordinator.pointerScroll.
Expand Down Expand Up @@ -111,7 +123,7 @@ class ScrollPositionWithSingleContext: ScrollPosition {
}
}

override var axisDirection: AxisDirection {
public override var axisDirection: AxisDirection {
context.axisDirection
}
}
2 changes: 1 addition & 1 deletion Sources/Shaft/Widgets/Scroll/Scrollable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public final class Scrollable: StatefulWidget {
/// to [ScrollView.clipBehavior] and is supplied to the [Viewport].
public let clipBehavior: Clip

public func createState() -> State<Scrollable> {
public func createState() -> ScrollableState {
ScrollableState()
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/Shaft/Widgets/ScrollView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -545,15 +545,15 @@ public class CustomScrollView: ScrollViewBase {
center: (any Key)? = nil,
anchor: Float = 0.0,
cacheExtent: Float? = nil,
slivers: [Widget] = [],
semanticChildCount: Int? = nil,
dragStartBehavior: DragStartBehavior = .start,
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior = .manual,
restorationId: String? = nil,
clipBehavior: Clip = .hardEdge,
hitTestBehavior: HitTestBehavior = .opaque
hitTestBehavior: HitTestBehavior = .opaque,
@WidgetListBuilder slivers: () -> [Widget]
) {
self.slivers = slivers
self.slivers = slivers()
super.init(
key: key,
scrollDirection: scrollDirection,
Expand Down
Loading
Loading