Add HSplitView and VSplitView
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run

Co-authored-by: desbeers nick@desbeers.nl
This commit is contained in:
david-swift 2025-09-18 21:22:20 +02:00
parent fea203fabd
commit d17306f195
4 changed files with 179 additions and 12 deletions

View File

@ -0,0 +1,131 @@
//
// SplitView.swift
// Adwaita
//
// Created by david-swift on 19.09.2025.
//
import CAdw
import Foundation
/// A split view.
struct SplitView: AdwaitaWidget {
/// The start widget.
@ViewProperty(
set: { widget, view in gtk_paned_set_start_child(.init(widget), view.cast()) },
pointer: OpaquePointer.self,
subview: OpaquePointer.self,
context: AdwaitaMainView.self
)
var start
/// The end widget.
@ViewProperty(
set: { widget, view in gtk_paned_set_end_child(.init(widget), view.cast()) },
pointer: OpaquePointer.self,
subview: OpaquePointer.self,
context: AdwaitaMainView.self
)
var end
/// Position of the splitter
@BindingProperty(
observe: { _, binding, storage in
storage.notify(name: "position") {
binding.wrappedValue = Int(gtk_paned_get_position(storage.opaquePointer))
}
},
set: { widget, value, _ in gtk_paned_set_position(widget, Int32(value)) },
pointer: OpaquePointer.self
)
var splitter: Binding<Int> = .constant(0)
/// Whether the split view is vertical.
var vertical: Bool
/// Initialize a split view.
/// - Parameters:
/// - splitter: The position of the splitter.
/// - vertical: Whether to make the splitter vertical.
/// - start: The start widget.
/// - end: The end widget.
init(
splitter: Binding<Int>,
vertical: Bool,
start: Body,
end: Body
) {
self.vertical = vertical
self.splitter = splitter
self.start = start
self.end = end
}
/// Initialize the widget.
func initializeWidget() -> Any {
gtk_paned_new(vertical ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL).opaque() as Any
}
}
/// A horizontal split view.
public struct HSplitView: SimpleView {
/// The splitter.
@Binding var splitter: Int
/// The start widget.
var start: Body
/// The end widget.
var end: Body
/// The view.
public var view: Body {
SplitView(splitter: $splitter, vertical: false, start: start, end: end)
}
/// Initialize a horizontal split view.
/// - Parameters:
/// - splitter: The position of the splitter.
/// - start: The start widget.
/// - end: The end widget.
public init(
splitter: Binding<Int>,
@ViewBuilder start: () -> Body,
@ViewBuilder end: () -> Body
) {
self._splitter = splitter
self.start = start()
self.end = end()
}
}
/// A vertical split view.
public struct VSplitView: SimpleView {
/// The splitter.
@Binding var splitter: Int
/// The start widget.
var start: Body
/// The end widget.
var end: Body
/// The view.
public var view: Body {
SplitView(splitter: $splitter, vertical: true, start: start, end: end)
}
/// Initialize a vertical split view.
/// - Parameters:
/// - splitter: The position of the splitter.
/// - start: The start widget.
/// - end: The end widget.
public init(
splitter: Binding<Int>,
@ViewBuilder start: () -> Body,
@ViewBuilder end: () -> Body
) {
self._splitter = splitter
self.start = start()
self.end = end()
}
}

View File

@ -33,6 +33,7 @@ enum Page: String, Identifiable, CaseIterable, Codable, CustomStringConvertible
case idle case idle
case fixed case fixed
case textEditor case textEditor
case splitView
var id: Self { var id: Self {
self self
@ -52,6 +53,8 @@ enum Page: String, Identifiable, CaseIterable, Codable, CustomStringConvertible
return "Password Checker" return "Password Checker"
case .textEditor: case .textEditor:
return "Text Editor" return "Text Editor"
case .splitView:
return "Split View"
default: default:
return rawValue.capitalized return rawValue.capitalized
} }
@ -110,6 +113,8 @@ enum Page: String, Identifiable, CaseIterable, Codable, CustomStringConvertible
return "Place widgets in a coordinate system" return "Place widgets in a coordinate system"
case .textEditor: case .textEditor:
return "A simple text editor" return "A simple text editor"
case .splitView:
return "A split view whose panes are ajustable in size"
} }
} }
@ -159,6 +164,8 @@ enum Page: String, Identifiable, CaseIterable, Codable, CustomStringConvertible
FixedDemo() FixedDemo()
case .textEditor: case .textEditor:
TextEditorDemo() TextEditorDemo()
case .splitView:
SplitViewDemo()
} }
} }
// swiftlint:enable cyclomatic_complexity // swiftlint:enable cyclomatic_complexity

View File

@ -0,0 +1,29 @@
//
// SplitViewDemo.swift
// Adwaita
//
// Created by david-swift on 16.09.25.
//
// swiftlint:disable missing_docs
import Adwaita
struct SplitViewDemo: View {
@State private var splitter = 200
var view: Body {
HSplitView(splitter: $splitter) {
Text("\(splitter) Pixels")
} end: {
Text("View 2")
}
.frame(minHeight: 200)
.card()
.padding()
}
}
// swiftlint:enable missing_docs