-
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reenable and update Picker after adding support for multiple backends…
… (it's so much cleaner now)
- Loading branch information
1 parent
66d37b3
commit ca0765f
Showing
3 changed files
with
135 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,47 @@ | ||
// import CGtk | ||
|
||
// // TODO: This Picker implementation should be able to be cleaned | ||
// // up immensely. Especially once ViewContent and View are combined. | ||
|
||
// // TODO: Move this elsewhere | ||
// public class Box<T> { | ||
// var wrappedValue: T | ||
|
||
// init(_ value: T) { | ||
// wrappedValue = value | ||
// } | ||
// } | ||
|
||
// /// Custom view content storage is required to store the previous set | ||
// /// of options to avoid infinite loops caused by repeatedly setting | ||
// /// options. Every time the options change, the selected index gets | ||
// /// updated, and then the view gets updated. If the view update causes | ||
// /// the index to be updated every single time, then an infinite loop | ||
// /// occurs. Using the view content as the children is possible as this | ||
// /// is just a simple way to store persistent data in the view graph. | ||
// public struct PickerViewContent: ViewContent, ViewGraphNodeChildren { | ||
// public typealias Children = Self | ||
// public typealias Content = Self | ||
|
||
// var lastOptions: Box<[String]?> | ||
|
||
// public var widgets: [AnyWidget] = [] | ||
|
||
// public init(from content: Content) { | ||
// self = content | ||
// } | ||
|
||
// init<Backend: AppBackend>(lastOptions: [String]?, backend: Backend) { | ||
// self.lastOptions = Box(lastOptions) | ||
// } | ||
|
||
// // Children will share the same Box as the content, so no need to update. | ||
// public func update<Backend: AppBackend>(with content: Content, backend: Backend) {} | ||
// } | ||
|
||
// /// A picker view. | ||
// public struct Picker<Value: Equatable>: View { | ||
// public typealias Content = PickerViewContent | ||
|
||
// public var body = PickerViewContent(lastOptions: nil) | ||
|
||
// /// The string to be shown in the text view. | ||
// private var options: [Value] | ||
// /// Specifies whether the text should be wrapped if wider than its container. | ||
// private var value: Binding<Value?> | ||
|
||
// /// Creates a new text view with the given content. | ||
// public init(of options: [Value], selection value: Binding<Value?>) { | ||
// self.options = options | ||
// self.value = value | ||
// } | ||
|
||
// public func asWidget(_ children: PickerViewContent.Children) -> GtkDropDown { | ||
// // TODO: Figure out why it crashes when given an empty array of strings | ||
// let optionStrings = options.map({ "\($0)" }) | ||
// let widget = GtkDropDown(strings: optionStrings) | ||
// children.lastOptions.wrappedValue = optionStrings | ||
|
||
// let options = options | ||
// widget.notifySelected = { [weak widget] in | ||
// guard let widget = widget else { | ||
// return | ||
// } | ||
|
||
// if Int(widget.selected) >= options.count { | ||
// self.value.wrappedValue = nil | ||
// } else { | ||
// self.value.wrappedValue = options[Int(widget.selected)] | ||
// } | ||
// } | ||
// return widget | ||
// } | ||
|
||
// public func update(_ widget: GtkDropDown, children: PickerViewContent.Children) { | ||
// let index: Int | ||
// if let selectedOption = value.wrappedValue { | ||
// index = | ||
// options.firstIndex { option in | ||
// return option == selectedOption | ||
// } ?? Int(GTK_INVALID_LIST_POSITION) | ||
// } else { | ||
// index = Int(GTK_INVALID_LIST_POSITION) | ||
// } | ||
|
||
// if widget.selected != index { | ||
// widget.selected = index | ||
// } | ||
|
||
// let options = options.map({ "\($0)" }) | ||
// if options != children.lastOptions.wrappedValue { | ||
// widget.model = gtk_string_list_new( | ||
// UnsafePointer( | ||
// options | ||
// .map({ UnsafePointer($0.unsafeUTF8Copy().baseAddress) }) | ||
// .unsafeCopy() | ||
// .baseAddress | ||
// ) | ||
// ) | ||
// children.lastOptions.wrappedValue = options | ||
// } | ||
// } | ||
// } | ||
import CGtk | ||
|
||
/// A picker view. | ||
public struct Picker<Value: Equatable>: View { | ||
public var body = EmptyViewContent() | ||
|
||
/// The string to be shown in the text view. | ||
private var options: [Value] | ||
/// Specifies whether the text should be wrapped if wider than its container. | ||
private var value: Binding<Value?> | ||
|
||
/// The index of the selected option (if any). | ||
private var selectedOptionIndex: Int? { | ||
return options.firstIndex { option in | ||
return option == value.wrappedValue | ||
} | ||
} | ||
|
||
/// Creates a new text view with the given content. | ||
public init(of options: [Value], selection value: Binding<Value?>) { | ||
self.options = options | ||
self.value = value | ||
} | ||
|
||
public func asWidget<Backend: AppBackend>( | ||
_ children: EmptyViewContent.Children, | ||
backend: Backend | ||
) -> Backend.Widget { | ||
return backend.createPicker( | ||
options: options.map { "\($0)" }, | ||
selectedOption: selectedOptionIndex | ||
) { selectedIndex in | ||
guard let selectedIndex = selectedIndex else { | ||
value.wrappedValue = nil | ||
return | ||
} | ||
value.wrappedValue = options[selectedIndex] | ||
} | ||
} | ||
|
||
public func update<Backend: AppBackend>( | ||
_ widget: Backend.Widget, children: EmptyViewContent.Children, backend: Backend | ||
) { | ||
backend.setOptions(ofPicker: widget, to: options.map { "\($0)" }) | ||
backend.setSelectedOption(ofPicker: widget, to: selectedOptionIndex) | ||
} | ||
} |