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.Expander;
26 
27 private import glib.ConstructionException;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gtk.Bin;
32 private import gtk.Widget;
33 public  import gtkc.gdktypes;
34 private import gtkc.gtk;
35 public  import gtkc.gtktypes;
36 private import std.algorithm;
37 
38 
39 /**
40  * A #GtkExpander allows the user to hide or show its child by clicking
41  * on an expander triangle similar to the triangles used in a #GtkTreeView.
42  * 
43  * Normally you use an expander as you would use any other descendant
44  * of #GtkBin; you create the child widget and use gtk_container_add()
45  * to add it to the expander. When the expander is toggled, it will take
46  * care of showing and hiding the child automatically.
47  * 
48  * # Special Usage
49  * 
50  * There are situations in which you may prefer to show and hide the
51  * expanded widget yourself, such as when you want to actually create
52  * the widget at expansion time. In this case, create a #GtkExpander
53  * but do not add a child to it. The expander widget has an
54  * #GtkExpander:expanded property which can be used to monitor
55  * its expansion state. You should watch this property with a signal
56  * connection as follows:
57  * 
58  * |[<!-- language="C" -->
59  * expander = gtk_expander_new_with_mnemonic ("_More Options");
60  * g_signal_connect (expander, "notify::expanded",
61  * G_CALLBACK (expander_callback), NULL);
62  * 
63  * ...
64  * 
65  * static void
66  * expander_callback (GObject    *object,
67  * GParamSpec *param_spec,
68  * gpointer    user_data)
69  * {
70  * GtkExpander *expander;
71  * 
72  * expander = GTK_EXPANDER (object);
73  * 
74  * if (gtk_expander_get_expanded (expander))
75  * {
76  * // Show or create widgets
77  * }
78  * else
79  * {
80  * // Hide or destroy widgets
81  * }
82  * }
83  * ]|
84  * 
85  * # GtkExpander as GtkBuildable
86  * 
87  * The GtkExpander implementation of the GtkBuildable interface supports
88  * placing a child in the label position by specifying “label” as the
89  * “type” attribute of a <child> element. A normal content child can be
90  * specified without specifying a <child> type attribute.
91  * 
92  * An example of a UI definition fragment with GtkExpander:
93  * |[
94  * <object class="GtkExpander">
95  * <child type="label">
96  * <object class="GtkLabel" id="expander-label"/>
97  * </child>
98  * <child>
99  * <object class="GtkEntry" id="expander-content"/>
100  * </child>
101  * </object>
102  * ]|
103  * 
104  * # CSS nodes
105  * 
106  * |[<!-- language="plain" -->
107  * expander
108  * ├── title
109  * │   ├── arrow
110  * │   ╰── <label widget>
111  * ╰── <child>
112  * ]|
113  * 
114  * GtkExpander has three CSS nodes, the main node with the name expander,
115  * a subnode with name title and node below it with name arrow. Neither of
116  * them is using any style classes.
117  */
118 public class Expander : Bin
119 {
120 	/** the main Gtk struct */
121 	protected GtkExpander* gtkExpander;
122 
123 	/** Get the main Gtk struct */
124 	public GtkExpander* getExpanderStruct()
125 	{
126 		return gtkExpander;
127 	}
128 
129 	/** the main Gtk struct as a void* */
130 	protected override void* getStruct()
131 	{
132 		return cast(void*)gtkExpander;
133 	}
134 
135 	protected override void setStruct(GObject* obj)
136 	{
137 		gtkExpander = cast(GtkExpander*)obj;
138 		super.setStruct(obj);
139 	}
140 
141 	/**
142 	 * Sets our main struct and passes it to the parent class.
143 	 */
144 	public this (GtkExpander* gtkExpander, bool ownedRef = false)
145 	{
146 		this.gtkExpander = gtkExpander;
147 		super(cast(GtkBin*)gtkExpander, ownedRef);
148 	}
149 
150 	/**
151 	 * Creates a new expander using label as the text of the label.
152 	 * Since 2.4
153 	 * Params:
154 	 *  label = the text of the label
155 	 *  mnemonic = if true characters in label that are preceded by an underscore,
156 	 *  are underlined.
157 	 *  If you need a literal underscore character in a label, use '__' (two
158 	 *  underscores). The first underlined character represents a keyboard
159 	 *  accelerator called a mnemonic.
160 	 * Throws: ConstructionException GTK+ fails to create the object.
161 	 */
162 	public this (string label, bool mnemonic=true)
163 	{
164 		GtkExpander* p;
165 		
166 		if ( mnemonic )
167 		{
168 			p = cast(GtkExpander*)gtk_expander_new_with_mnemonic(Str.toStringz(label));
169 		}
170 		else
171 		{
172 			p = cast(GtkExpander*)gtk_expander_new(Str.toStringz(label));
173 		}
174 		
175 		if(p is null)
176 		{
177 			throw new ConstructionException("null returned by gtk_expander_new");
178 		}
179 		
180 		this(p);
181 	}
182 
183 	/**
184 	 */
185 
186 	/** */
187 	public static GType getType()
188 	{
189 		return gtk_expander_get_type();
190 	}
191 
192 	/**
193 	 * Queries a #GtkExpander and returns its current state. Returns %TRUE
194 	 * if the child widget is revealed.
195 	 *
196 	 * See gtk_expander_set_expanded().
197 	 *
198 	 * Return: the current state of the expander
199 	 *
200 	 * Since: 2.4
201 	 */
202 	public bool getExpanded()
203 	{
204 		return gtk_expander_get_expanded(gtkExpander) != 0;
205 	}
206 
207 	/**
208 	 * Fetches the text from a label widget including any embedded
209 	 * underlines indicating mnemonics and Pango markup, as set by
210 	 * gtk_expander_set_label(). If the label text has not been set the
211 	 * return value will be %NULL. This will be the case if you create an
212 	 * empty button with gtk_button_new() to use as a container.
213 	 *
214 	 * Note that this function behaved differently in versions prior to
215 	 * 2.14 and used to return the label text stripped of embedded
216 	 * underlines indicating mnemonics and Pango markup. This problem can
217 	 * be avoided by fetching the label text directly from the label
218 	 * widget.
219 	 *
220 	 * Return: The text of the label widget. This string is owned
221 	 *     by the widget and must not be modified or freed.
222 	 *
223 	 * Since: 2.4
224 	 */
225 	public string getLabel()
226 	{
227 		return Str.toString(gtk_expander_get_label(gtkExpander));
228 	}
229 
230 	/**
231 	 * Returns whether the label widget will fill all available
232 	 * horizontal space allocated to @expander.
233 	 *
234 	 * Return: %TRUE if the label widget will fill all
235 	 *     available horizontal space
236 	 *
237 	 * Since: 2.22
238 	 */
239 	public bool getLabelFill()
240 	{
241 		return gtk_expander_get_label_fill(gtkExpander) != 0;
242 	}
243 
244 	/**
245 	 * Retrieves the label widget for the frame. See
246 	 * gtk_expander_set_label_widget().
247 	 *
248 	 * Return: the label widget,
249 	 *     or %NULL if there is none
250 	 *
251 	 * Since: 2.4
252 	 */
253 	public Widget getLabelWidget()
254 	{
255 		auto p = gtk_expander_get_label_widget(gtkExpander);
256 		
257 		if(p is null)
258 		{
259 			return null;
260 		}
261 		
262 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
263 	}
264 
265 	/**
266 	 * Returns whether the expander will resize the toplevel widget
267 	 * containing the expander upon resizing and collpasing.
268 	 *
269 	 * Return: the “resize toplevel” setting.
270 	 *
271 	 * Since: 3.2
272 	 */
273 	public bool getResizeToplevel()
274 	{
275 		return gtk_expander_get_resize_toplevel(gtkExpander) != 0;
276 	}
277 
278 	/**
279 	 * Gets the value set by gtk_expander_set_spacing().
280 	 *
281 	 * Deprecated: Use margins on the child instead.
282 	 *
283 	 * Return: spacing between the expander and child
284 	 *
285 	 * Since: 2.4
286 	 */
287 	public int getSpacing()
288 	{
289 		return gtk_expander_get_spacing(gtkExpander);
290 	}
291 
292 	/**
293 	 * Returns whether the label’s text is interpreted as marked up with
294 	 * the [Pango text markup language][PangoMarkupFormat].
295 	 * See gtk_expander_set_use_markup().
296 	 *
297 	 * Return: %TRUE if the label’s text will be parsed for markup
298 	 *
299 	 * Since: 2.4
300 	 */
301 	public bool getUseMarkup()
302 	{
303 		return gtk_expander_get_use_markup(gtkExpander) != 0;
304 	}
305 
306 	/**
307 	 * Returns whether an embedded underline in the expander label
308 	 * indicates a mnemonic. See gtk_expander_set_use_underline().
309 	 *
310 	 * Return: %TRUE if an embedded underline in the expander
311 	 *     label indicates the mnemonic accelerator keys
312 	 *
313 	 * Since: 2.4
314 	 */
315 	public bool getUseUnderline()
316 	{
317 		return gtk_expander_get_use_underline(gtkExpander) != 0;
318 	}
319 
320 	/**
321 	 * Sets the state of the expander. Set to %TRUE, if you want
322 	 * the child widget to be revealed, and %FALSE if you want the
323 	 * child widget to be hidden.
324 	 *
325 	 * Params:
326 	 *     expanded = whether the child widget is revealed
327 	 *
328 	 * Since: 2.4
329 	 */
330 	public void setExpanded(bool expanded)
331 	{
332 		gtk_expander_set_expanded(gtkExpander, expanded);
333 	}
334 
335 	/**
336 	 * Sets the text of the label of the expander to @label.
337 	 *
338 	 * This will also clear any previously set labels.
339 	 *
340 	 * Params:
341 	 *     label = a string
342 	 *
343 	 * Since: 2.4
344 	 */
345 	public void setLabel(string label)
346 	{
347 		gtk_expander_set_label(gtkExpander, Str.toStringz(label));
348 	}
349 
350 	/**
351 	 * Sets whether the label widget should fill all available
352 	 * horizontal space allocated to @expander.
353 	 *
354 	 * Params:
355 	 *     labelFill = %TRUE if the label should should fill
356 	 *         all available horizontal space
357 	 *
358 	 * Since: 2.22
359 	 */
360 	public void setLabelFill(bool labelFill)
361 	{
362 		gtk_expander_set_label_fill(gtkExpander, labelFill);
363 	}
364 
365 	/**
366 	 * Set the label widget for the expander. This is the widget
367 	 * that will appear embedded alongside the expander arrow.
368 	 *
369 	 * Params:
370 	 *     labelWidget = the new label widget
371 	 *
372 	 * Since: 2.4
373 	 */
374 	public void setLabelWidget(Widget labelWidget)
375 	{
376 		gtk_expander_set_label_widget(gtkExpander, (labelWidget is null) ? null : labelWidget.getWidgetStruct());
377 	}
378 
379 	/**
380 	 * Sets whether the expander will resize the toplevel widget
381 	 * containing the expander upon resizing and collpasing.
382 	 *
383 	 * Params:
384 	 *     resizeToplevel = whether to resize the toplevel
385 	 *
386 	 * Since: 3.2
387 	 */
388 	public void setResizeToplevel(bool resizeToplevel)
389 	{
390 		gtk_expander_set_resize_toplevel(gtkExpander, resizeToplevel);
391 	}
392 
393 	/**
394 	 * Sets the spacing field of @expander, which is the number of
395 	 * pixels to place between expander and the child.
396 	 *
397 	 * Deprecated: Use margins on the child instead.
398 	 *
399 	 * Params:
400 	 *     spacing = distance between the expander and child in pixels
401 	 *
402 	 * Since: 2.4
403 	 */
404 	public void setSpacing(int spacing)
405 	{
406 		gtk_expander_set_spacing(gtkExpander, spacing);
407 	}
408 
409 	/**
410 	 * Sets whether the text of the label contains markup in
411 	 * [Pango’s text markup language][PangoMarkupFormat].
412 	 * See gtk_label_set_markup().
413 	 *
414 	 * Params:
415 	 *     useMarkup = %TRUE if the label’s text should be parsed for markup
416 	 *
417 	 * Since: 2.4
418 	 */
419 	public void setUseMarkup(bool useMarkup)
420 	{
421 		gtk_expander_set_use_markup(gtkExpander, useMarkup);
422 	}
423 
424 	/**
425 	 * If true, an underline in the text of the expander label indicates
426 	 * the next character should be used for the mnemonic accelerator key.
427 	 *
428 	 * Params:
429 	 *     useUnderline = %TRUE if underlines in the text indicate mnemonics
430 	 *
431 	 * Since: 2.4
432 	 */
433 	public void setUseUnderline(bool useUnderline)
434 	{
435 		gtk_expander_set_use_underline(gtkExpander, useUnderline);
436 	}
437 
438 	protected class OnActivateDelegateWrapper
439 	{
440 		void delegate(Expander) dlg;
441 		gulong handlerId;
442 		ConnectFlags flags;
443 		this(void delegate(Expander) dlg, gulong handlerId, ConnectFlags flags)
444 		{
445 			this.dlg = dlg;
446 			this.handlerId = handlerId;
447 			this.flags = flags;
448 		}
449 	}
450 	protected OnActivateDelegateWrapper[] onActivateListeners;
451 
452 	/** */
453 	gulong addOnActivate(void delegate(Expander) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
454 	{
455 		onActivateListeners ~= new OnActivateDelegateWrapper(dlg, 0, connectFlags);
456 		onActivateListeners[onActivateListeners.length - 1].handlerId = Signals.connectData(
457 			this,
458 			"activate",
459 			cast(GCallback)&callBackActivate,
460 			cast(void*)onActivateListeners[onActivateListeners.length - 1],
461 			cast(GClosureNotify)&callBackActivateDestroy,
462 			connectFlags);
463 		return onActivateListeners[onActivateListeners.length - 1].handlerId;
464 	}
465 	
466 	extern(C) static void callBackActivate(GtkExpander* expanderStruct,OnActivateDelegateWrapper wrapper)
467 	{
468 		wrapper.dlg(wrapper.outer);
469 	}
470 	
471 	extern(C) static void callBackActivateDestroy(OnActivateDelegateWrapper wrapper, GClosure* closure)
472 	{
473 		wrapper.outer.internalRemoveOnActivate(wrapper);
474 	}
475 
476 	protected void internalRemoveOnActivate(OnActivateDelegateWrapper source)
477 	{
478 		foreach(index, wrapper; onActivateListeners)
479 		{
480 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
481 			{
482 				onActivateListeners[index] = null;
483 				onActivateListeners = std.algorithm.remove(onActivateListeners, index);
484 				break;
485 			}
486 		}
487 	}
488 	
489 }