1 /** 2 * Widget module. 3 * 4 * License: 5 * MIT. See LICENSE for full details. 6 */ 7 module tkd.widget.text; 8 9 /** 10 * Imports. 11 */ 12 import tkd.element.uielement; 13 import tkd.image.image; 14 import tkd.widget.common.border; 15 import tkd.widget.common.height; 16 import tkd.widget.common.relief; 17 import tkd.widget.common.width; 18 import tkd.widget.common.xscrollcommand; 19 import tkd.widget.common.xview; 20 import tkd.widget.common.yscrollcommand; 21 import tkd.widget.common.yview; 22 import tkd.widget.textwrapmode; 23 import tkd.widget.widget; 24 25 /** 26 * A text widget displays one or more lines of text and allows that text to be 27 * edited. Text widgets support embedded widgets or embedded images. 28 * 29 * Example: 30 * --- 31 * auto text = new Text() 32 * .appendText("Text") 33 * .pack(); 34 * --- 35 * 36 * Common_Commands: 37 * These are injected common commands that can also be used with this widget. 38 * $(P 39 * $(LINK2 ./common/border.html, Border) $(BR) 40 * $(LINK2 ./common/height.html, Height) $(BR) 41 * $(LINK2 ./common/relief.html, Relief) $(BR) 42 * $(LINK2 ./common/width.html, Width) $(BR) 43 * $(LINK2 ./common/xscrollcommand.html, XScrollCommand) $(BR) 44 * $(LINK2 ./common/xview.html, XView) $(BR) 45 * $(LINK2 ./common/yscrollcommand.html, YScrollCommand) $(BR) 46 * $(LINK2 ./common/yview.html, YView) $(BR) 47 * ) 48 * 49 * Additional_Events: 50 * Additional events that can also be bound to using the $(LINK2 ../element/uielement.html#UiElement.bind, bind) method. 51 * $(P 52 * <<Clear>>, 53 * <<Copy>>, 54 * <<Cut>>, 55 * <<Modified>>, 56 * <<Paste>>, 57 * <<PasteSelection>>, 58 * <<PrevWindow>>, 59 * <<Redo>>, 60 * <<Selection>>, 61 * <<Undo>>, 62 * <Alt-Key>, 63 * <B1-Enter>, 64 * <B1-Leave>, 65 * <B1-Motion>, 66 * <B2-Motion>, 67 * <Button-1>, 68 * <Button-2>, 69 * <Button-4>, 70 * <Button-5>, 71 * <ButtonRelease-1>, 72 * <Control-Button-1>, 73 * <Control-Key-Down>, 74 * <Control-Key-End>, 75 * <Control-Key-Home>, 76 * <Control-Key-Left>, 77 * <Control-Key-Next>, 78 * <Control-Key-Prior>, 79 * <Control-Key-Right>, 80 * <Control-Key-Tab>, 81 * <Control-Key-Up>, 82 * <Control-Key-a>, 83 * <Control-Key-b>, 84 * <Control-Key-backslash>, 85 * <Control-Key-d>, 86 * <Control-Key-e>, 87 * <Control-Key-f>, 88 * <Control-Key-h>, 89 * <Control-Key-i>, 90 * <Control-Key-k>, 91 * <Control-Key-n>, 92 * <Control-Key-o>, 93 * <Control-Key-p>, 94 * <Control-Key-slash>, 95 * <Control-Key-space>, 96 * <Control-Key-t>, 97 * <Control-Key>, 98 * <Control-Shift-Key-Down>, 99 * <Control-Shift-Key-End>, 100 * <Control-Shift-Key-Home>, 101 * <Control-Shift-Key-Left>, 102 * <Control-Shift-Key-Right>, 103 * <Control-Shift-Key-Tab>, 104 * <Control-Shift-Key-Up>, 105 * <Control-Shift-Key-space>, 106 * <Double-Button-1>, 107 * <Double-Shift-Button-1>, 108 * <Key-BackSpace>, 109 * <Key-Delete>, 110 * <Key-Down>, 111 * <Key-End>, 112 * <Key-Escape>, 113 * <Key-F10>, 114 * <Key-Home>, 115 * <Key-Insert>, 116 * <Key-KP_Enter>, 117 * <Key-Left>, 118 * <Key-Next>, 119 * <Key-Prior>, 120 * <Key-Return>, 121 * <Key-Right>, 122 * <Key-Select>, 123 * <Key-Tab>, 124 * <Key-Up>, 125 * <Key>, 126 * <Meta-Key-BackSpace>, 127 * <Meta-Key-Delete>, 128 * <Meta-Key-b>, 129 * <Meta-Key-d>, 130 * <Meta-Key-f>, 131 * <Meta-Key-greater>, 132 * <Meta-Key-less>, 133 * <Meta-Key>, 134 * <MouseWheel>, 135 * <Shift-Button-1>, 136 * <Shift-Key-Down>, 137 * <Shift-Key-End>, 138 * <Shift-Key-Home>, 139 * <Shift-Key-Left>, 140 * <Shift-Key-Next>, 141 * <Shift-Key-Prior>, 142 * <Shift-Key-Right>, 143 * <Shift-Key-Select>, 144 * <Shift-Key-Tab>, 145 * <Shift-Key-Up>, 146 * <Triple-Button-1>, 147 * <Triple-Shift-Button-1>, 148 * ) 149 * 150 * See_Also: 151 * $(LINK2 ./widget.html, tkd.widget.widget) 152 */ 153 class Text : Widget, IXScrollable!(Text), IYScrollable!(Text) 154 { 155 /** 156 * Construct the widget. 157 * 158 * Params: 159 * parent = The parent of this widget. 160 * 161 * See_Also: 162 * $(LINK2 ../element/uielement.html, tkd.element.UiElement) $(BR) 163 */ 164 public this(UiElement parent = null) 165 { 166 super(parent); 167 this._elementId = "text"; 168 169 this._tk.eval("text %s -highlightthickness 0", this.id); 170 171 this.setUndoSupport(true); 172 this.setUndoLevels(25); 173 this.setWrapMode(TextWrapMode.word); 174 } 175 176 /** 177 * Set the amount of padding in the text widget. 178 * 179 * Params: 180 * padding = The amount of padding in the text widget. 181 * 182 * Returns: 183 * This widget to aid method chaining. 184 */ 185 public auto setPadding(this T)(int padding) 186 { 187 this._tk.eval("%s configure -padx %s -pady %s", this.id, padding, padding); 188 189 return cast(T) this; 190 } 191 192 /** 193 * Set if the widget is readonly or not. 194 * 195 * Params: 196 * readOnly = Flag to toggle readonly state. 197 * 198 * Returns: 199 * This widget to aid method chaining. 200 */ 201 public auto setReadOnly(this T)(bool readOnly = true) 202 { 203 if(readOnly) 204 { 205 this._tk.eval("%s configure -state disabled", this.id); 206 } 207 else 208 { 209 this._tk.eval("%s configure -state normal", this.id); 210 } 211 212 return cast(T) this; 213 } 214 215 /** 216 * Enable or disable undo support. 217 * 218 * Params: 219 * enable = True to enable undo support, false to disable it. 220 * 221 * Returns: 222 * This widget to aid method chaining. 223 */ 224 public auto setUndoSupport(this T)(bool enable) 225 { 226 this._tk.eval("%s configure -undo %s", this.id, enable); 227 228 return cast(T) this; 229 } 230 231 /** 232 * Set the number of undo levels the widget will support. 233 * 234 * Params: 235 * undoLevels = The number of undo levels the widget will support. 236 * 237 * Returns: 238 * This widget to aid method chaining. 239 */ 240 public auto setUndoLevels(this T)(int undoLevels) 241 { 242 this._tk.eval("%s configure -maxundo %s", this.id, undoLevels); 243 244 return cast(T) this; 245 } 246 247 /** 248 * Set the wrap mode of the text. 249 * 250 * Params: 251 * mode = The mode to wrap the text with. 252 * 253 * Returns: 254 * This widget to aid method chaining. 255 * 256 * See_Also: 257 * $(LINK2 ./textwrapmode.html, tkd.widget.textwrapmode) 258 */ 259 public auto setWrapMode(this T)(string mode) 260 { 261 this._tk.eval("%s configure -wrap %s", this.id, mode); 262 263 return cast(T) this; 264 } 265 266 /** 267 * Appends text to the widget. 268 * 269 * Params: 270 * text = The text to append. 271 * 272 * Returns: 273 * This widget to aid method chaining. 274 */ 275 public auto appendText(this T)(string text) 276 { 277 this._tk.eval("%s insert end {%s}", this.id, text); 278 279 return cast(T) this; 280 } 281 282 /** 283 * Inserts text into the widget at a specified line and character index. 284 * 285 * Params: 286 * line = The line at which to insert the text. Indexes start at 1. 287 * character = The character at which to insert the text. Indexes start at 0. 288 * text = The text to insert. 289 * 290 * Returns: 291 * This widget to aid method chaining. 292 */ 293 public auto insertText(this T)(int line, int character, string text) 294 { 295 this._tk.eval("%s insert %s.%s {%s}", this.id, line, character, text); 296 297 return cast(T) this; 298 } 299 300 /** 301 * Get the text from the widget. 302 * 303 * Returns: 304 * The text from the widget. 305 */ 306 public string getText(this T)() 307 { 308 this._tk.eval("%s get 0.0 end", this.id); 309 310 return this._tk.getResult!(string); 311 } 312 313 /** 314 * Delete text from the widget. 315 * 316 * Params: 317 * fromLine = The line from which to start deleting. Indexes start at 1. 318 * fromChar = The character from which to start deleting. Indexes start at 0. 319 * toLine = The line up to (but not including) which to delete. Indexes start at 1. 320 * toChar = The character up to (but not including) which to delete. Indexes start at 0. 321 * 322 * Returns: 323 * This widget to aid method chaining. 324 */ 325 public auto deleteText(this T)(int fromLine, int fromChar, int toLine, int toChar) 326 { 327 this._tk.eval("%s delete %s.%s %s.%s", this.id, fromLine, fromChar, toLine, toChar); 328 329 return cast(T) this; 330 } 331 332 /** 333 * Delete all content from the widget. 334 * 335 * Returns: 336 * This widget to aid method chaining. 337 */ 338 public auto clear(this T)() 339 { 340 this._tk.eval("%s delete 0.0 end", this.id); 341 342 return cast(T) this; 343 } 344 345 /** 346 * Embed a widget into the text. 347 * 348 * Params: 349 * line = The line at which to insert the text. Indexes start at 1. 350 * character = The character at which to insert the text. Indexes start at 0. 351 * widget = The widget to embed. 352 * padding = The amount of padding around the widget. 353 * 354 * Returns: 355 * This widget to aid method chaining. 356 */ 357 public auto embedWidget(this T)(int line, int character, Widget widget, int padding = 0) 358 { 359 this._tk.eval("%s window create %s.%s -window %s -align center -padx %s -pady %s", this.id, line, character, widget.id, padding, padding); 360 361 return cast(T) this; 362 } 363 364 /** 365 * Embed an image into the text. 366 * 367 * Params: 368 * line = The line at which to insert the text. Indexes start at 1. 369 * character = The character at which to insert the text. Indexes start at 0. 370 * image = The image to embed. 371 * padding = The amount of padding around the widget. 372 * 373 * Returns: 374 * This widget to aid method chaining. 375 */ 376 public auto embedImage(this T)(int line, int character, Image image, int padding = 0) 377 { 378 this._tk.eval("%s image create %s.%s -image %s -align center -padx %s -pady %s", this.id, line, character, image.id, padding, padding); 379 380 return cast(T) this; 381 } 382 383 /** 384 * Undo the last edit to the widget. This only applied to the widget if 385 * undo is enabled. 386 * 387 * Returns: 388 * This widget to aid method chaining. 389 */ 390 public auto undo(this T)() 391 { 392 this._tk.eval("%s edit undo", this.id); 393 394 return cast(T) this; 395 } 396 397 /** 398 * Redo the last edit to the widget. This only applied to the widget if 399 * undo is enabled. 400 * 401 * Returns: 402 * This widget to aid method chaining. 403 */ 404 public auto redo(this T)() 405 { 406 this._tk.eval("%s edit redo", this.id); 407 408 return cast(T) this; 409 } 410 411 /** 412 * Clear all undo's. This only applied to the widget if 413 * undo is enabled. 414 * 415 * Returns: 416 * This widget to aid method chaining. 417 */ 418 public auto resetUndo(this T)() 419 { 420 this._tk.eval("%s edit reset", this.id); 421 422 return cast(T) this; 423 } 424 425 /** 426 * See a particular text index. The text widget automatically scrolls to 427 * see the passed indexes. 428 * 429 * Params: 430 * line = The line to see. Indexes start at 1. 431 * character = The character to see. Indexes start at 0. 432 * 433 * Returns: 434 * This widget to aid method chaining. 435 */ 436 public auto seeText(this T)(int line, int character = 0) 437 { 438 this._tk.eval("%s see %s.%s", this.id, line, character); 439 440 return cast(T) this; 441 } 442 443 /** 444 * Cut the selected text to the clipboard. 445 * 446 * Returns: 447 * This widget to aid method chaining. 448 */ 449 public auto cutText(this T)() 450 { 451 this._tk.eval("tk_textCut %s", this.id); 452 453 return cast(T) this; 454 } 455 456 /** 457 * Copy the selected text to the clipboard. 458 * 459 * Returns: 460 * This widget to aid method chaining. 461 */ 462 public auto copyText(this T)() 463 { 464 this._tk.eval("tk_textCopy %s", this.id); 465 466 return cast(T) this; 467 } 468 469 /** 470 * Paste the selected text from the clipboard at the cursor position. 471 * 472 * Returns: 473 * This widget to aid method chaining. 474 */ 475 public auto pasteText(this T)() 476 { 477 this._tk.eval("tk_textPaste %s", this.id); 478 479 return cast(T) this; 480 } 481 482 /** 483 * Mixin common commands. 484 */ 485 mixin Border; 486 mixin Height; 487 mixin Relief; 488 mixin Width; 489 mixin XScrollCommand!(Text); 490 mixin XView; 491 mixin YScrollCommand!(Text); 492 mixin YView; 493 }