1 /** 2 * Widget module. 3 * 4 * License: 5 * MIT. See LICENSE for full details. 6 */ 7 module tkd.widget.scrollbar; 8 9 /** 10 * Imports. 11 */ 12 import std.conv; 13 import tkd.element.uielement; 14 import tkd.widget.common.xscrollcommand; 15 import tkd.widget.common.yscrollcommand; 16 import tkd.widget.widget; 17 18 /** 19 * Scrollbar widgets are typically linked to an associated window that displays 20 * a document of some sort, such as a file being edited or a drawing. A 21 * scrollbar displays a thumb in the middle portion of the scrollbar, whose 22 * position and size provides information about the portion of the document 23 * visible in the associated window. The thumb may be dragged by the user to 24 * control the visible region. Depending on the theme, two or more arrow 25 * buttons may also be present; these are used to scroll the visible region in 26 * discrete units. 27 * 28 * Example: 29 * --- 30 * auto frame = new Frame() 31 * .grid(0, 0); 32 * 33 * auto canvas = new Canvas(frame); 34 * .setWidth(300) 35 * .setHeight(150) 36 * .setScrollRegion(-100, -150, 500, 350) 37 * 38 * auto yscroll = new YScrollBar(frame) 39 * .attachWidget(canvas) 40 * .grid(1, 0, 0, 0, 1, 1, "nes"); 41 * 42 * auto xscroll = new XScrollBar(frame) 43 * .attachWidget(canvas) 44 * .grid(0, 1, 0, 0, 1, 1, "esw"); 45 * 46 * canvas.attachXScrollBar(xscroll) 47 * .attachYScrollBar(yscroll) 48 * .grid(0, 0, 0, 0, 1, 1, "nesw"); 49 * --- 50 * 51 * Additional_Events: 52 * Additional events that can also be bound to using the $(LINK2 ../element/uielement.html#UiElement.bind, bind) method. 53 * $(P 54 * <<PrevWindow>>, 55 * <Alt-Key>, 56 * <B1-Motion>, 57 * <B2-Motion>, 58 * <Button-1>, 59 * <Button-2>, 60 * <ButtonRelease-1>, 61 * <ButtonRelease-2>, 62 * <Key-F10>, 63 * <Key-Tab>, 64 * ) 65 * 66 * States: 67 * The scrollbar automatically sets the disabled state when the entire 68 * range is visible and clears it otherwise. 69 * 70 * See_Also: 71 * $(LINK2 ./widget.html, tkd.widget.widget) 72 */ 73 abstract class ScrollBar : Widget 74 { 75 /** 76 * Construct the widget. 77 * 78 * Params: 79 * parent = The parent of this widget. 80 * 81 * See_Also: 82 * $(LINK2 ../element/uielement.html, tkd.element.uielement) $(BR) 83 */ 84 this(UiElement parent = null) 85 { 86 super(parent); 87 this._elementId = "scrollbar"; 88 89 this._tk.eval("ttk::scrollbar %s", this.id); 90 } 91 92 /** 93 * Returns a real number indicating the fractional change in the scrollbar 94 * setting that corresponds to a given change in thumb position. For 95 * example, if the scrollbar is horizontal, the result indicates how much 96 * the scrollbar setting must change to move the thumb deltaX pixels to the 97 * right (deltaY is ignored in this case). If the scrollbar is vertical, 98 * the result indicates how much the scrollbar setting must change to move 99 * the thumb deltaY pixels down. The arguments and the result may be zero 100 * or negative. 101 * 102 * Params: 103 * deltaX = The amount to move horizontally. 104 * deltaY = The amount to move vertically. 105 * 106 * Returns: 107 * The fractional change. 108 */ 109 public double getDelta(int deltaX, int deltaY) 110 { 111 this._tk.eval("%s delta %s %s", this.id, deltaX, deltaY); 112 return this._tk.getResult!(double); 113 } 114 115 /** 116 * Returns a real number between 0 and 1 indicating where the point given 117 * by x and y lies in the trough area of the scrollbar, where 0.0 118 * corresponds to the top or left of the trough and 1.0 corresponds to the 119 * bottom or right. X and y are pixel coordinates relative to the scrollbar 120 * widget. If x and y refer to a point outside the trough, the closest 121 * point in the trough is used. 122 * 123 * Params: 124 * x = The x position. 125 * y = The y position. 126 * 127 * Returns: 128 * The fractional position. 129 */ 130 public double getFraction(int x, int y) 131 { 132 this._tk.eval("%s fraction %s %s", this.id, x, y); 133 return this._tk.getResult!(double); 134 } 135 } 136 137 /** 138 * Class representing a horizontal scrollbar widget. 139 */ 140 class XScrollBar : ScrollBar 141 { 142 /** 143 * Construct the widget. 144 * 145 * Params: 146 * parent = The parent of this widget. 147 * 148 * See_Also: 149 * $(LINK2 ../element/uielement.html, tkd.element.uielement) $(BR) 150 */ 151 this(UiElement parent = null) 152 { 153 super(parent); 154 this._tk.eval("%s configure -orient horizontal", this.id); 155 } 156 157 /** 158 * Attach a horizontally scrollable widget to this scrollbar. 159 * 160 * Params: 161 * scrollableWidget = A horizontally scrollable widget. 162 * 163 * Returns: 164 * This widget to aid method chaining. 165 * 166 * See_Also: 167 * $(LINK2 ./common/xscrollcommand.html, tkd.widget.common.xscrollcommand) $(BR) 168 */ 169 public auto attachWidget(this T, S)(IXScrollable!(S) scrollableWidget) 170 { 171 auto widget = cast(Widget)scrollableWidget; 172 173 this._tk.eval("%s configure -command [list %s xview]", this.id, widget.id); 174 175 return cast(T) this; 176 } 177 178 } 179 180 /** 181 * Class representing a vertical scrollbar widget. 182 */ 183 class YScrollBar : ScrollBar 184 { 185 /** 186 * Construct the widget. 187 * 188 * Params: 189 * parent = The parent of this widget. 190 * 191 * See_Also: 192 * $(LINK2 ../element/uielement.html, tkd.element.uielement) $(BR) 193 */ 194 this(UiElement parent = null) 195 { 196 super(parent); 197 this._tk.eval("%s configure -orient vertical", this.id); 198 } 199 200 /** 201 * Attach a vertically scrollable widget to this scrollbar. 202 * 203 * Params: 204 * scrollableWidget = A vertically scrollable widget. 205 * 206 * Returns: 207 * This widget to aid method chaining. 208 * 209 * See_Also: 210 * $(LINK2 ./common/yscrollcommand.html, tkd.widget.common.yscrollcommand) $(BR) 211 */ 212 public auto attachWidget(this T, S)(IYScrollable!(S) scrollableWidget) 213 { 214 auto widget = cast(Widget)scrollableWidget; 215 216 this._tk.eval("%s configure -command [list %s yview]", this.id, widget.id); 217 218 return cast(T) this; 219 } 220 }