|
| 1 | +import CGtk |
| 2 | + |
| 3 | +/// Dialogs are a convenient way to prompt the user for a small amount |
| 4 | +/// of input. |
| 5 | +/// |
| 6 | +///  |
| 7 | +/// |
| 8 | +/// Typical uses are to display a message, ask a question, or anything else |
| 9 | +/// that does not require extensive effort on the user’s part. |
| 10 | +/// |
| 11 | +/// The main area of a `GtkDialog` is called the "content area", and is yours |
| 12 | +/// to populate with widgets such a `GtkLabel` or `GtkEntry`, to present |
| 13 | +/// your information, questions, or tasks to the user. |
| 14 | +/// |
| 15 | +/// In addition, dialogs allow you to add "action widgets". Most commonly, |
| 16 | +/// action widgets are buttons. Depending on the platform, action widgets may |
| 17 | +/// be presented in the header bar at the top of the window, or at the bottom |
| 18 | +/// of the window. To add action widgets, create your `GtkDialog` using |
| 19 | +/// [ctor@Gtk.Dialog.new_with_buttons], or use |
| 20 | +/// [method@Gtk.Dialog.add_button], [method@Gtk.Dialog.add_buttons], |
| 21 | +/// or [method@Gtk.Dialog.add_action_widget]. |
| 22 | +/// |
| 23 | +/// `GtkDialogs` uses some heuristics to decide whether to add a close |
| 24 | +/// button to the window decorations. If any of the action buttons use |
| 25 | +/// the response ID %GTK_RESPONSE_CLOSE or %GTK_RESPONSE_CANCEL, the |
| 26 | +/// close button is omitted. |
| 27 | +/// |
| 28 | +/// Clicking a button that was added as an action widget will emit the |
| 29 | +/// [signal@Gtk.Dialog::response] signal with a response ID that you specified. |
| 30 | +/// GTK will never assign a meaning to positive response IDs; these are |
| 31 | +/// entirely user-defined. But for convenience, you can use the response |
| 32 | +/// IDs in the [enum@Gtk.ResponseType] enumeration (these all have values |
| 33 | +/// less than zero). If a dialog receives a delete event, the |
| 34 | +/// [signal@Gtk.Dialog::response] signal will be emitted with the |
| 35 | +/// %GTK_RESPONSE_DELETE_EVENT response ID. |
| 36 | +/// |
| 37 | +/// Dialogs are created with a call to [ctor@Gtk.Dialog.new] or |
| 38 | +/// [ctor@Gtk.Dialog.new_with_buttons]. The latter is recommended; it allows |
| 39 | +/// you to set the dialog title, some convenient flags, and add buttons. |
| 40 | +/// |
| 41 | +/// A “modal” dialog (that is, one which freezes the rest of the application |
| 42 | +/// from user input), can be created by calling [method@Gtk.Window.set_modal] |
| 43 | +/// on the dialog. When using [ctor@Gtk.Dialog.new_with_buttons], you can also |
| 44 | +/// pass the %GTK_DIALOG_MODAL flag to make a dialog modal. |
| 45 | +/// |
| 46 | +/// For the simple dialog in the following example, a [class@Gtk.MessageDialog] |
| 47 | +/// would save some effort. But you’d need to create the dialog contents manually |
| 48 | +/// if you had more than a simple message in the dialog. |
| 49 | +/// |
| 50 | +/// An example for simple `GtkDialog` usage: |
| 51 | +/// |
| 52 | +/// ```c |
| 53 | +/// // Function to open a dialog box with a message |
| 54 | +/// void |
| 55 | +/// quick_message (GtkWindow *parent, char *message) |
| 56 | +/// { |
| 57 | +/// GtkWidget *dialog, *label, *content_area; |
| 58 | +/// GtkDialogFlags flags; |
| 59 | +/// |
| 60 | +/// // Create the widgets |
| 61 | +/// flags = GTK_DIALOG_DESTROY_WITH_PARENT; |
| 62 | +/// dialog = gtk_dialog_new_with_buttons ("Message", |
| 63 | +/// parent, |
| 64 | +/// flags, |
| 65 | +/// _("_OK"), |
| 66 | +/// GTK_RESPONSE_NONE, |
| 67 | +/// NULL); |
| 68 | +/// content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); |
| 69 | +/// label = gtk_label_new (message); |
| 70 | +/// |
| 71 | +/// // Ensure that the dialog box is destroyed when the user responds |
| 72 | +/// |
| 73 | +/// g_signal_connect_swapped (dialog, |
| 74 | +/// "response", |
| 75 | +/// G_CALLBACK (gtk_window_destroy), |
| 76 | +/// dialog); |
| 77 | +/// |
| 78 | +/// // Add the label, and show everything we’ve added |
| 79 | +/// |
| 80 | +/// gtk_box_append (GTK_BOX (content_area), label); |
| 81 | +/// gtk_widget_show (dialog); |
| 82 | +/// } |
| 83 | +/// ``` |
| 84 | +/// |
| 85 | +/// # GtkDialog as GtkBuildable |
| 86 | +/// |
| 87 | +/// The `GtkDialog` implementation of the `GtkBuildable` interface exposes the |
| 88 | +/// @content_area as an internal child with the name “content_area”. |
| 89 | +/// |
| 90 | +/// `GtkDialog` supports a custom `<action-widgets>` element, which can contain |
| 91 | +/// multiple `<action-widget>` elements. The “response” attribute specifies a |
| 92 | +/// numeric response, and the content of the element is the id of widget |
| 93 | +/// (which should be a child of the dialogs @action_area). To mark a response |
| 94 | +/// as default, set the “default” attribute of the `<action-widget>` element |
| 95 | +/// to true. |
| 96 | +/// |
| 97 | +/// `GtkDialog` supports adding action widgets by specifying “action” as |
| 98 | +/// the “type” attribute of a `<child>` element. The widget will be added |
| 99 | +/// either to the action area or the headerbar of the dialog, depending |
| 100 | +/// on the “use-header-bar” property. The response id has to be associated |
| 101 | +/// with the action widget using the `<action-widgets>` element. |
| 102 | +/// |
| 103 | +/// An example of a `GtkDialog` UI definition fragment: |
| 104 | +/// |
| 105 | +/// ```xml |
| 106 | +/// <object class="GtkDialog" id="dialog1"><child type="action"><object class="GtkButton" id="button_cancel"/></child><child type="action"><object class="GtkButton" id="button_ok"></object></child><action-widgets><action-widget response="cancel">button_cancel</action-widget><action-widget response="ok" default="true">button_ok</action-widget></action-widgets></object> |
| 107 | +/// ``` |
| 108 | +/// |
| 109 | +/// # Accessibility |
| 110 | +/// |
| 111 | +/// `GtkDialog` uses the %GTK_ACCESSIBLE_ROLE_DIALOG role. |
| 112 | +open class Dialog: Window { |
| 113 | + /// Creates a new dialog box. |
| 114 | + /// |
| 115 | + /// Widgets should not be packed into the `GtkWindow` |
| 116 | + /// directly, but into the @content_area and @action_area, |
| 117 | + /// as described above. |
| 118 | + override public init() { |
| 119 | + super.init() |
| 120 | + widgetPointer = gtk_dialog_new() |
| 121 | + } |
| 122 | + |
| 123 | + func registerSignalHandlers() { |
| 124 | + removeSignals() |
| 125 | + |
| 126 | + super.didMoveToParent() |
| 127 | + |
| 128 | + addSignal(name: "close") { [weak self] () in |
| 129 | + guard let self = self else { return } |
| 130 | + self.close?(self) |
| 131 | + } |
| 132 | + |
| 133 | + let handler1: |
| 134 | + @convention(c) (UnsafeMutableRawPointer, Int, UnsafeMutableRawPointer) -> Void = |
| 135 | + { _, value1, data in |
| 136 | + SignalBox1<Int>.run(data, value1) |
| 137 | + } |
| 138 | + |
| 139 | + addSignal(name: "response", handler: gCallback(handler1)) { [weak self] (responseId: Int) in |
| 140 | + guard let self = self else { return } |
| 141 | + self.response?(self, responseId) |
| 142 | + } |
| 143 | + |
| 144 | + let handler2: |
| 145 | + @convention(c) (UnsafeMutableRawPointer, OpaquePointer, UnsafeMutableRawPointer) -> Void = |
| 146 | + { _, value1, data in |
| 147 | + SignalBox1<OpaquePointer>.run(data, value1) |
| 148 | + } |
| 149 | + |
| 150 | + addSignal(name: "notify::use-header-bar", handler: gCallback(handler2)) { |
| 151 | + [weak self] (_: OpaquePointer) in |
| 152 | + guard let self = self else { return } |
| 153 | + self.notifyUseHeaderBar?(self) |
| 154 | + } |
| 155 | + } |
| 156 | + |
| 157 | + public func addButton(label: String, responseId: Int) { |
| 158 | + gtk_dialog_add_button( |
| 159 | + castedPointer(), |
| 160 | + label, |
| 161 | + Int32(responseId) |
| 162 | + ) |
| 163 | + } |
| 164 | + |
| 165 | + /// Show the dialog and set up signal handlers. |
| 166 | + override public func show() { |
| 167 | + registerSignalHandlers() |
| 168 | + super.show() |
| 169 | + } |
| 170 | + |
| 171 | + /// Emitted when the user uses a keybinding to close the dialog. |
| 172 | + /// |
| 173 | + /// This is a [keybinding signal](class.SignalAction.html). |
| 174 | + /// |
| 175 | + /// The default binding for this signal is the Escape key. |
| 176 | + public var close: ((Dialog) -> Void)? |
| 177 | + |
| 178 | + /// Emitted when an action widget is clicked. |
| 179 | + /// |
| 180 | + /// The signal is also emitted when the dialog receives a |
| 181 | + /// delete event, and when [method@Gtk.Dialog.response] is called. |
| 182 | + /// On a delete event, the response ID is %GTK_RESPONSE_DELETE_EVENT. |
| 183 | + /// Otherwise, it depends on which action widget was clicked. |
| 184 | + public var response: ((Dialog, Int) -> Void)? |
| 185 | + |
| 186 | + public var notifyUseHeaderBar: ((Dialog) -> Void)? |
| 187 | +} |
0 commit comments