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.Scale; 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.Adjustment; 32 private import gtk.Range; 33 private import gtk.Widget; 34 public import gtkc.gdktypes; 35 private import gtkc.gtk; 36 public import gtkc.gtktypes; 37 private import pango.PgLayout; 38 private import std.algorithm; 39 40 41 /** 42 * A GtkScale is a slider control used to select a numeric value. 43 * To use it, you’ll probably want to investigate the methods on 44 * its base class, #GtkRange, in addition to the methods for GtkScale itself. 45 * To set the value of a scale, you would normally use gtk_range_set_value(). 46 * To detect changes to the value, you would normally use the 47 * #GtkRange::value-changed signal. 48 * 49 * Note that using the same upper and lower bounds for the #GtkScale (through 50 * the #GtkRange methods) will hide the slider itself. This is useful for 51 * applications that want to show an undeterminate value on the scale, without 52 * changing the layout of the application (such as movie or music players). 53 * 54 * # GtkScale as GtkBuildable 55 * 56 * GtkScale supports a custom <marks> element, which can contain multiple 57 * <mark> elements. The “value” and “position” attributes have the same 58 * meaning as gtk_scale_add_mark() parameters of the same name. If the 59 * element is not empty, its content is taken as the markup to show at 60 * the mark. It can be translated with the usual ”translatable” and 61 * “context” attributes. 62 * 63 * # CSS nodes 64 * 65 * |[<!-- language="plain" --> 66 * scale[.fine-tune][.marks-before][.marks-after] 67 * ├── marks.top 68 * │ ├── mark 69 * │ ┊ ├── [label] 70 * │ ┊ ╰── indicator 71 * ┊ ┊ 72 * │ ╰── mark 73 * ├── [value] 74 * ├── contents 75 * │ ╰── trough 76 * │ ├── slider 77 * │ ├── [highlight] 78 * │ ╰── [fill] 79 * ╰── marks.bottom 80 * ├── mark 81 * ┊ ├── indicator 82 * ┊ ╰── [label] 83 * ╰── mark 84 * ]| 85 * 86 * GtkScale has a main CSS node with name scale and a subnode for its contents, 87 * with subnodes named trough and slider. 88 * 89 * The main node gets the style class .fine-tune added when the scale is in 90 * 'fine-tuning' mode. 91 * 92 * If the scale has an origin (see gtk_scale_set_has_origin()), there is a 93 * subnode with name highlight below the trough node that is used for rendering 94 * the highlighted part of the trough. 95 * 96 * If the scale is showing a fill level (see gtk_range_set_show_fill_level()), 97 * there is a subnode with name fill below the trough node that is used for 98 * rendering the filled in part of the trough. 99 * 100 * If marks are present, there is a marks subnode before or after the contents 101 * node, below which each mark gets a node with name mark. The marks nodes get 102 * either the .top or .bottom style class. 103 * 104 * The mark node has a subnode named indicator. If the mark has text, it also 105 * has a subnode named label. When the mark is either above or left of the 106 * scale, the label subnode is the first when present. Otherwise, the indicator 107 * subnode is the first. 108 * 109 * The main CSS node gets the 'marks-before' and/or 'marks-after' style classes 110 * added depending on what marks are present. 111 * 112 * If the scale is displaying the value (see #GtkScale:draw-value), there is 113 * subnode with name value. 114 */ 115 public class Scale : Range 116 { 117 /** the main Gtk struct */ 118 protected GtkScale* gtkScale; 119 120 /** Get the main Gtk struct */ 121 public GtkScale* getScaleStruct() 122 { 123 return gtkScale; 124 } 125 126 /** the main Gtk struct as a void* */ 127 protected override void* getStruct() 128 { 129 return cast(void*)gtkScale; 130 } 131 132 protected override void setStruct(GObject* obj) 133 { 134 gtkScale = cast(GtkScale*)obj; 135 super.setStruct(obj); 136 } 137 138 /** 139 * Sets our main struct and passes it to the parent class. 140 */ 141 public this (GtkScale* gtkScale, bool ownedRef = false) 142 { 143 this.gtkScale = gtkScale; 144 super(cast(GtkRange*)gtkScale, ownedRef); 145 } 146 147 148 /** */ 149 public static GType getType() 150 { 151 return gtk_scale_get_type(); 152 } 153 154 /** 155 * Creates a new #GtkScale. 156 * 157 * Params: 158 * orientation = the scale’s orientation. 159 * adjustment = the #GtkAdjustment which sets the range 160 * of the scale, or %NULL to create a new adjustment. 161 * 162 * Return: a new #GtkScale 163 * 164 * Since: 3.0 165 * 166 * Throws: ConstructionException GTK+ fails to create the object. 167 */ 168 public this(GtkOrientation orientation, Adjustment adjustment) 169 { 170 auto p = gtk_scale_new(orientation, (adjustment is null) ? null : adjustment.getAdjustmentStruct()); 171 172 if(p is null) 173 { 174 throw new ConstructionException("null returned by new"); 175 } 176 177 this(cast(GtkScale*) p); 178 } 179 180 /** 181 * Creates a new scale widget with the given orientation that lets the 182 * user input a number between @min and @max (including @min and @max) 183 * with the increment @step. @step must be nonzero; it’s the distance 184 * the slider moves when using the arrow keys to adjust the scale 185 * value. 186 * 187 * Note that the way in which the precision is derived works best if @step 188 * is a power of ten. If the resulting precision is not suitable for your 189 * needs, use gtk_scale_set_digits() to correct it. 190 * 191 * Params: 192 * orientation = the scale’s orientation. 193 * min = minimum value 194 * max = maximum value 195 * step = step increment (tick size) used with keyboard shortcuts 196 * 197 * Return: a new #GtkScale 198 * 199 * Since: 3.0 200 * 201 * Throws: ConstructionException GTK+ fails to create the object. 202 */ 203 public this(GtkOrientation orientation, double min, double max, double step) 204 { 205 auto p = gtk_scale_new_with_range(orientation, min, max, step); 206 207 if(p is null) 208 { 209 throw new ConstructionException("null returned by new_with_range"); 210 } 211 212 this(cast(GtkScale*) p); 213 } 214 215 /** 216 * Adds a mark at @value. 217 * 218 * A mark is indicated visually by drawing a tick mark next to the scale, 219 * and GTK+ makes it easy for the user to position the scale exactly at the 220 * marks value. 221 * 222 * If @markup is not %NULL, text is shown next to the tick mark. 223 * 224 * To remove marks from a scale, use gtk_scale_clear_marks(). 225 * 226 * Params: 227 * value = the value at which the mark is placed, must be between 228 * the lower and upper limits of the scales’ adjustment 229 * position = where to draw the mark. For a horizontal scale, #GTK_POS_TOP 230 * and %GTK_POS_LEFT are drawn above the scale, anything else below. 231 * For a vertical scale, #GTK_POS_LEFT and %GTK_POS_TOP are drawn to 232 * the left of the scale, anything else to the right. 233 * markup = Text to be shown at the mark, using [Pango markup][PangoMarkupFormat], or %NULL 234 * 235 * Since: 2.16 236 */ 237 public void addMark(double value, GtkPositionType position, string markup) 238 { 239 gtk_scale_add_mark(gtkScale, value, position, Str.toStringz(markup)); 240 } 241 242 /** 243 * Removes any marks that have been added with gtk_scale_add_mark(). 244 * 245 * Since: 2.16 246 */ 247 public void clearMarks() 248 { 249 gtk_scale_clear_marks(gtkScale); 250 } 251 252 /** 253 * Gets the number of decimal places that are displayed in the value. 254 * 255 * Return: the number of decimal places that are displayed 256 */ 257 public int getDigits() 258 { 259 return gtk_scale_get_digits(gtkScale); 260 } 261 262 /** 263 * Returns whether the current value is displayed as a string 264 * next to the slider. 265 * 266 * Return: whether the current value is displayed as a string 267 */ 268 public bool getDrawValue() 269 { 270 return gtk_scale_get_draw_value(gtkScale) != 0; 271 } 272 273 /** 274 * Returns whether the scale has an origin. 275 * 276 * Return: %TRUE if the scale has an origin. 277 * 278 * Since: 3.4 279 */ 280 public bool getHasOrigin() 281 { 282 return gtk_scale_get_has_origin(gtkScale) != 0; 283 } 284 285 /** 286 * Gets the #PangoLayout used to display the scale. The returned 287 * object is owned by the scale so does not need to be freed by 288 * the caller. 289 * 290 * Return: the #PangoLayout for this scale, 291 * or %NULL if the #GtkScale:draw-value property is %FALSE. 292 * 293 * Since: 2.4 294 */ 295 public PgLayout getLayout() 296 { 297 auto p = gtk_scale_get_layout(gtkScale); 298 299 if(p is null) 300 { 301 return null; 302 } 303 304 return ObjectG.getDObject!(PgLayout)(cast(PangoLayout*) p); 305 } 306 307 /** 308 * Obtains the coordinates where the scale will draw the 309 * #PangoLayout representing the text in the scale. Remember 310 * when using the #PangoLayout function you need to convert to 311 * and from pixels using PANGO_PIXELS() or #PANGO_SCALE. 312 * 313 * If the #GtkScale:draw-value property is %FALSE, the return 314 * values are undefined. 315 * 316 * Params: 317 * x = location to store X offset of layout, or %NULL 318 * y = location to store Y offset of layout, or %NULL 319 * 320 * Since: 2.4 321 */ 322 public void getLayoutOffsets(out int x, out int y) 323 { 324 gtk_scale_get_layout_offsets(gtkScale, &x, &y); 325 } 326 327 /** 328 * Gets the position in which the current value is displayed. 329 * 330 * Return: the position in which the current value is displayed 331 */ 332 public GtkPositionType getValuePos() 333 { 334 return gtk_scale_get_value_pos(gtkScale); 335 } 336 337 /** 338 * Sets the number of decimal places that are displayed in the value. 339 * Also causes the value of the adjustment to be rounded off to this 340 * number of digits, so the retrieved value matches the value the user saw. 341 * 342 * Note that rounding to a small number of digits can interfere with 343 * the smooth autoscrolling that is built into #GtkScale. As an alternative, 344 * you can use the #GtkScale::format-value signal to format the displayed 345 * value yourself. 346 * 347 * Params: 348 * digits = the number of decimal places to display, 349 * e.g. use 1 to display 1.0, 2 to display 1.00, etc 350 */ 351 public void setDigits(int digits) 352 { 353 gtk_scale_set_digits(gtkScale, digits); 354 } 355 356 /** 357 * Specifies whether the current value is displayed as a string next 358 * to the slider. 359 * 360 * Params: 361 * drawValue = %TRUE to draw the value 362 */ 363 public void setDrawValue(bool drawValue) 364 { 365 gtk_scale_set_draw_value(gtkScale, drawValue); 366 } 367 368 /** 369 * If @has_origin is set to %TRUE (the default), 370 * the scale will highlight the part of the scale 371 * between the origin (bottom or left side) of the scale 372 * and the current value. 373 * 374 * Params: 375 * hasOrigin = %TRUE if the scale has an origin 376 * 377 * Since: 3.4 378 */ 379 public void setHasOrigin(bool hasOrigin) 380 { 381 gtk_scale_set_has_origin(gtkScale, hasOrigin); 382 } 383 384 /** 385 * Sets the position in which the current value is displayed. 386 * 387 * Params: 388 * pos = the position in which the current value is displayed 389 */ 390 public void setValuePos(GtkPositionType pos) 391 { 392 gtk_scale_set_value_pos(gtkScale, pos); 393 } 394 395 protected class OnFormatValueDelegateWrapper 396 { 397 string delegate(double, Scale) dlg; 398 gulong handlerId; 399 ConnectFlags flags; 400 this(string delegate(double, Scale) dlg, gulong handlerId, ConnectFlags flags) 401 { 402 this.dlg = dlg; 403 this.handlerId = handlerId; 404 this.flags = flags; 405 } 406 } 407 protected OnFormatValueDelegateWrapper[] onFormatValueListeners; 408 409 /** 410 * Signal which allows you to change how the scale value is displayed. 411 * Connect a signal handler which returns an allocated string representing 412 * @value. That string will then be used to display the scale's value. 413 * 414 * Here's an example signal handler which displays a value 1.0 as 415 * with "-->1.0<--". 416 * |[<!-- language="C" --> 417 * static gchar* 418 * format_value_callback (GtkScale *scale, 419 * gdouble value) 420 * { 421 * return g_strdup_printf ("-->\%0.*g<--", 422 * gtk_scale_get_digits (scale), value); 423 * } 424 * ]| 425 * 426 * Params: 427 * value = the value to format 428 * 429 * Return: allocated string representing @value 430 */ 431 gulong addOnFormatValue(string delegate(double, Scale) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 432 { 433 onFormatValueListeners ~= new OnFormatValueDelegateWrapper(dlg, 0, connectFlags); 434 onFormatValueListeners[onFormatValueListeners.length - 1].handlerId = Signals.connectData( 435 this, 436 "format-value", 437 cast(GCallback)&callBackFormatValue, 438 cast(void*)onFormatValueListeners[onFormatValueListeners.length - 1], 439 cast(GClosureNotify)&callBackFormatValueDestroy, 440 connectFlags); 441 return onFormatValueListeners[onFormatValueListeners.length - 1].handlerId; 442 } 443 444 extern(C) static string callBackFormatValue(GtkScale* scaleStruct, double value,OnFormatValueDelegateWrapper wrapper) 445 { 446 return wrapper.dlg(value, wrapper.outer); 447 } 448 449 extern(C) static void callBackFormatValueDestroy(OnFormatValueDelegateWrapper wrapper, GClosure* closure) 450 { 451 wrapper.outer.internalRemoveOnFormatValue(wrapper); 452 } 453 454 protected void internalRemoveOnFormatValue(OnFormatValueDelegateWrapper source) 455 { 456 foreach(index, wrapper; onFormatValueListeners) 457 { 458 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 459 { 460 onFormatValueListeners[index] = null; 461 onFormatValueListeners = std.algorithm.remove(onFormatValueListeners, index); 462 break; 463 } 464 } 465 } 466 467 }