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.Range;
26 
27 private import gobject.ObjectG;
28 private import gobject.Signals;
29 private import gtk.Adjustment;
30 private import gtk.OrientableIF;
31 private import gtk.OrientableT;
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  * #GtkRange is the common base class for widgets which visualize an
41  * adjustment, e.g #GtkScale or #GtkScrollbar.
42  * 
43  * Apart from signals for monitoring the parameters of the adjustment,
44  * #GtkRange provides properties and methods for influencing the sensitivity
45  * of the “steppers”. It also provides properties and methods for setting a
46  * “fill level” on range widgets. See gtk_range_set_fill_level().
47  */
48 public class Range : Widget, OrientableIF
49 {
50 	/** the main Gtk struct */
51 	protected GtkRange* gtkRange;
52 
53 	/** Get the main Gtk struct */
54 	public GtkRange* getRangeStruct()
55 	{
56 		return gtkRange;
57 	}
58 
59 	/** the main Gtk struct as a void* */
60 	protected override void* getStruct()
61 	{
62 		return cast(void*)gtkRange;
63 	}
64 
65 	protected override void setStruct(GObject* obj)
66 	{
67 		gtkRange = cast(GtkRange*)obj;
68 		super.setStruct(obj);
69 	}
70 
71 	/**
72 	 * Sets our main struct and passes it to the parent class.
73 	 */
74 	public this (GtkRange* gtkRange, bool ownedRef = false)
75 	{
76 		this.gtkRange = gtkRange;
77 		super(cast(GtkWidget*)gtkRange, ownedRef);
78 	}
79 
80 	// add the Orientable capabilities
81 	mixin OrientableT!(GtkRange);
82 
83 
84 	/** */
85 	public static GType getType()
86 	{
87 		return gtk_range_get_type();
88 	}
89 
90 	/**
91 	 * Get the #GtkAdjustment which is the “model” object for #GtkRange.
92 	 * See gtk_range_set_adjustment() for details.
93 	 * The return value does not have a reference added, so should not
94 	 * be unreferenced.
95 	 *
96 	 * Return: a #GtkAdjustment
97 	 */
98 	public Adjustment getAdjustment()
99 	{
100 		auto p = gtk_range_get_adjustment(gtkRange);
101 		
102 		if(p is null)
103 		{
104 			return null;
105 		}
106 		
107 		return ObjectG.getDObject!(Adjustment)(cast(GtkAdjustment*) p);
108 	}
109 
110 	/**
111 	 * Gets the current position of the fill level indicator.
112 	 *
113 	 * Return: The current fill level
114 	 *
115 	 * Since: 2.12
116 	 */
117 	public double getFillLevel()
118 	{
119 		return gtk_range_get_fill_level(gtkRange);
120 	}
121 
122 	/**
123 	 * Gets the value set by gtk_range_set_flippable().
124 	 *
125 	 * Return: %TRUE if the range is flippable
126 	 *
127 	 * Since: 2.18
128 	 */
129 	public bool getFlippable()
130 	{
131 		return gtk_range_get_flippable(gtkRange) != 0;
132 	}
133 
134 	/**
135 	 * Gets the value set by gtk_range_set_inverted().
136 	 *
137 	 * Return: %TRUE if the range is inverted
138 	 */
139 	public bool getInverted()
140 	{
141 		return gtk_range_get_inverted(gtkRange) != 0;
142 	}
143 
144 	/**
145 	 * Gets the sensitivity policy for the stepper that points to the
146 	 * 'lower' end of the GtkRange’s adjustment.
147 	 *
148 	 * Return: The lower stepper’s sensitivity policy.
149 	 *
150 	 * Since: 2.10
151 	 */
152 	public GtkSensitivityType getLowerStepperSensitivity()
153 	{
154 		return gtk_range_get_lower_stepper_sensitivity(gtkRange);
155 	}
156 
157 	/**
158 	 * This function is useful mainly for #GtkRange subclasses.
159 	 *
160 	 * See gtk_range_set_min_slider_size().
161 	 *
162 	 * Deprecated: Use the min-height/min-width CSS properties on the slider
163 	 * node.
164 	 *
165 	 * Return: The minimum size of the range’s slider.
166 	 *
167 	 * Since: 2.20
168 	 */
169 	public int getMinSliderSize()
170 	{
171 		return gtk_range_get_min_slider_size(gtkRange);
172 	}
173 
174 	/**
175 	 * This function returns the area that contains the range’s trough
176 	 * and its steppers, in widget->window coordinates.
177 	 *
178 	 * This function is useful mainly for #GtkRange subclasses.
179 	 *
180 	 * Params:
181 	 *     rangeRect = return location for the range rectangle
182 	 *
183 	 * Since: 2.20
184 	 */
185 	public void getRangeRect(out GdkRectangle rangeRect)
186 	{
187 		gtk_range_get_range_rect(gtkRange, &rangeRect);
188 	}
189 
190 	/**
191 	 * Gets whether the range is restricted to the fill level.
192 	 *
193 	 * Return: %TRUE if @range is restricted to the fill level.
194 	 *
195 	 * Since: 2.12
196 	 */
197 	public bool getRestrictToFillLevel()
198 	{
199 		return gtk_range_get_restrict_to_fill_level(gtkRange) != 0;
200 	}
201 
202 	/**
203 	 * Gets the number of digits to round the value to when
204 	 * it changes. See #GtkRange::change-value.
205 	 *
206 	 * Return: the number of digits to round to
207 	 *
208 	 * Since: 2.24
209 	 */
210 	public int getRoundDigits()
211 	{
212 		return gtk_range_get_round_digits(gtkRange);
213 	}
214 
215 	/**
216 	 * Gets whether the range displays the fill level graphically.
217 	 *
218 	 * Return: %TRUE if @range shows the fill level.
219 	 *
220 	 * Since: 2.12
221 	 */
222 	public bool getShowFillLevel()
223 	{
224 		return gtk_range_get_show_fill_level(gtkRange) != 0;
225 	}
226 
227 	/**
228 	 * This function returns sliders range along the long dimension,
229 	 * in widget->window coordinates.
230 	 *
231 	 * This function is useful mainly for #GtkRange subclasses.
232 	 *
233 	 * Params:
234 	 *     sliderStart = return location for the slider's
235 	 *         start, or %NULL
236 	 *     sliderEnd = return location for the slider's
237 	 *         end, or %NULL
238 	 *
239 	 * Since: 2.20
240 	 */
241 	public void getSliderRange(out int sliderStart, out int sliderEnd)
242 	{
243 		gtk_range_get_slider_range(gtkRange, &sliderStart, &sliderEnd);
244 	}
245 
246 	/**
247 	 * This function is useful mainly for #GtkRange subclasses.
248 	 *
249 	 * See gtk_range_set_slider_size_fixed().
250 	 *
251 	 * Return: whether the range’s slider has a fixed size.
252 	 *
253 	 * Since: 2.20
254 	 */
255 	public bool getSliderSizeFixed()
256 	{
257 		return gtk_range_get_slider_size_fixed(gtkRange) != 0;
258 	}
259 
260 	/**
261 	 * Gets the sensitivity policy for the stepper that points to the
262 	 * 'upper' end of the GtkRange’s adjustment.
263 	 *
264 	 * Return: The upper stepper’s sensitivity policy.
265 	 *
266 	 * Since: 2.10
267 	 */
268 	public GtkSensitivityType getUpperStepperSensitivity()
269 	{
270 		return gtk_range_get_upper_stepper_sensitivity(gtkRange);
271 	}
272 
273 	/**
274 	 * Gets the current value of the range.
275 	 *
276 	 * Return: current value of the range.
277 	 */
278 	public double getValue()
279 	{
280 		return gtk_range_get_value(gtkRange);
281 	}
282 
283 	/**
284 	 * Sets the adjustment to be used as the “model” object for this range
285 	 * widget. The adjustment indicates the current range value, the
286 	 * minimum and maximum range values, the step/page increments used
287 	 * for keybindings and scrolling, and the page size. The page size
288 	 * is normally 0 for #GtkScale and nonzero for #GtkScrollbar, and
289 	 * indicates the size of the visible area of the widget being scrolled.
290 	 * The page size affects the size of the scrollbar slider.
291 	 *
292 	 * Params:
293 	 *     adjustment = a #GtkAdjustment
294 	 */
295 	public void setAdjustment(Adjustment adjustment)
296 	{
297 		gtk_range_set_adjustment(gtkRange, (adjustment is null) ? null : adjustment.getAdjustmentStruct());
298 	}
299 
300 	/**
301 	 * Set the new position of the fill level indicator.
302 	 *
303 	 * The “fill level” is probably best described by its most prominent
304 	 * use case, which is an indicator for the amount of pre-buffering in
305 	 * a streaming media player. In that use case, the value of the range
306 	 * would indicate the current play position, and the fill level would
307 	 * be the position up to which the file/stream has been downloaded.
308 	 *
309 	 * This amount of prebuffering can be displayed on the range’s trough
310 	 * and is themeable separately from the trough. To enable fill level
311 	 * display, use gtk_range_set_show_fill_level(). The range defaults
312 	 * to not showing the fill level.
313 	 *
314 	 * Additionally, it’s possible to restrict the range’s slider position
315 	 * to values which are smaller than the fill level. This is controller
316 	 * by gtk_range_set_restrict_to_fill_level() and is by default
317 	 * enabled.
318 	 *
319 	 * Params:
320 	 *     fillLevel = the new position of the fill level indicator
321 	 *
322 	 * Since: 2.12
323 	 */
324 	public void setFillLevel(double fillLevel)
325 	{
326 		gtk_range_set_fill_level(gtkRange, fillLevel);
327 	}
328 
329 	/**
330 	 * If a range is flippable, it will switch its direction if it is
331 	 * horizontal and its direction is %GTK_TEXT_DIR_RTL.
332 	 *
333 	 * See gtk_widget_get_direction().
334 	 *
335 	 * Params:
336 	 *     flippable = %TRUE to make the range flippable
337 	 *
338 	 * Since: 2.18
339 	 */
340 	public void setFlippable(bool flippable)
341 	{
342 		gtk_range_set_flippable(gtkRange, flippable);
343 	}
344 
345 	/**
346 	 * Sets the step and page sizes for the range.
347 	 * The step size is used when the user clicks the #GtkScrollbar
348 	 * arrows or moves #GtkScale via arrow keys. The page size
349 	 * is used for example when moving via Page Up or Page Down keys.
350 	 *
351 	 * Params:
352 	 *     step = step size
353 	 *     page = page size
354 	 */
355 	public void setIncrements(double step, double page)
356 	{
357 		gtk_range_set_increments(gtkRange, step, page);
358 	}
359 
360 	/**
361 	 * Ranges normally move from lower to higher values as the
362 	 * slider moves from top to bottom or left to right. Inverted
363 	 * ranges have higher values at the top or on the right rather than
364 	 * on the bottom or left.
365 	 *
366 	 * Params:
367 	 *     setting = %TRUE to invert the range
368 	 */
369 	public void setInverted(bool setting)
370 	{
371 		gtk_range_set_inverted(gtkRange, setting);
372 	}
373 
374 	/**
375 	 * Sets the sensitivity policy for the stepper that points to the
376 	 * 'lower' end of the GtkRange’s adjustment.
377 	 *
378 	 * Params:
379 	 *     sensitivity = the lower stepper’s sensitivity policy.
380 	 *
381 	 * Since: 2.10
382 	 */
383 	public void setLowerStepperSensitivity(GtkSensitivityType sensitivity)
384 	{
385 		gtk_range_set_lower_stepper_sensitivity(gtkRange, sensitivity);
386 	}
387 
388 	/**
389 	 * Sets the minimum size of the range’s slider.
390 	 *
391 	 * This function is useful mainly for #GtkRange subclasses.
392 	 *
393 	 * Deprecated: Use the min-height/min-width CSS properties on the slider
394 	 * node.
395 	 *
396 	 * Params:
397 	 *     minSize = The slider’s minimum size
398 	 *
399 	 * Since: 2.20
400 	 */
401 	public void setMinSliderSize(int minSize)
402 	{
403 		gtk_range_set_min_slider_size(gtkRange, minSize);
404 	}
405 
406 	/**
407 	 * Sets the allowable values in the #GtkRange, and clamps the range
408 	 * value to be between @min and @max. (If the range has a non-zero
409 	 * page size, it is clamped between @min and @max - page-size.)
410 	 *
411 	 * Params:
412 	 *     min = minimum range value
413 	 *     max = maximum range value
414 	 */
415 	public void setRange(double min, double max)
416 	{
417 		gtk_range_set_range(gtkRange, min, max);
418 	}
419 
420 	/**
421 	 * Sets whether the slider is restricted to the fill level. See
422 	 * gtk_range_set_fill_level() for a general description of the fill
423 	 * level concept.
424 	 *
425 	 * Params:
426 	 *     restrictToFillLevel = Whether the fill level restricts slider movement.
427 	 *
428 	 * Since: 2.12
429 	 */
430 	public void setRestrictToFillLevel(bool restrictToFillLevel)
431 	{
432 		gtk_range_set_restrict_to_fill_level(gtkRange, restrictToFillLevel);
433 	}
434 
435 	/**
436 	 * Sets the number of digits to round the value to when
437 	 * it changes. See #GtkRange::change-value.
438 	 *
439 	 * Params:
440 	 *     roundDigits = the precision in digits, or -1
441 	 *
442 	 * Since: 2.24
443 	 */
444 	public void setRoundDigits(int roundDigits)
445 	{
446 		gtk_range_set_round_digits(gtkRange, roundDigits);
447 	}
448 
449 	/**
450 	 * Sets whether a graphical fill level is show on the trough. See
451 	 * gtk_range_set_fill_level() for a general description of the fill
452 	 * level concept.
453 	 *
454 	 * Params:
455 	 *     showFillLevel = Whether a fill level indicator graphics is shown.
456 	 *
457 	 * Since: 2.12
458 	 */
459 	public void setShowFillLevel(bool showFillLevel)
460 	{
461 		gtk_range_set_show_fill_level(gtkRange, showFillLevel);
462 	}
463 
464 	/**
465 	 * Sets whether the range’s slider has a fixed size, or a size that
466 	 * depends on its adjustment’s page size.
467 	 *
468 	 * This function is useful mainly for #GtkRange subclasses.
469 	 *
470 	 * Params:
471 	 *     sizeFixed = %TRUE to make the slider size constant
472 	 *
473 	 * Since: 2.20
474 	 */
475 	public void setSliderSizeFixed(bool sizeFixed)
476 	{
477 		gtk_range_set_slider_size_fixed(gtkRange, sizeFixed);
478 	}
479 
480 	/**
481 	 * Sets the sensitivity policy for the stepper that points to the
482 	 * 'upper' end of the GtkRange’s adjustment.
483 	 *
484 	 * Params:
485 	 *     sensitivity = the upper stepper’s sensitivity policy.
486 	 *
487 	 * Since: 2.10
488 	 */
489 	public void setUpperStepperSensitivity(GtkSensitivityType sensitivity)
490 	{
491 		gtk_range_set_upper_stepper_sensitivity(gtkRange, sensitivity);
492 	}
493 
494 	/**
495 	 * Sets the current value of the range; if the value is outside the
496 	 * minimum or maximum range values, it will be clamped to fit inside
497 	 * them. The range emits the #GtkRange::value-changed signal if the
498 	 * value changes.
499 	 *
500 	 * Params:
501 	 *     value = new value of the range
502 	 */
503 	public void setValue(double value)
504 	{
505 		gtk_range_set_value(gtkRange, value);
506 	}
507 
508 	protected class OnAdjustBoundsDelegateWrapper
509 	{
510 		void delegate(double, Range) dlg;
511 		gulong handlerId;
512 		ConnectFlags flags;
513 		this(void delegate(double, Range) dlg, gulong handlerId, ConnectFlags flags)
514 		{
515 			this.dlg = dlg;
516 			this.handlerId = handlerId;
517 			this.flags = flags;
518 		}
519 	}
520 	protected OnAdjustBoundsDelegateWrapper[] onAdjustBoundsListeners;
521 
522 	/**
523 	 * Emitted before clamping a value, to give the application a
524 	 * chance to adjust the bounds.
525 	 *
526 	 * Params:
527 	 *     value = the value before we clamp
528 	 */
529 	gulong addOnAdjustBounds(void delegate(double, Range) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
530 	{
531 		onAdjustBoundsListeners ~= new OnAdjustBoundsDelegateWrapper(dlg, 0, connectFlags);
532 		onAdjustBoundsListeners[onAdjustBoundsListeners.length - 1].handlerId = Signals.connectData(
533 			this,
534 			"adjust-bounds",
535 			cast(GCallback)&callBackAdjustBounds,
536 			cast(void*)onAdjustBoundsListeners[onAdjustBoundsListeners.length - 1],
537 			cast(GClosureNotify)&callBackAdjustBoundsDestroy,
538 			connectFlags);
539 		return onAdjustBoundsListeners[onAdjustBoundsListeners.length - 1].handlerId;
540 	}
541 	
542 	extern(C) static void callBackAdjustBounds(GtkRange* rangeStruct, double value,OnAdjustBoundsDelegateWrapper wrapper)
543 	{
544 		wrapper.dlg(value, wrapper.outer);
545 	}
546 	
547 	extern(C) static void callBackAdjustBoundsDestroy(OnAdjustBoundsDelegateWrapper wrapper, GClosure* closure)
548 	{
549 		wrapper.outer.internalRemoveOnAdjustBounds(wrapper);
550 	}
551 
552 	protected void internalRemoveOnAdjustBounds(OnAdjustBoundsDelegateWrapper source)
553 	{
554 		foreach(index, wrapper; onAdjustBoundsListeners)
555 		{
556 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
557 			{
558 				onAdjustBoundsListeners[index] = null;
559 				onAdjustBoundsListeners = std.algorithm.remove(onAdjustBoundsListeners, index);
560 				break;
561 			}
562 		}
563 	}
564 	
565 
566 	protected class OnChangeValueDelegateWrapper
567 	{
568 		bool delegate(GtkScrollType, double, Range) dlg;
569 		gulong handlerId;
570 		ConnectFlags flags;
571 		this(bool delegate(GtkScrollType, double, Range) dlg, gulong handlerId, ConnectFlags flags)
572 		{
573 			this.dlg = dlg;
574 			this.handlerId = handlerId;
575 			this.flags = flags;
576 		}
577 	}
578 	protected OnChangeValueDelegateWrapper[] onChangeValueListeners;
579 
580 	/**
581 	 * The #GtkRange::change-value signal is emitted when a scroll action is
582 	 * performed on a range.  It allows an application to determine the
583 	 * type of scroll event that occurred and the resultant new value.
584 	 * The application can handle the event itself and return %TRUE to
585 	 * prevent further processing.  Or, by returning %FALSE, it can pass
586 	 * the event to other handlers until the default GTK+ handler is
587 	 * reached.
588 	 *
589 	 * The value parameter is unrounded.  An application that overrides
590 	 * the GtkRange::change-value signal is responsible for clamping the
591 	 * value to the desired number of decimal digits; the default GTK+
592 	 * handler clamps the value based on #GtkRange:round-digits.
593 	 *
594 	 * It is not possible to use delayed update policies in an overridden
595 	 * #GtkRange::change-value handler.
596 	 *
597 	 * Params:
598 	 *     scroll = the type of scroll action that was performed
599 	 *     value = the new value resulting from the scroll action
600 	 *
601 	 * Return: %TRUE to prevent other handlers from being invoked for
602 	 *     the signal, %FALSE to propagate the signal further
603 	 *
604 	 * Since: 2.6
605 	 */
606 	gulong addOnChangeValue(bool delegate(GtkScrollType, double, Range) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
607 	{
608 		onChangeValueListeners ~= new OnChangeValueDelegateWrapper(dlg, 0, connectFlags);
609 		onChangeValueListeners[onChangeValueListeners.length - 1].handlerId = Signals.connectData(
610 			this,
611 			"change-value",
612 			cast(GCallback)&callBackChangeValue,
613 			cast(void*)onChangeValueListeners[onChangeValueListeners.length - 1],
614 			cast(GClosureNotify)&callBackChangeValueDestroy,
615 			connectFlags);
616 		return onChangeValueListeners[onChangeValueListeners.length - 1].handlerId;
617 	}
618 	
619 	extern(C) static int callBackChangeValue(GtkRange* rangeStruct, GtkScrollType scroll, double value,OnChangeValueDelegateWrapper wrapper)
620 	{
621 		return wrapper.dlg(scroll, value, wrapper.outer);
622 	}
623 	
624 	extern(C) static void callBackChangeValueDestroy(OnChangeValueDelegateWrapper wrapper, GClosure* closure)
625 	{
626 		wrapper.outer.internalRemoveOnChangeValue(wrapper);
627 	}
628 
629 	protected void internalRemoveOnChangeValue(OnChangeValueDelegateWrapper source)
630 	{
631 		foreach(index, wrapper; onChangeValueListeners)
632 		{
633 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
634 			{
635 				onChangeValueListeners[index] = null;
636 				onChangeValueListeners = std.algorithm.remove(onChangeValueListeners, index);
637 				break;
638 			}
639 		}
640 	}
641 	
642 
643 	protected class OnMoveSliderDelegateWrapper
644 	{
645 		void delegate(GtkScrollType, Range) dlg;
646 		gulong handlerId;
647 		ConnectFlags flags;
648 		this(void delegate(GtkScrollType, Range) dlg, gulong handlerId, ConnectFlags flags)
649 		{
650 			this.dlg = dlg;
651 			this.handlerId = handlerId;
652 			this.flags = flags;
653 		}
654 	}
655 	protected OnMoveSliderDelegateWrapper[] onMoveSliderListeners;
656 
657 	/**
658 	 * Virtual function that moves the slider. Used for keybindings.
659 	 *
660 	 * Params:
661 	 *     step = how to move the slider
662 	 */
663 	gulong addOnMoveSlider(void delegate(GtkScrollType, Range) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
664 	{
665 		onMoveSliderListeners ~= new OnMoveSliderDelegateWrapper(dlg, 0, connectFlags);
666 		onMoveSliderListeners[onMoveSliderListeners.length - 1].handlerId = Signals.connectData(
667 			this,
668 			"move-slider",
669 			cast(GCallback)&callBackMoveSlider,
670 			cast(void*)onMoveSliderListeners[onMoveSliderListeners.length - 1],
671 			cast(GClosureNotify)&callBackMoveSliderDestroy,
672 			connectFlags);
673 		return onMoveSliderListeners[onMoveSliderListeners.length - 1].handlerId;
674 	}
675 	
676 	extern(C) static void callBackMoveSlider(GtkRange* rangeStruct, GtkScrollType step,OnMoveSliderDelegateWrapper wrapper)
677 	{
678 		wrapper.dlg(step, wrapper.outer);
679 	}
680 	
681 	extern(C) static void callBackMoveSliderDestroy(OnMoveSliderDelegateWrapper wrapper, GClosure* closure)
682 	{
683 		wrapper.outer.internalRemoveOnMoveSlider(wrapper);
684 	}
685 
686 	protected void internalRemoveOnMoveSlider(OnMoveSliderDelegateWrapper source)
687 	{
688 		foreach(index, wrapper; onMoveSliderListeners)
689 		{
690 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
691 			{
692 				onMoveSliderListeners[index] = null;
693 				onMoveSliderListeners = std.algorithm.remove(onMoveSliderListeners, index);
694 				break;
695 			}
696 		}
697 	}
698 	
699 
700 	protected class OnValueChangedDelegateWrapper
701 	{
702 		void delegate(Range) dlg;
703 		gulong handlerId;
704 		ConnectFlags flags;
705 		this(void delegate(Range) dlg, gulong handlerId, ConnectFlags flags)
706 		{
707 			this.dlg = dlg;
708 			this.handlerId = handlerId;
709 			this.flags = flags;
710 		}
711 	}
712 	protected OnValueChangedDelegateWrapper[] onValueChangedListeners;
713 
714 	/**
715 	 * Emitted when the range value changes.
716 	 */
717 	gulong addOnValueChanged(void delegate(Range) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
718 	{
719 		onValueChangedListeners ~= new OnValueChangedDelegateWrapper(dlg, 0, connectFlags);
720 		onValueChangedListeners[onValueChangedListeners.length - 1].handlerId = Signals.connectData(
721 			this,
722 			"value-changed",
723 			cast(GCallback)&callBackValueChanged,
724 			cast(void*)onValueChangedListeners[onValueChangedListeners.length - 1],
725 			cast(GClosureNotify)&callBackValueChangedDestroy,
726 			connectFlags);
727 		return onValueChangedListeners[onValueChangedListeners.length - 1].handlerId;
728 	}
729 	
730 	extern(C) static void callBackValueChanged(GtkRange* rangeStruct,OnValueChangedDelegateWrapper wrapper)
731 	{
732 		wrapper.dlg(wrapper.outer);
733 	}
734 	
735 	extern(C) static void callBackValueChangedDestroy(OnValueChangedDelegateWrapper wrapper, GClosure* closure)
736 	{
737 		wrapper.outer.internalRemoveOnValueChanged(wrapper);
738 	}
739 
740 	protected void internalRemoveOnValueChanged(OnValueChangedDelegateWrapper source)
741 	{
742 		foreach(index, wrapper; onValueChangedListeners)
743 		{
744 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
745 			{
746 				onValueChangedListeners[index] = null;
747 				onValueChangedListeners = std.algorithm.remove(onValueChangedListeners, index);
748 				break;
749 			}
750 		}
751 	}
752 	
753 }