forked from aparoksha/adwaita-swift
Compare commits
No commits in common. "ebb2455fe1ec54ec8841d251db8cc39a92c39e4a" and "daa922d33b4fdd45795978de3e13a69b57c08310" have entirely different histories.
ebb2455fe1
...
daa922d33b
@ -1,43 +0,0 @@
|
|||||||
//
|
|
||||||
// WrapMode.swift
|
|
||||||
// Adwaita
|
|
||||||
//
|
|
||||||
// Created by mlm on 24.08.25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import CAdw
|
|
||||||
|
|
||||||
/// Wrap modes for `TextView`/`TextEditor`
|
|
||||||
public enum WrapMode: GtkWrapMode, RawRepresentable {
|
|
||||||
|
|
||||||
// swiftlint:disable discouraged_none_name
|
|
||||||
/// GTK_WRAP_NONE
|
|
||||||
case none
|
|
||||||
// swiftlint:enable discouraged_none_name
|
|
||||||
/// GTK_WRAP_CHAR
|
|
||||||
case char
|
|
||||||
/// GTK_WRAP_WORD
|
|
||||||
case word
|
|
||||||
/// GTK_WRAP_WORD_CHAR
|
|
||||||
case wordChar
|
|
||||||
|
|
||||||
/// Get the GtkWrapMode.
|
|
||||||
public var rawValue: GtkWrapMode {
|
|
||||||
switch self {
|
|
||||||
case .none:
|
|
||||||
GTK_WRAP_NONE
|
|
||||||
case .char:
|
|
||||||
GTK_WRAP_CHAR
|
|
||||||
case .word:
|
|
||||||
GTK_WRAP_WORD
|
|
||||||
case .wordChar:
|
|
||||||
GTK_WRAP_WORD_CHAR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialize from the GtkWrapMode.
|
|
||||||
/// - Parameter rawValue: The GtkWrapMode.
|
|
||||||
public init?(rawValue: GtkWrapMode) {
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// GtkWrapMode.swift
|
|
||||||
// Adwaita
|
|
||||||
//
|
|
||||||
// Created by mlm on 24.08.25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import CAdw
|
|
||||||
|
|
||||||
/// Add ExpressibleByIntegerLiteral conformance to make GtkWrapMode usable as
|
|
||||||
/// a RawValue in an enum.
|
|
||||||
extension GtkWrapMode: @retroactive ExpressibleByIntegerLiteral {
|
|
||||||
|
|
||||||
/// Initialize from an integer literal.
|
|
||||||
public init(integerLiteral value: Int) {
|
|
||||||
self.init(UInt32(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -14,75 +14,73 @@ public typealias TextEditor = TextView
|
|||||||
public struct TextView: AdwaitaWidget {
|
public struct TextView: AdwaitaWidget {
|
||||||
|
|
||||||
/// The editor's content.
|
/// The editor's content.
|
||||||
@BindingProperty(
|
@Binding var text: String
|
||||||
observe: { _, text, storage in
|
|
||||||
if let buffer = storage.content["buffer"]?.first {
|
|
||||||
buffer.connectSignal(name: "changed") {
|
|
||||||
let currentText = Self.getText(buffer: buffer)
|
|
||||||
if text.wrappedValue != currentText {
|
|
||||||
text.wrappedValue = currentText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set: { _, text, storage in
|
|
||||||
if let buffer = storage.content["buffer"]?.first, Self.getText(buffer: buffer) != text {
|
|
||||||
gtk_text_buffer_set_text(buffer.opaquePointer?.cast(), text, -1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pointer: Any.self
|
|
||||||
)
|
|
||||||
var text: Binding<String> = .constant("")
|
|
||||||
/// The padding between the border and the content.
|
/// The padding between the border and the content.
|
||||||
@Property(
|
var padding = 0
|
||||||
set: { $1.set($0) },
|
/// The edges affected by the padding.
|
||||||
pointer: OpaquePointer.self
|
var paddingEdges: Set<Edge> = []
|
||||||
)
|
|
||||||
var padding: InnerPadding?
|
|
||||||
/// The (word) wrap mode used when rendering the text.
|
|
||||||
@Property(
|
|
||||||
set: { gtk_text_view_set_wrap_mode($0.cast(), $1.rawValue) },
|
|
||||||
pointer: OpaquePointer.self
|
|
||||||
)
|
|
||||||
var wrapMode: WrapMode = .none
|
|
||||||
|
|
||||||
/// Initialize a text editor.
|
/// Initialize a text editor.
|
||||||
/// - Parameter text: The editor's content.
|
/// - Parameter text: The editor's content.
|
||||||
public init(text: Binding<String>) {
|
public init(text: Binding<String>) {
|
||||||
self.text = text
|
self._text = text
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inner padding of a text view.
|
/// Get the editor's view storage.
|
||||||
struct InnerPadding {
|
/// - Parameters:
|
||||||
|
/// - data: The widget data.
|
||||||
|
/// - type: The view render data type.
|
||||||
|
/// - Returns: The view storage.
|
||||||
|
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage {
|
||||||
|
let buffer = ViewStorage(gtk_text_buffer_new(nil)?.opaque())
|
||||||
|
let editor = ViewStorage(
|
||||||
|
gtk_text_view_new_with_buffer(buffer.opaquePointer?.cast())?.opaque(),
|
||||||
|
content: ["buffer": [buffer]]
|
||||||
|
)
|
||||||
|
update(editor, data: data, updateProperties: true, type: type)
|
||||||
|
return editor
|
||||||
|
}
|
||||||
|
|
||||||
/// The padding.
|
/// Update a view storage to the editor.
|
||||||
var padding: Int
|
/// - Parameters:
|
||||||
/// The affected edges.
|
/// - storage: The view storage.
|
||||||
var paddingEdges: Set<Edge>
|
/// - data: The widget data.
|
||||||
|
/// - updateProperties: Whether to update the view's properties.
|
||||||
/// Set the inner padding on a text view.
|
/// - type: The view render data type.
|
||||||
/// - Parameter pointer: The text view.
|
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) {
|
||||||
func set(_ pointer: OpaquePointer) {
|
if let buffer = storage.content["buffer"]?.first {
|
||||||
if paddingEdges.contains(.top) {
|
buffer.connectSignal(name: "changed") {
|
||||||
gtk_text_view_set_top_margin(pointer.cast(), padding.cInt)
|
let text = getText(buffer: buffer)
|
||||||
|
if self.text != text {
|
||||||
|
self.text = text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if paddingEdges.contains(.bottom) {
|
if updateProperties {
|
||||||
gtk_text_view_set_bottom_margin(pointer.cast(), padding.cInt)
|
if getText(buffer: buffer) != self.text {
|
||||||
}
|
gtk_text_buffer_set_text(buffer.opaquePointer?.cast(), text, -1)
|
||||||
if paddingEdges.contains(.leading) {
|
}
|
||||||
gtk_text_view_set_left_margin(pointer.cast(), padding.cInt)
|
}
|
||||||
}
|
}
|
||||||
if paddingEdges.contains(.trailing) {
|
if updateProperties {
|
||||||
gtk_text_view_set_right_margin(pointer.cast(), padding.cInt)
|
if paddingEdges.contains(.top) {
|
||||||
|
gtk_text_view_set_top_margin(storage.opaquePointer?.cast(), padding.cInt)
|
||||||
|
}
|
||||||
|
if paddingEdges.contains(.bottom) {
|
||||||
|
gtk_text_view_set_bottom_margin(storage.opaquePointer?.cast(), padding.cInt)
|
||||||
|
}
|
||||||
|
if paddingEdges.contains(.leading) {
|
||||||
|
gtk_text_view_set_left_margin(storage.opaquePointer?.cast(), padding.cInt)
|
||||||
|
}
|
||||||
|
if paddingEdges.contains(.trailing) {
|
||||||
|
gtk_text_view_set_right_margin(storage.opaquePointer?.cast(), padding.cInt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the text view's content.
|
/// Get the text view's content.
|
||||||
/// - Parameter buffer: The text view's buffer.
|
/// - Parameter buffer: The text view's buffer.
|
||||||
/// - Returns: The content.
|
/// - Returns: The content.
|
||||||
static func getText(buffer: ViewStorage) -> String {
|
func getText(buffer: ViewStorage) -> String {
|
||||||
let startIter: UnsafeMutablePointer<GtkTextIter> = .allocate(capacity: 1)
|
let startIter: UnsafeMutablePointer<GtkTextIter> = .allocate(capacity: 1)
|
||||||
let endIter: UnsafeMutablePointer<GtkTextIter> = .allocate(capacity: 1)
|
let endIter: UnsafeMutablePointer<GtkTextIter> = .allocate(capacity: 1)
|
||||||
gtk_text_buffer_get_start_iter(buffer.opaquePointer?.cast(), startIter)
|
gtk_text_buffer_get_start_iter(buffer.opaquePointer?.cast(), startIter)
|
||||||
@ -92,34 +90,6 @@ public struct TextView: AdwaitaWidget {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the editor's view storage.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - data: The widget data.
|
|
||||||
/// - type: The view render data type.
|
|
||||||
/// - Returns: The view storage.
|
|
||||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
|
||||||
let buffer = ViewStorage(gtk_text_buffer_new(nil)?.opaque())
|
|
||||||
let editor = ViewStorage(
|
|
||||||
gtk_text_view_new_with_buffer(buffer.opaquePointer?.cast())?.opaque(),
|
|
||||||
content: ["buffer": [buffer]]
|
|
||||||
)
|
|
||||||
initProperties(editor, data: data, type: type)
|
|
||||||
update(editor, data: data, updateProperties: true, type: type)
|
|
||||||
return editor
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the wrapMode for the text view.
|
|
||||||
///
|
|
||||||
/// Available wrap modes are `none`, `char`, `word`, `wordChar`. Please refer to the
|
|
||||||
/// corresponding `GtkWrapMode` documentation for the details on how they work.
|
|
||||||
///
|
|
||||||
/// - Parameter mode: The `WrapMode` to set.
|
|
||||||
public func wrapMode(_ mode: WrapMode) -> Self {
|
|
||||||
var newSelf = self
|
|
||||||
newSelf.wrapMode = mode
|
|
||||||
return newSelf
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add padding between the editor's content and border.
|
/// Add padding between the editor's content and border.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - padding: The padding's value.
|
/// - padding: The padding's value.
|
||||||
@ -127,7 +97,8 @@ public struct TextView: AdwaitaWidget {
|
|||||||
/// - Returns: The editor.
|
/// - Returns: The editor.
|
||||||
public func innerPadding(_ padding: Int = 10, edges: Set<Edge> = .all) -> Self {
|
public func innerPadding(_ padding: Int = 10, edges: Set<Edge> = .all) -> Self {
|
||||||
var newSelf = self
|
var newSelf = self
|
||||||
newSelf.padding = .init(padding: padding, paddingEdges: edges)
|
newSelf.padding = padding
|
||||||
|
newSelf.paddingEdges = edges
|
||||||
return newSelf
|
return newSelf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user