1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.Dialog;
26 
27 private import gdk.Screen;
28 private import glib.ConstructionException;
29 private import glib.Str;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gtk.Button;
33 private import gtk.HButtonBox;
34 private import gtk.VBox;
35 private import gtk.Widget;
36 private import gtk.Window;
37 public  import gtkc.gdktypes;
38 private import gtkc.gtk;
39 public  import gtkc.gtktypes;
40 
41 
42 /**
43  * Dialog boxes are a convenient way to prompt the user for a small amount
44  * of input, e.g. to display a message, ask a question, or anything else
45  * that does not require extensive effort on the user’s part.
46  * 
47  * GTK+ treats a dialog as a window split vertically. The top section is a
48  * #GtkVBox, and is where widgets such as a #GtkLabel or a #GtkEntry should
49  * be packed. The bottom area is known as the
50  * “action area”. This is generally used for
51  * packing buttons into the dialog which may perform functions such as
52  * cancel, ok, or apply.
53  * 
54  * #GtkDialog boxes are created with a call to gtk_dialog_new() or
55  * gtk_dialog_new_with_buttons(). gtk_dialog_new_with_buttons() is
56  * recommended; it allows you to set the dialog title, some convenient
57  * flags, and add simple buttons.
58  * 
59  * If “dialog” is a newly created dialog, the two primary areas of the
60  * window can be accessed through gtk_dialog_get_content_area() and
61  * gtk_dialog_get_action_area(), as can be seen from the example below.
62  * 
63  * A “modal” dialog (that is, one which freezes the rest of the application
64  * from user input), can be created by calling gtk_window_set_modal() on the
65  * dialog. Use the GTK_WINDOW() macro to cast the widget returned from
66  * gtk_dialog_new() into a #GtkWindow. When using gtk_dialog_new_with_buttons()
67  * you can also pass the #GTK_DIALOG_MODAL flag to make a dialog modal.
68  * 
69  * If you add buttons to #GtkDialog using gtk_dialog_new_with_buttons(),
70  * gtk_dialog_add_button(), gtk_dialog_add_buttons(), or
71  * gtk_dialog_add_action_widget(), clicking the button will emit a signal
72  * called #GtkDialog::response with a response ID that you specified. GTK+
73  * will never assign a meaning to positive response IDs; these are entirely
74  * user-defined. But for convenience, you can use the response IDs in the
75  * #GtkResponseType enumeration (these all have values less than zero). If
76  * a dialog receives a delete event, the #GtkDialog::response signal will
77  * be emitted with a response ID of #GTK_RESPONSE_DELETE_EVENT.
78  * 
79  * If you want to block waiting for a dialog to return before returning
80  * control flow to your code, you can call gtk_dialog_run(). This function
81  * enters a recursive main loop and waits for the user to respond to the
82  * dialog, returning the response ID corresponding to the button the user
83  * clicked.
84  * 
85  * For the simple dialog in the following example, in reality you’d probably
86  * use #GtkMessageDialog to save yourself some effort. But you’d need to
87  * create the dialog contents manually if you had more than a simple message
88  * in the dialog.
89  * 
90  * An example for simple GtkDialog usage:
91  * |[<!-- language="C" -->
92  * // Function to open a dialog box with a message
93  * void
94  * quick_message (GtkWindow *parent, gchar *message)
95  * {
96  * GtkWidget *dialog, *label, *content_area;
97  * GtkDialogFlags flags;
98  * 
99  * // Create the widgets
100  * flags = GTK_DIALOG_DESTROY_WITH_PARENT;
101  * dialog = gtk_dialog_new_with_buttons ("Message",
102  * parent,
103  * flags,
104  * _("_OK"),
105  * GTK_RESPONSE_NONE,
106  * NULL);
107  * content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
108  * label = gtk_label_new (message);
109  * 
110  * // Ensure that the dialog box is destroyed when the user responds
111  * 
112  * g_signal_connect_swapped (dialog,
113  * "response",
114  * G_CALLBACK (gtk_widget_destroy),
115  * dialog);
116  * 
117  * // Add the label, and show everything we’ve added
118  * 
119  * gtk_container_add (GTK_CONTAINER (content_area), label);
120  * gtk_widget_show_all (dialog);
121  * }
122  * ]|
123  * 
124  * # GtkDialog as GtkBuildable
125  * 
126  * The GtkDialog implementation of the #GtkBuildable interface exposes the
127  * @vbox and @action_area as internal children with the names “vbox” and
128  * “action_area”.
129  * 
130  * GtkDialog supports a custom <action-widgets> element, which can contain
131  * multiple <action-widget> elements. The “response” attribute specifies a
132  * numeric response, and the content of the element is the id of widget
133  * (which should be a child of the dialogs @action_area). To mark a response
134  * as default, set the “default“ attribute of the <action-widget> element
135  * to true.
136  * 
137  * GtkDialog supports adding action widgets by specifying “action“ as
138  * the “type“ attribute of a <child> element. The widget will be added
139  * either to the action area or the headerbar of the dialog, depending
140  * on the “use-header-bar“ property. The response id has to be associated
141  * with the action widget using the <action-widgets> element.
142  * 
143  * An example of a #GtkDialog UI definition fragment:
144  * |[
145  * <object class="GtkDialog" id="dialog1">
146  * <child type="action">
147  * <object class="GtkButton" id="button_cancel"/>
148  * </child>
149  * <child type="action">
150  * <object class="GtkButton" id="button_ok">
151  * <property name="can-default">True</property>
152  * </object>
153  * </child>
154  * <action-widgets>
155  * <action-widget response="cancel">button_cancel</action-widget>
156  * <action-widget response="ok" default="true">button_ok</action-widget>
157  * </action-widgets>
158  * </object>
159  * ]|
160  */
161 public class Dialog : Window
162 {
163 	/** the main Gtk struct */
164 	protected GtkDialog* gtkDialog;
165 
166 	/** Get the main Gtk struct */
167 	public GtkDialog* getDialogStruct()
168 	{
169 		return gtkDialog;
170 	}
171 
172 	/** the main Gtk struct as a void* */
173 	protected override void* getStruct()
174 	{
175 		return cast(void*)gtkDialog;
176 	}
177 
178 	protected override void setStruct(GObject* obj)
179 	{
180 		gtkDialog = cast(GtkDialog*)obj;
181 		super.setStruct(obj);
182 	}
183 
184 	/**
185 	 * Sets our main struct and passes it to the parent class.
186 	 */
187 	public this (GtkDialog* gtkDialog, bool ownedRef = false)
188 	{
189 		this.gtkDialog = gtkDialog;
190 		super(cast(GtkWindow*)gtkDialog, ownedRef);
191 	}
192 
193 	/**
194 	 * Both title and parent can be null.
195 	 */
196 	this(string title, Window parent, GtkDialogFlags flags, string[] buttonsText, ResponseType[] responses)
197 	{
198 		auto p = gtk_dialog_new_with_buttons(Str.toStringz(title), (parent is null) ? null : parent.getWindowStruct(), flags, Str.toStringz(buttonsText[0]), responses[0], null);
199 		if(p is null)
200 		{
201 			throw new ConstructionException("null returned by gtk_dialog_new_with_buttons");
202 		}
203 		
204 		this(cast(GtkDialog*)p);
205 		
206 		addButtons(buttonsText[1 .. $], responses[1 .. $]);
207 	}
208 	
209 	/** ditto */
210 	this(string title, Window parent, GtkDialogFlags flags, StockID[] stockIDs, ResponseType[] responses)
211 	{
212 		auto p = gtk_dialog_new_with_buttons(Str.toStringz(title), (parent is null) ? null : parent.getWindowStruct(), flags, Str.toStringz(stockIDs[0]), responses[0], null);
213 		if(p is null)
214 		{
215 			throw new ConstructionException("null returned by gtk_dialog_new_with_buttons");
216 		}
217 		
218 		this(cast(GtkDialog*)p);
219 		
220 		addButtons(stockIDs[1 .. $], responses[1 .. $]);
221 	}
222 	
223 	/** */
224 	public Button addButton(StockID stockID, int responseId)
225 	{
226 		auto p = gtk_dialog_add_button(gtkDialog, Str.toStringz(stockID), responseId);
227 		
228 		if ( p is null )
229 		{
230 			return null;
231 		}
232 		
233 		return new Button(cast(GtkButton*)p);
234 	}
235 	
236 	/** */
237 	public void addButtons(string[] buttonsText, ResponseType[] responses)
238 	{
239 		for ( int i=0 ; i<buttonsText.length && i<responses.length ; i++)
240 		{
241 			addButton(buttonsText[i], responses[i]);
242 		}
243 	}
244 	
245 	/** */
246 	public void addButtons(StockID[] stockIDs, ResponseType[] responses)
247 	{
248 		for ( int i=0 ; i<stockIDs.length && i<responses.length ; i++)
249 		{
250 			addButton(stockIDs[i], responses[i]);
251 		}
252 	}
253 	
254 	//Return the corect class instead of Widget
255 	/**
256 	 * Returns the action area of dialog.
257 	 * Since: 2.14
258 	 * Returns: the action area.
259 	 */
260 	public HButtonBox getActionArea()
261 	{
262 		auto p = gtk_dialog_get_action_area(gtkDialog);
263 		if(p is null)
264 		{
265 			return null;
266 		}
267 		return new HButtonBox(cast(GtkHButtonBox*) p);
268 	}
269 	
270 	//Return the corect class instead of Widget
271 	/**
272 	 * Returns the content area of dialog.
273 	 * Since: 2.14
274 	 * Returns: the content area GtkVBox.
275 	 */
276 	public VBox getContentArea()
277 	{
278 		auto p = gtk_dialog_get_content_area(gtkDialog);
279 		if(p is null)
280 		{
281 			return null;
282 		}
283 		return new VBox(cast(GtkVBox*) p);
284 	}
285 
286 	/**
287 	 */
288 
289 	/** */
290 	public static GType getType()
291 	{
292 		return gtk_dialog_get_type();
293 	}
294 
295 	/**
296 	 * Creates a new dialog box.
297 	 *
298 	 * Widgets should not be packed into this #GtkWindow
299 	 * directly, but into the @vbox and @action_area, as described above.
300 	 *
301 	 * Return: the new dialog as a #GtkWidget
302 	 *
303 	 * Throws: ConstructionException GTK+ fails to create the object.
304 	 */
305 	public this()
306 	{
307 		auto p = gtk_dialog_new();
308 		
309 		if(p is null)
310 		{
311 			throw new ConstructionException("null returned by new");
312 		}
313 		
314 		this(cast(GtkDialog*) p);
315 	}
316 
317 	/**
318 	 * Adds an activatable widget to the action area of a #GtkDialog,
319 	 * connecting a signal handler that will emit the #GtkDialog::response
320 	 * signal on the dialog when the widget is activated. The widget is
321 	 * appended to the end of the dialog’s action area. If you want to add a
322 	 * non-activatable widget, simply pack it into the @action_area field
323 	 * of the #GtkDialog struct.
324 	 *
325 	 * Params:
326 	 *     child = an activatable widget
327 	 *     responseId = response ID for @child
328 	 */
329 	public void addActionWidget(Widget child, int responseId)
330 	{
331 		gtk_dialog_add_action_widget(gtkDialog, (child is null) ? null : child.getWidgetStruct(), responseId);
332 	}
333 
334 	/**
335 	 * Adds a button with the given text and sets things up so that
336 	 * clicking the button will emit the #GtkDialog::response signal with
337 	 * the given @response_id. The button is appended to the end of the
338 	 * dialog’s action area. The button widget is returned, but usually
339 	 * you don’t need it.
340 	 *
341 	 * Params:
342 	 *     buttonText = text of button
343 	 *     responseId = response ID for the button
344 	 *
345 	 * Return: the #GtkButton widget that was added
346 	 */
347 	public Widget addButton(string buttonText, int responseId)
348 	{
349 		auto p = gtk_dialog_add_button(gtkDialog, Str.toStringz(buttonText), responseId);
350 		
351 		if(p is null)
352 		{
353 			return null;
354 		}
355 		
356 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
357 	}
358 
359 	/**
360 	 * Returns the header bar of @dialog. Note that the
361 	 * headerbar is only used by the dialog if the
362 	 * #GtkDialog:use-header-bar property is %TRUE.
363 	 *
364 	 * Return: the header bar
365 	 *
366 	 * Since: 3.12
367 	 */
368 	public Widget getHeaderBar()
369 	{
370 		auto p = gtk_dialog_get_header_bar(gtkDialog);
371 		
372 		if(p is null)
373 		{
374 			return null;
375 		}
376 		
377 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
378 	}
379 
380 	/**
381 	 * Gets the response id of a widget in the action area
382 	 * of a dialog.
383 	 *
384 	 * Params:
385 	 *     widget = a widget in the action area of @dialog
386 	 *
387 	 * Return: the response id of @widget, or %GTK_RESPONSE_NONE
388 	 *     if @widget doesn’t have a response id set.
389 	 *
390 	 * Since: 2.8
391 	 */
392 	public int getResponseForWidget(Widget widget)
393 	{
394 		return gtk_dialog_get_response_for_widget(gtkDialog, (widget is null) ? null : widget.getWidgetStruct());
395 	}
396 
397 	/**
398 	 * Gets the widget button that uses the given response ID in the action area
399 	 * of a dialog.
400 	 *
401 	 * Params:
402 	 *     responseId = the response ID used by the @dialog widget
403 	 *
404 	 * Return: the @widget button that uses the given
405 	 *     @response_id, or %NULL.
406 	 *
407 	 * Since: 2.20
408 	 */
409 	public Widget getWidgetForResponse(int responseId)
410 	{
411 		auto p = gtk_dialog_get_widget_for_response(gtkDialog, responseId);
412 		
413 		if(p is null)
414 		{
415 			return null;
416 		}
417 		
418 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
419 	}
420 
421 	/**
422 	 * Emits the #GtkDialog::response signal with the given response ID.
423 	 * Used to indicate that the user has responded to the dialog in some way;
424 	 * typically either you or gtk_dialog_run() will be monitoring the
425 	 * ::response signal and take appropriate action.
426 	 *
427 	 * Params:
428 	 *     responseId = response ID
429 	 */
430 	public void response(int responseId)
431 	{
432 		gtk_dialog_response(gtkDialog, responseId);
433 	}
434 
435 	/**
436 	 * Blocks in a recursive main loop until the @dialog either emits the
437 	 * #GtkDialog::response signal, or is destroyed. If the dialog is
438 	 * destroyed during the call to gtk_dialog_run(), gtk_dialog_run() returns
439 	 * #GTK_RESPONSE_NONE. Otherwise, it returns the response ID from the
440 	 * ::response signal emission.
441 	 *
442 	 * Before entering the recursive main loop, gtk_dialog_run() calls
443 	 * gtk_widget_show() on the dialog for you. Note that you still
444 	 * need to show any children of the dialog yourself.
445 	 *
446 	 * During gtk_dialog_run(), the default behavior of #GtkWidget::delete-event
447 	 * is disabled; if the dialog receives ::delete_event, it will not be
448 	 * destroyed as windows usually are, and gtk_dialog_run() will return
449 	 * #GTK_RESPONSE_DELETE_EVENT. Also, during gtk_dialog_run() the dialog
450 	 * will be modal. You can force gtk_dialog_run() to return at any time by
451 	 * calling gtk_dialog_response() to emit the ::response signal. Destroying
452 	 * the dialog during gtk_dialog_run() is a very bad idea, because your
453 	 * post-run code won’t know whether the dialog was destroyed or not.
454 	 *
455 	 * After gtk_dialog_run() returns, you are responsible for hiding or
456 	 * destroying the dialog if you wish to do so.
457 	 *
458 	 * Typical usage of this function might be:
459 	 * |[<!-- language="C" -->
460 	 * gint result = gtk_dialog_run (GTK_DIALOG (dialog));
461 	 * switch (result)
462 	 * {
463 	 * case GTK_RESPONSE_ACCEPT:
464 	 * do_application_specific_something ();
465 	 * break;
466 	 * default:
467 	 * do_nothing_since_dialog_was_cancelled ();
468 	 * break;
469 	 * }
470 	 * gtk_widget_destroy (dialog);
471 	 * ]|
472 	 *
473 	 * Note that even though the recursive main loop gives the effect of a
474 	 * modal dialog (it prevents the user from interacting with other
475 	 * windows in the same window group while the dialog is run), callbacks
476 	 * such as timeouts, IO channel watches, DND drops, etc, will
477 	 * be triggered during a gtk_dialog_run() call.
478 	 *
479 	 * Return: response ID
480 	 */
481 	public int run()
482 	{
483 		return gtk_dialog_run(gtkDialog);
484 	}
485 
486 	/**
487 	 * Sets an alternative button order. If the
488 	 * #GtkSettings:gtk-alternative-button-order setting is set to %TRUE,
489 	 * the dialog buttons are reordered according to the order of the
490 	 * response ids in @new_order.
491 	 *
492 	 * See gtk_dialog_set_alternative_button_order() for more information.
493 	 *
494 	 * This function is for use by language bindings.
495 	 *
496 	 * Deprecated: Deprecated
497 	 *
498 	 * Params:
499 	 *     nParams = the number of response ids in @new_order
500 	 *     newOrder = an array of response ids of
501 	 *         @dialog’s buttons
502 	 *
503 	 * Since: 2.6
504 	 */
505 	public void setAlternativeButtonOrder(int[] newOrder)
506 	{
507 		gtk_dialog_set_alternative_button_order_from_array(gtkDialog, cast(int)newOrder.length, newOrder.ptr);
508 	}
509 
510 	/**
511 	 * Sets the last widget in the dialog’s action area with the given @response_id
512 	 * as the default widget for the dialog. Pressing “Enter” normally activates
513 	 * the default widget.
514 	 *
515 	 * Params:
516 	 *     responseId = a response ID
517 	 */
518 	public void setDefaultResponse(int responseId)
519 	{
520 		gtk_dialog_set_default_response(gtkDialog, responseId);
521 	}
522 
523 	/**
524 	 * Calls `gtk_widget_set_sensitive (widget, @setting)`
525 	 * for each widget in the dialog’s action area with the given @response_id.
526 	 * A convenient way to sensitize/desensitize dialog buttons.
527 	 *
528 	 * Params:
529 	 *     responseId = a response ID
530 	 *     setting = %TRUE for sensitive
531 	 */
532 	public void setResponseSensitive(int responseId, bool setting)
533 	{
534 		gtk_dialog_set_response_sensitive(gtkDialog, responseId, setting);
535 	}
536 
537 	int[string] connectedSignals;
538 
539 	void delegate(Dialog)[] onCloseListeners;
540 	/**
541 	 * The ::close signal is a
542 	 * [keybinding signal][GtkBindingSignal]
543 	 * which gets emitted when the user uses a keybinding to close
544 	 * the dialog.
545 	 *
546 	 * The default binding for this signal is the Escape key.
547 	 */
548 	void addOnClose(void delegate(Dialog) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
549 	{
550 		if ( "close" !in connectedSignals )
551 		{
552 			Signals.connectData(
553 				this,
554 				"close",
555 				cast(GCallback)&callBackClose,
556 				cast(void*)this,
557 				null,
558 				connectFlags);
559 			connectedSignals["close"] = 1;
560 		}
561 		onCloseListeners ~= dlg;
562 	}
563 	extern(C) static void callBackClose(GtkDialog* dialogStruct, Dialog _dialog)
564 	{
565 		foreach ( void delegate(Dialog) dlg; _dialog.onCloseListeners )
566 		{
567 			dlg(_dialog);
568 		}
569 	}
570 
571 	void delegate(int, Dialog)[] onResponseListeners;
572 	/**
573 	 * Emitted when an action widget is clicked, the dialog receives a
574 	 * delete event, or the application programmer calls gtk_dialog_response().
575 	 * On a delete event, the response ID is #GTK_RESPONSE_DELETE_EVENT.
576 	 * Otherwise, it depends on which action widget was clicked.
577 	 *
578 	 * Params:
579 	 *     responseId = the response ID
580 	 */
581 	void addOnResponse(void delegate(int, Dialog) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
582 	{
583 		if ( "response" !in connectedSignals )
584 		{
585 			Signals.connectData(
586 				this,
587 				"response",
588 				cast(GCallback)&callBackResponse,
589 				cast(void*)this,
590 				null,
591 				connectFlags);
592 			connectedSignals["response"] = 1;
593 		}
594 		onResponseListeners ~= dlg;
595 	}
596 	extern(C) static void callBackResponse(GtkDialog* dialogStruct, int responseId, Dialog _dialog)
597 	{
598 		foreach ( void delegate(int, Dialog) dlg; _dialog.onResponseListeners )
599 		{
600 			dlg(responseId, _dialog);
601 		}
602 	}
603 
604 	/**
605 	 * Returns %TRUE if dialogs are expected to use an alternative
606 	 * button order on the screen @screen. See
607 	 * gtk_dialog_set_alternative_button_order() for more details
608 	 * about alternative button order.
609 	 *
610 	 * If you need to use this function, you should probably connect
611 	 * to the ::notify:gtk-alternative-button-order signal on the
612 	 * #GtkSettings object associated to @screen, in order to be
613 	 * notified if the button order setting changes.
614 	 *
615 	 * Deprecated: Deprecated
616 	 *
617 	 * Params:
618 	 *     screen = a #GdkScreen, or %NULL to use the default screen
619 	 *
620 	 * Return: Whether the alternative button order should be used
621 	 *
622 	 * Since: 2.6
623 	 */
624 	public static bool alternativeDialogButtonOrder(Screen screen)
625 	{
626 		return gtk_alternative_dialog_button_order((screen is null) ? null : screen.getScreenStruct()) != 0;
627 	}
628 }