1 /** 2 * Widget module. 3 * 4 * License: 5 * MIT. See LICENSE for full details. 6 */ 7 module tkd.widget.canvas; 8 9 /** 10 * Imports. 11 */ 12 import std.algorithm; 13 import std.array; 14 import std.conv; 15 import std..string; 16 import std.uni; 17 import tkd.element.color; 18 import tkd.element.element; 19 import tkd.element.uielement; 20 import tkd.image.image; 21 import tkd.widget.anchorposition; 22 import tkd.widget.common.border; 23 import tkd.widget.common.canvas.anchor; 24 import tkd.widget.common.canvas.arcspecific; 25 import tkd.widget.common.canvas.bind; 26 import tkd.widget.common.canvas.fillcolor; 27 import tkd.widget.common.canvas.imagespecific; 28 import tkd.widget.common.canvas.linespecific; 29 import tkd.widget.common.canvas.outlinecolor; 30 import tkd.widget.common.canvas.outlinedash; 31 import tkd.widget.common.canvas.outlinewidth; 32 import tkd.widget.common.canvas.state; 33 import tkd.widget.common.canvas.textspecific; 34 import tkd.widget.common.canvas.vertex; 35 import tkd.widget.common.canvas.widgetspecific; 36 import tkd.widget.common.height; 37 import tkd.widget.common.relief; 38 import tkd.widget.common.width; 39 import tkd.widget.common.xscrollcommand; 40 import tkd.widget.common.xview; 41 import tkd.widget.common.yscrollcommand; 42 import tkd.widget.common.yview; 43 import tkd.widget.reliefstyle; 44 import tkd.widget.widget; 45 46 /** 47 * Canvas widgets implement structured graphics. A canvas displays any number 48 * of items, which may be things like rectangles, circles, lines, and text. 49 * Items may be manipulated (e.g. moved or re-colored) and commands may be 50 * associated with items in much the same way that the bind command allows 51 * commands to be bound to widgets. 52 * 53 * Example: 54 * --- 55 * auto canvas = new Canvas(Color.white) 56 * .setWidth(350) 57 * .setHeight(250) 58 * .addItem(new CanvasRectangle([10, 10, 200, 100])) 59 * .bind("<ButtonPress-1>", delegate(CommandArgs args){ ... }) 60 * .pack(); 61 * --- 62 * 63 * Common_Commands: 64 * These are injected common commands that can also be used with this widget. 65 * $(P 66 * $(LINK2 ./common/border.html, Border) $(BR) 67 * $(LINK2 ./common/height.html, Height) $(BR) 68 * $(LINK2 ./common/relief.html, Relief) $(BR) 69 * $(LINK2 ./common/width.html, Width) $(BR) 70 * $(LINK2 ./common/xscrollcommand.html, XScrollCommand) $(BR) 71 * $(LINK2 ./common/xview.html, XView) $(BR) 72 * $(LINK2 ./common/yscrollcommand.html, YScrollCommand) $(BR) 73 * $(LINK2 ./common/yview.html, YView) $(BR) 74 * ) 75 * 76 * Additional_Events: 77 * Additional events that can also be bound to using the $(LINK2 ../element/uielement.html#UiElement.bind, bind) method. 78 * $(P 79 * <<PrevWindow>>, 80 * <Alt-Key>, 81 * <Key-F10>, 82 * <Key-Tab>, 83 * ) 84 * 85 * See_Also: 86 * $(LINK2 ./widget.html, tkd.widget.widget) 87 */ 88 class Canvas : Widget, IXScrollable!(Canvas), IYScrollable!(Canvas) 89 { 90 /** 91 * Construct the widget. 92 * 93 * Params: 94 * parent = The parent of this widget. 95 * backgroundColor = The background color. 96 * 97 * See_Also: 98 * $(LINK2 ../element/uielement.html, tkd.element.UiElement) $(BR) 99 */ 100 public this(UiElement parent, string backgroundColor = Color.default_) 101 { 102 super(parent); 103 this._elementId = "canvas"; 104 105 this._tk.eval("canvas %s", this.id); 106 107 this.setBorderWidth(1); 108 this.setRelief(ReliefStyle.sunken); 109 this.setBackgroundColor(backgroundColor); 110 } 111 112 /** 113 * Construct the widget. 114 * 115 * Params: 116 * backgroundColor = The background color. 117 * 118 * See_Also: 119 * $(LINK2 ../element/uielement.html, tkd.element.UiElement) $(BR) 120 */ 121 public this(string backgroundColor = Color.default_) 122 { 123 this(null, backgroundColor); 124 } 125 126 /** 127 * Set the background color. 128 * Use colors from the preset color $(LINK2 ../element/color.html, list) or a web style hex color. 129 * 130 * Params: 131 * color = The background color. 132 * 133 * Returns: 134 * This widget to aid method chaining. 135 * 136 * See_Also: 137 * $(LINK2 ../element/color.html, tkd.widget.color) $(BR) 138 */ 139 public auto setBackgroundColor(this T)(string color) 140 { 141 if (color.length) 142 { 143 this._tk.eval("%s configure -background {%s}", this.id, color); 144 } 145 146 return cast(T) this; 147 } 148 149 /** 150 * Specifies a floating-point value indicating how close the mouse cursor 151 * must be to an item before it is considered to be 'inside' the item and 152 * able to select it. Defaults to 1.0. 153 * 154 * Params: 155 * tolerance = The tolerance of the selection. 156 * 157 * Returns: 158 * This widget to aid method chaining. 159 */ 160 public auto setSelectionTolerance(this T)(double tolerance) 161 { 162 this._tk.eval("%s configure -closeenough %s", this.id, tolerance); 163 164 return cast(T) this; 165 } 166 167 /** 168 * Set the scroll region of the canvas. This region can be scrolled using 169 * scrollbars if it's bigger than the canvas widget itself. 170 * 171 * Params: 172 * left = The left hand side of the widget. 173 * top = The top side of the widget. 174 * right = The right hand side of the widget. 175 * bottom = The bottom side of the widget. 176 * 177 * Returns: 178 * This widget to aid method chaining. 179 */ 180 public auto setScrollRegion(this T)(double left, double top, double right, double bottom) 181 { 182 this._tk.eval("%s configure -scrollregion [list %s %s %s %s]", this.id, left, top, right, bottom); 183 184 return cast(T) this; 185 } 186 187 /** 188 * Set the scroll increment i.e. how many pixels are scrolled per each 189 * click on a scrollbar. 190 * 191 * Params: 192 * increment = The increment to scroll by. 193 * 194 * Returns: 195 * This widget to aid method chaining. 196 */ 197 public auto setScrollIncrement(this T)(int increment) 198 { 199 this._tk.eval("%s configure -xscrollincrement %s -yscrollincrement %s", this.id, increment, increment); 200 201 return cast(T) this; 202 } 203 204 /** 205 * Get the horizontal position on the canvas that relates to a particular 206 * horizontal position on screen. 207 * 208 * Params: 209 * screenXPos = The horizontal screen position to transpose. 210 * gridSpacing = The grid spacing to round it to. 211 * 212 * Returns: 213 * The horizontal canvas position. 214 */ 215 public int getXPosFromScreen(int screenXPos, int gridSpacing = 1) 216 { 217 this._tk.eval("%s canvasx %s %s", this.id, screenXPos, gridSpacing); 218 219 return this._tk.getResult!(string).chomp(".0").to!(int) - this.getXPos(); 220 } 221 222 /** 223 * Get the vertical position on the canvas that relates to a particular 224 * vertical position on screen. 225 * 226 * Params: 227 * screenYPos = The vertical screen position to transpose. 228 * gridSpacing = The grid spacing to round it to. 229 * 230 * Returns: 231 * The vertical canvas position. 232 */ 233 public int getYPosFromScreen(int screenYPos, int gridSpacing = 1) 234 { 235 this._tk.eval("%s canvasy %s %s", this.id, screenYPos, gridSpacing); 236 237 return this._tk.getResult!(string).chomp(".0").to!(int) - this.getYPos(); 238 } 239 240 /** 241 * Tag an item nearest to coordinates. If more than one item is at the same 242 * closest distance (e.g. two items overlap the point), then the top-most 243 * of these items (the last one in the display list) is used. If radius is 244 * specified, then it must be a non-negative value. Any item closer than 245 * halo to the point is considered to overlap it. 246 * 247 * Params: 248 * tag = The tag to add. 249 * xPos = The horizontal position. 250 * yPos = The vertical position. 251 * radius = The radius around the point. 252 * 253 * Returns: 254 * This widget to aid method chaining. 255 */ 256 public auto tagItemNear(this T)(string tag, int xPos, int yPos, uint radius = 0) 257 { 258 if (tag.length) 259 { 260 this._tk.eval("%s addtag %s closest %s %s %s", this.id, tag, xPos, yPos, radius); 261 } 262 263 return cast(T) this; 264 } 265 266 /** 267 * Tag items within a selection region. 268 * 269 * Params: 270 * tag = The tag to add. 271 * x1 = The left edge of the selection region. 272 * y1 = The top edge of the selection region. 273 * x2 = The right edge of the selection region. 274 * y2 = The bottom edge of the selection region. 275 * enclosedFully = Specifies if the items have to be enclosed fully or not. 276 * 277 * Returns: 278 * This widget to aid method chaining. 279 */ 280 public auto tagItemIn(this T)(string tag, int x1, int y1, int x2, int y2, bool enclosedFully = false) 281 { 282 assert(x1 <= x2, "x1 must not be greater than x2."); 283 assert(y1 <= y2, "y1 must not be greater than y2."); 284 285 if (tag.length) 286 { 287 if (enclosedFully) 288 { 289 this._tk.eval("%s addtag %s enclosed %s %s %s %s", this.id, tag, x1, y1, x2, y2); 290 } 291 else 292 { 293 this._tk.eval("%s addtag %s overlapping %s %s %s %s", this.id, tag, x1, y1, x2, y2); 294 } 295 } 296 297 return cast(T) this; 298 } 299 300 /** 301 * Tag items that are already tagged with another tag. 302 * 303 * Params: 304 * tag = The tag to add. 305 * searchTag = The tag to select items to tag. 306 * 307 * Returns: 308 * This widget to aid method chaining. 309 */ 310 public auto tagItemWithTag(this T)(string tag, string searchTag) 311 { 312 if (tag.length && searchTag.length) 313 { 314 this._tk.eval("%s addtag %s withtag %s", this.id, tag, searchTag); 315 } 316 317 return cast(T) this; 318 } 319 320 /** 321 * Get an item id nearest to coordinates. If more than one item is at the 322 * same closest distance (e.g. two items overlap the point), then the 323 * top-most of these items (the last one in the display list) is used. If 324 * radius is specified, then it must be a non-negative value. Any item 325 * closer than halo to the point is considered to overlap it. 326 * 327 * Params: 328 * xPos = The horizontal position. 329 * yPos = The vertical position. 330 * radius = The radius around the point. 331 * 332 * Returns: 333 * The item found. 334 */ 335 public int getItemIdNear(int xPos, int yPos, uint radius = 0) 336 { 337 this._tk.eval("%s find closest %s %s %s", this.id, xPos, yPos, radius); 338 339 return this._tk.getResult!(int); 340 } 341 342 /** 343 * Get items within a selection region. 344 * 345 * Params: 346 * x1 = The left edge of the selection region. 347 * y1 = The top edge of the selection region. 348 * x2 = The right edge of the selection region. 349 * y2 = The bottom edge of the selection region. 350 * enclosedFully = Specifies if the items have to be enclosed fully or not. 351 * 352 * Returns: 353 * An array of found items. 354 */ 355 public int[] getItemIdsIn(int x1, int y1, int x2, int y2, bool enclosedFully = false) 356 { 357 assert(x1 <= x2, "x1 must not be greater than x2."); 358 assert(y1 <= y2, "y1 must not be greater than y2."); 359 360 if (enclosedFully) 361 { 362 this._tk.eval("%s find enclosed %s %s %s %s", this.id, x1, y1, x2, y2); 363 } 364 else 365 { 366 this._tk.eval("%s find overlapping %s %s %s %s", this.id, x1, y1, x2, y2); 367 } 368 369 return this._tk.getResult!(string).split().map!(to!(int)).array; 370 } 371 372 /** 373 * Add an item to the canvas. 374 * 375 * Params: 376 * item = The item to add. 377 * 378 * Returns: 379 * This widget to aid method chaining. 380 */ 381 public auto addItem(this T)(CanvasItem item) 382 { 383 this._tk.eval("%s create %s [list %s]", this.id, item._type, item._coords.map!(to!(string)).join(" ")); 384 385 item.overrideGeneratedId(this._tk.getResult!(string)); 386 item.init(this); 387 388 return cast(T) this; 389 } 390 391 /** 392 * Add a tag configuration to the canvas. These can apply options to a tag 393 * which can then be applied to any item. 394 * 395 * Params: 396 * tagConfig = The configuration to add. 397 * 398 * Returns: 399 * This widget to aid method chaining. 400 */ 401 public auto addTagConfig(this T)(CanvasTagConfig tagConfig) 402 { 403 tagConfig.init(this); 404 405 return cast(T) this; 406 } 407 408 /** 409 * This command is used to implement scanning on canvases. Records x and y 410 * positions and the canvas's current view. This is used in conjunction 411 * with later scanDragTo commands. 412 * 413 * Params: 414 * xPos = The marked horizontal starting point of a scan. 415 * yPos = The marked vertical starting point of a scan. 416 * 417 * Returns: 418 * This widget to aid method chaining. 419 * 420 * See_Also: 421 * $(LINK2 ./canvas.html#Canvas.scanDragTo, tkd.widget.canvas.Canvas.scanDragTo) 422 */ 423 public auto setScanMark(this T)(double xPos, double yPos) 424 { 425 this._tk.eval("%s scan mark %s %s", this.id, xPos, yPos); 426 427 return cast(T) this; 428 } 429 430 /** 431 * This command is used to implement scanning on canvases. This command 432 * computes the difference between its xPos and yPos arguments (which are 433 * typically mouse coordinates) and the xPos and yPos arguments to the last 434 * setScanMark command for the widget. It then adjusts the view by gain 435 * times the difference in coordinates, where gain defaults to 1. This 436 * command is typically associated with mouse motion events in the widget, 437 * to produce the effect of dragging the canvas at high speed through its 438 * window. 439 * 440 * Params: 441 * xPos = The marked horizontal starting point of a scan. 442 * yPos = The marked vertical starting point of a scan. 443 * gain = The adjustment in the drag amount. 444 * 445 * Returns: 446 * This widget to aid method chaining. 447 * 448 * See_Also: 449 * $(LINK2 ./canvas.html#Canvas.setScanMark, tkd.widget.canvas.Canvas.setScanMark) 450 */ 451 public auto scanDragTo(this T)(double xPos, double yPos, int gain = 1) 452 { 453 this._tk.eval("%s scan dragto %s %s %s", this.id, xPos, yPos, gain); 454 455 return cast(T) this; 456 } 457 458 /** 459 * Mixin common commands. 460 */ 461 mixin Border; 462 mixin Height; 463 mixin Relief; 464 mixin Width; 465 mixin XScrollCommand!(Canvas); 466 mixin XView; 467 mixin YScrollCommand!(Canvas); 468 mixin YView; 469 } 470 471 /** 472 * Class representing a tag configuration. Tags can be applied to numerous 473 * items on the canvas but keep in mind the tag options set in the 474 * configuration must be compatible for all items the tag is assigned to or an 475 * error will occur. Tags must be applied to items before they can be 476 * configured. 477 * 478 * Common_Commands: 479 * These are injected common commands that can also be used with this widget. 480 * $(P 481 * $(LINK2 ./common/canvas/anchor.html, Anchor) $(BR) 482 * $(LINK2 ./common/canvas/arcspecific.html, ArcSpecific) $(BR) 483 * $(LINK2 ./common/canvas/bind.html, Bind) $(BR) 484 * $(LINK2 ./common/canvas/fillcolor.html, FillColor) $(BR) 485 * $(LINK2 ./common/canvas/imagespecific.html, ImageSpecific) $(BR) 486 * $(LINK2 ./common/canvas/linespecific.html, LineSpecific) $(BR) 487 * $(LINK2 ./common/canvas/outlinecolor.html, OutlineColor) $(BR) 488 * $(LINK2 ./common/canvas/outlinedash.html, OutlineDash) $(BR) 489 * $(LINK2 ./common/canvas/outlinewidth.html, OutlineWidth) $(BR) 490 * $(LINK2 ./common/canvas/state.html, State) $(BR) 491 * $(LINK2 ./common/canvas/textspecific.html, TextSpecific) $(BR) 492 * $(LINK2 ./common/canvas/vertex.html, Vertex) $(BR) 493 * $(LINK2 ./common/canvas/widgetspecific.html, WidgetSpecific) $(BR) 494 * ) 495 * 496 * See_Also: 497 * $(LINK2 ../element/element.html, tkd.element.element) 498 */ 499 class CanvasTagConfig : Element 500 { 501 /** 502 * Constructor. 503 * 504 * Params: 505 * tagName = The name of the tag to configure. 506 */ 507 this(string tagName) 508 { 509 this.overrideGeneratedId(tagName); 510 } 511 512 /* 513 * Initialise the item. 514 * 515 * Params: 516 * parent = The parent canvas to initialise against. 517 */ 518 protected void init(Canvas parent) 519 { 520 this._parent = parent; 521 522 foreach (binding, callback; this._bindings) 523 { 524 this.bind(binding, callback); 525 } 526 527 this.setActiveFillColor(this._activeFillColor); 528 this.setActiveImage(this._activeImage); 529 this.setActiveOutlineColor(this._activeOutlineColor); 530 this.setActiveOutlineDash(this._activeOutlineDash); 531 this.setActiveOutlineWidth(this._activeOutlineWidth); 532 this.setAlignment(this._alignment); 533 this.setAnchor(this._anchor); 534 this.setAngle(this._angle); 535 this.setArrowPosition(this._arrowPosition); 536 this.setArrowShape(this._arrowShape); 537 this.setCapStyle(this._capStyle); 538 this.setDisabledFillColor(this._disabledFillColor); 539 this.setDisabledImage(this._disabledImage); 540 this.setDisabledOutlineColor(this._disabledOutlineColor); 541 this.setDisabledOutlineDash(this._disabledOutlineDash); 542 this.setDisabledOutlineWidth(this._disabledOutlineWidth); 543 this.setExtent(this._extent); 544 this.setFillColor(this._fillColor); 545 this.setFont(this._font); 546 this.setHeight(this._height); 547 this.setImage(this._image); 548 this.setJoinStyle(this._joinStyle); 549 this.setMaxLineLength(this._maxLineLength); 550 this.setOutlineColor(this._outlineColor); 551 this.setOutlineDash(this._outlineDash); 552 this.setOutlineDashOffset(this._outlineDashOffset); 553 this.setOutlineWidth(this._outlineWidth); 554 this.setSmoothMethod(this._smoothMethod); 555 this.setSmoothSplineSteps(this._splineSteps); 556 this.setStartAngle(this._startAngle); 557 this.setState(this._state); 558 this.setStyle(this._style); 559 this.setText(this._text); 560 this.setWidget(this._widget); 561 this.setWidth(this._width); 562 } 563 564 /** 565 * Mixin common commands. 566 */ 567 mixin Anchor; 568 mixin ArcSpecific; 569 mixin Bind; 570 mixin FillColor; 571 mixin ImageSpecific; 572 mixin LineSpecific; 573 mixin OutlineColor; 574 mixin OutlineDash; 575 mixin OutlineWidth; 576 mixin State; 577 mixin TextSpecific; 578 mixin Vertex; 579 mixin WidgetSpecific; 580 } 581 582 /** 583 * Abstract base class of all canvas items. 584 * 585 * Common_Commands: 586 * These are injected common commands that can also be used with this widget. 587 * $(P 588 * $(LINK2 ./common/canvas/bind.html, Bind) $(BR) 589 * $(LINK2 ./common/canvas/state.html, State) $(BR) 590 * ) 591 * 592 * See_Also: 593 * $(LINK2 ../element/element.html, tkd.element.element) 594 */ 595 protected abstract class CanvasItem : Element 596 { 597 /** 598 * The type of the item. 599 */ 600 private string _type; 601 602 /** 603 * The coordinates where to draw the item. 604 */ 605 private double[] _coords; 606 607 /** 608 * The tags associated with this item. 609 */ 610 private string[] _tags; 611 612 /** 613 * Get the type of canvas item. 614 * 615 * Returns: 616 * The type of canvas item. 617 */ 618 public @property string type() 619 { 620 return this._type; 621 } 622 623 /* 624 * Initialise the item. 625 * 626 * Params: 627 * parent = The parent canvas to initialise against. 628 */ 629 protected void init(Canvas parent) 630 { 631 this._parent = parent; 632 633 foreach (binding, callback; this._bindings) 634 { 635 this.bind(binding, callback); 636 } 637 638 this.setState(this._state); 639 640 this.setTags(this._tags); 641 } 642 643 /** 644 * Get the coords of this item. 645 * 646 * Returns: 647 * An array of coords of this item. 648 */ 649 public double[] getCoords() 650 { 651 if (this._parent) 652 { 653 this._tk.eval("%s coords %s", this._parent.id, this.id); 654 this._coords = this._tk.getResult!(string).split().map!(to!(double)).array; 655 } 656 657 return this._coords; 658 } 659 660 /** 661 * Set the coordinates used to draw this item. 662 * 663 * Params: 664 * coords = The coords used for this item. 665 * 666 * Returns: 667 * This item to aid method chaining. 668 */ 669 public auto setCoords(this T)(double[] coords) 670 { 671 assert(coords.length >= 2, "Not enough coordinates specified."); 672 673 this._coords = coords; 674 675 if (this._parent) 676 { 677 this._tk.eval("%s coords %s [list %s]", this._parent.id, this.id, this._coords.map!(to!(string)).join(" ")); 678 } 679 680 return cast(T) this; 681 } 682 683 /** 684 * Get the tags associated with this item. 685 * 686 * Returns: 687 * An array of tags associated with this item. 688 */ 689 public string[] getTags() 690 { 691 if (this._parent) 692 { 693 this._tk.eval("%s gettags %s", this._parent.id, this.id); 694 this._tags = this._tk.getResult!(string).split(); 695 } 696 697 return this._tags; 698 } 699 700 /** 701 * Set tags associated with this item. 702 * 703 * Params: 704 * tags = The tags to associated with this item. 705 * 706 * Returns: 707 * This item to aid method chaining. 708 */ 709 public auto setTags(this T)(string[] tags) 710 { 711 foreach (tag; tags) 712 { 713 assert(!tag.all!(isNumber), "Tags must not be entirely composed of numbers."); 714 } 715 716 this._tags = tags; 717 718 if (this._parent && this._tags.length) 719 { 720 this._tk.eval("%s itemconfigure %s -tags {%s}", this._parent.id, this.id, this._tags.join(" ")); 721 } 722 723 return cast(T) this; 724 } 725 726 /** 727 * Add a specific tag to this item. 728 * 729 * Params: 730 * tag = The tags to add. 731 * 732 * Returns: 733 * This item to aid method chaining. 734 */ 735 public auto addTag(this T)(string tag) 736 { 737 assert(!tag.all!(isNumber), "Tags must not be entirely composed of numbers."); 738 739 this._tags = (this._tags ~= tag).uniq().array(); 740 741 if (this._parent && tag.length) 742 { 743 this._tk.eval("%s addtag {%s} withtag %s", this._parent.id, tag, this.id); 744 } 745 746 return cast(T) this; 747 } 748 749 /** 750 * Delete a specific tag associated to this item. 751 * 752 * Params: 753 * tag = The tags to delete. 754 * 755 * Returns: 756 * This item to aid method chaining. 757 */ 758 public auto deleteTag(this T)(string tag) 759 { 760 if (this._tags.canFind(tag)) 761 { 762 this._tags = std.algorithm.remove(this._tags, this._tags.countUntil(tag)); 763 } 764 765 if (this._parent && tag.length) 766 { 767 this._tk.eval("%s dtag %s {%s}", this._parent.id, this.id, tag); 768 } 769 770 return cast(T) this; 771 } 772 773 /** 774 * Delete all tags associated to this item. 775 * 776 * Returns: 777 * This item to aid method chaining. 778 */ 779 public auto clearTags(this T)() 780 { 781 this._tags = []; 782 783 if (this._parent) 784 { 785 this._tk.eval("%s itemconfigure %s -tags {}", this._parent.id, this.id); 786 } 787 788 return cast(T) this; 789 } 790 791 /** 792 * Destroy this item and remove it from the canvas. 793 * 794 * Caveats: 795 * Once an item is destroyed it can no longer be referenced in your 796 * code or a segmentation fault will occur and potentially crash your 797 * program. 798 */ 799 public void destroy() 800 { 801 if (this._parent) 802 { 803 this._tk.eval("%s delete %s", this._parent.id, this.id); 804 } 805 806 super.destroy(); 807 } 808 809 /** 810 * Set the keyboard focus to this item in the canvas. 811 * 812 * Returns: 813 * This widget to aid method chaining. 814 */ 815 public auto focus(this T)() 816 { 817 if (this._parent) 818 { 819 this._tk.eval("%s focus %s", this._parent.id, this.id); 820 } 821 822 return cast(T) this; 823 } 824 825 /** 826 * Lower an item in the drawing order. 827 * 828 * Returns: 829 * This widget to aid method chaining. 830 */ 831 public auto lower(this T)() 832 { 833 if (this._parent) 834 { 835 this._tk.eval("%s lower %s", this._parent.id, this.id); 836 } 837 838 return cast(T) this; 839 } 840 841 /** 842 * Raise an item in the drawing order. 843 * 844 * Returns: 845 * This widget to aid method chaining. 846 */ 847 public auto raise(this T)() 848 { 849 if (this._parent) 850 { 851 this._tk.eval("%s raise %s", this._parent.id, this.id); 852 } 853 854 return cast(T) this; 855 } 856 857 /** 858 * Move an item on the canvas by an amount. 859 * 860 * Params: 861 * xAmount = The amount to move the item horizontally. 862 * yAmount = The amount to move the item vertically. 863 * 864 * Returns: 865 * This widget to aid method chaining. 866 */ 867 public auto moveBy(this T)(int xAmount, int yAmount) 868 { 869 if (this._parent) 870 { 871 this._tk.eval("%s move %s %s %s", this._parent.id, this.id, xAmount, yAmount); 872 } 873 874 return cast(T) this; 875 } 876 877 /** 878 * Move an item on the canvas to a position. 879 * 880 * Params: 881 * xPos = The new horizontal position. 882 * yPos = The new vertical position. 883 * 884 * Returns: 885 * This widget to aid method chaining. 886 */ 887 public auto moveTo(this T)(int xPos, int yPos) 888 { 889 if (this._parent) 890 { 891 this._tk.eval("%s moveto %s %s %s", this._parent.id, this.id, xPos, yPos); 892 } 893 894 return cast(T) this; 895 } 896 897 /** 898 * Scale an item on the canvas. Note that some items have only a single 899 * pair of coordinates (e.g., text, images and widgets) and so scaling of 900 * them by this command can only move them around. 901 * 902 * Params: 903 * xOrigin = The horizontal origin from which to perform the scale. 904 * yOrigin = The vertical origin from which to perform the scale. 905 * xPercent = The amount to scale horizontally. 906 * yPercent = The amount to scale vertically. 907 * 908 * Returns: 909 * This widget to aid method chaining. 910 */ 911 public auto scale(this T)(double xOrigin, double yOrigin, double xPercent, double yPercent) 912 { 913 if (this._parent) 914 { 915 this._tk.eval("%s scale %s %s %s %s %s", this._parent.id, this.id, xOrigin, yOrigin, xPercent / 100, yPercent / 100); 916 } 917 918 return cast(T) this; 919 } 920 921 /** 922 * Mixin common commands. 923 */ 924 mixin Bind; 925 mixin State; 926 } 927 928 /** 929 * A canvas arc item. 930 * 931 * Common_Commands: 932 * These are injected common commands that can also be used with this canvas item. 933 * $(P 934 * $(LINK2 ./common/canvas/arcspecific.html, ArcSpecific) $(BR) 935 * $(LINK2 ./common/canvas/fillcolor.html, FillColor) $(BR) 936 * $(LINK2 ./common/canvas/outlinecolor.html, OutlineColor) $(BR) 937 * $(LINK2 ./common/canvas/outlinedash.html, OutlineDash) $(BR) 938 * $(LINK2 ./common/canvas/outlinewidth.html, OutlineWidth) $(BR) 939 * ) 940 * 941 * See_Also: 942 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 943 */ 944 class CanvasArc : CanvasItem 945 { 946 /** 947 * Create an arc. 948 * Use colors from the preset color $(LINK2 ../element/color.html, list) or a web style hex color. 949 * 950 * Params: 951 * coords = The coordinates of the outer elipse. 952 * style = The style of arc. 953 * fillColor = The fill color. 954 * outlineColor = The outline color. 955 * outlineWidth = The outline width. 956 * 957 * See_Also: 958 * $(LINK2 ../element/color.html, tkd.widget.color) $(BR) 959 * $(LINK2 ./canvas.html#CanvasArcStyle, tkd.widget.canvas.CanvasArcStyle) 960 */ 961 public this(double[] coords, string style = CanvasArcStyle.pie, string fillColor = Color.default_, string outlineColor = Color.black, int outlineWidth = 1) 962 { 963 assert(coords.length == 4, "Four coordinates are needed to draw an arc."); 964 965 this._type = "arc"; 966 this._coords = coords; 967 this._style = style; 968 this._fillColor = fillColor; 969 this._outlineColor = outlineColor; 970 this._outlineWidth = outlineWidth; 971 } 972 973 /* 974 * Initialise the item. 975 * 976 * Params: 977 * parent = The parent canvas to initialise against. 978 */ 979 override protected void init(Canvas parent) 980 { 981 super.init(parent); 982 983 this.setActiveFillColor(this._activeFillColor); 984 this.setActiveOutlineColor(this._activeOutlineColor); 985 this.setActiveOutlineDash(this._activeOutlineDash); 986 this.setActiveOutlineWidth(this._activeOutlineWidth); 987 this.setDisabledFillColor(this._disabledFillColor); 988 this.setDisabledOutlineColor(this._disabledOutlineColor); 989 this.setDisabledOutlineDash(this._disabledOutlineDash); 990 this.setDisabledOutlineWidth(this._disabledOutlineWidth); 991 this.setExtent(this._extent); 992 this.setFillColor(this._fillColor); 993 this.setOutlineColor(this._outlineColor); 994 this.setOutlineDash(this._outlineDash); 995 this.setOutlineDashOffset(this._outlineDashOffset); 996 this.setOutlineWidth(this._outlineWidth); 997 this.setStartAngle(this._startAngle); 998 this.setStyle(this._style); 999 } 1000 1001 /** 1002 * Mixin common commands. 1003 */ 1004 mixin ArcSpecific; 1005 mixin FillColor; 1006 mixin OutlineColor; 1007 mixin OutlineDash; 1008 mixin OutlineWidth; 1009 } 1010 1011 /** 1012 * Styles of arcs 1013 */ 1014 enum CanvasArcStyle : string 1015 { 1016 arc = "arc", /// Arc is drawn as an arc only. 1017 chord = "chord", /// Arc is drawn as a chord. 1018 pie = "pieslice", /// Arc is drawn as a pie chart. 1019 } 1020 1021 /** 1022 * An canvas image item. 1023 * 1024 * Common_Commands: 1025 * These are injected common commands that can also be used with this canvas item. 1026 * $(P 1027 * $(LINK2 ./common/canvas/anchor.html, Anchor) $(BR) 1028 * $(LINK2 ./common/canvas/imagespecific.html, ImageSpecific) $(BR) 1029 * ) 1030 * 1031 * See_Also: 1032 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 1033 */ 1034 class CanvasImage : CanvasItem 1035 { 1036 /** 1037 * Create an image. 1038 * 1039 * Params: 1040 * coords = The coordinates where to position the image. 1041 * image = The image to draw. 1042 * anchor = The anchor position of the image. 1043 * 1044 * See_Also: 1045 * $(LINK2 ../image/gif.html, tkd.image.gif) $(BR) 1046 * $(LINK2 ../image/image.html, tkd.image.image) $(BR) 1047 * $(LINK2 ../image/png.html, tkd.image.png) $(BR) 1048 * $(LINK2 ./anchorposition.html, tkd.widget.anchorposition) $(BR) 1049 */ 1050 public this(double[] coords, Image image, string anchor = AnchorPosition.northWest) 1051 { 1052 assert(coords.length == 2, "Two coordinates are needed to position an image."); 1053 1054 this._type = "image"; 1055 this._coords = coords; 1056 this._image = image; 1057 this._anchor = anchor; 1058 } 1059 1060 /* 1061 * Initialise the item. 1062 * 1063 * Params: 1064 * parent = The parent canvas to initialise against. 1065 */ 1066 override protected void init(Canvas parent) 1067 { 1068 super.init(parent); 1069 1070 this.setAnchor(this._anchor); 1071 this.setImage(this._image); 1072 this.setActiveImage(this._activeImage); 1073 this.setDisabledImage(this._disabledImage); 1074 } 1075 1076 /** 1077 * Mixin common commands. 1078 */ 1079 mixin Anchor; 1080 mixin ImageSpecific; 1081 } 1082 1083 /** 1084 * A canvas line item. 1085 * 1086 * Common_Commands: 1087 * These are injected common commands that can also be used with this canvas item. 1088 * $(P 1089 * $(LINK2 ./common/canvas/fillcolor.html, FillColor) $(BR) 1090 * $(LINK2 ./common/canvas/linespecific.html, LineSpecific) $(BR) 1091 * $(LINK2 ./common/canvas/outlinedash.html, OutlineDash) $(BR) 1092 * $(LINK2 ./common/canvas/outlinewidth.html, OutlineWidth) $(BR) 1093 * $(LINK2 ./common/canvas/vertex.html, Vertex) $(BR) 1094 * ) 1095 * 1096 * See_Also: 1097 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 1098 */ 1099 class CanvasLine : CanvasItem 1100 { 1101 /** 1102 * Create a line from coordinates. 1103 * Use colors from the preset color $(LINK2 ../element/color.html, list) or a web style hex color. 1104 * 1105 * Params: 1106 * coords = The coordinates where to draw the line. 1107 * fillColor = The color of the line. 1108 * outlineWidth = The outline width. 1109 * 1110 * See_Also: 1111 * $(LINK2 ../element/color.html, tkd.widget.color) $(BR) 1112 */ 1113 public this(double[] coords, string fillColor = Color.black, int outlineWidth = 1) 1114 { 1115 assert(coords.length >= 4, "Four or more coordinates are needed to draw a line."); 1116 1117 this._type = "line"; 1118 this._coords = coords; 1119 this._fillColor = fillColor; 1120 this._outlineWidth = outlineWidth; 1121 } 1122 1123 /* 1124 * Initialise the item. 1125 * 1126 * Params: 1127 * parent = The parent canvas to initialise against. 1128 */ 1129 override protected void init(Canvas parent) 1130 { 1131 super.init(parent); 1132 1133 this.setActiveFillColor(this._activeFillColor); 1134 this.setActiveOutlineDash(this._activeOutlineDash); 1135 this.setActiveOutlineWidth(this._activeOutlineWidth); 1136 this.setArrowPosition(this._arrowPosition); 1137 this.setArrowShape(this._arrowShape); 1138 this.setCapStyle(this._capStyle); 1139 this.setDisabledFillColor(this._disabledFillColor); 1140 this.setDisabledOutlineDash(this._disabledOutlineDash); 1141 this.setDisabledOutlineWidth(this._disabledOutlineWidth); 1142 this.setFillColor(this._fillColor); 1143 this.setJoinStyle(this._joinStyle); 1144 this.setOutlineDash(this._outlineDash); 1145 this.setOutlineDashOffset(this._outlineDashOffset); 1146 this.setOutlineWidth(this._outlineWidth); 1147 this.setSmoothMethod(this._smoothMethod); 1148 this.setSmoothSplineSteps(this._splineSteps); 1149 } 1150 1151 /** 1152 * Mixin common commands. 1153 */ 1154 mixin FillColor; 1155 mixin LineSpecific; 1156 mixin OutlineDash; 1157 mixin OutlineWidth; 1158 mixin Vertex; 1159 } 1160 1161 /** 1162 * Arrow positions on a canvas line. 1163 */ 1164 enum CanvasLineArrow : string 1165 { 1166 none = "none", /// No arrows. 1167 first = "first", /// Arrows on the first coordinate. 1168 last = "last", /// Arrow on the last coordinate. 1169 both = "both", /// Arrows on both ends. 1170 } 1171 1172 /** 1173 * The cap styles of a canvas line. 1174 */ 1175 enum CanvasLineCapStyle : string 1176 { 1177 butt = "butt", /// The cap is just a butt. 1178 projecting = "projecting", /// The cap projects beyond the line. 1179 round = "round", /// The cap is rounded. 1180 } 1181 1182 /** 1183 * The join styles of a canvas line. 1184 */ 1185 enum CanvasLineJoinStyle : string 1186 { 1187 bevel = "bevel", /// The join is bevelled. 1188 mitre = "miter", /// The join is mitred. 1189 round = "round", /// The join is round. 1190 } 1191 1192 /** 1193 * The join styles of a canvas line. 1194 */ 1195 enum CanvasLineSmoothMethod : string 1196 { 1197 none = "", /// No smoothing. 1198 bezier = "bezier", /// Draw the line using the bezier smooth method. 1199 raw = "raw", /// Draw the line using the raw smooth method. 1200 } 1201 1202 /** 1203 * A canvas rectangle item. 1204 * 1205 * Common_Commands: 1206 * These are injected common commands that can also be used with this canvas item. 1207 * $(P 1208 * $(LINK2 ./common/canvas/fillcolor.html, FillColor) $(BR) 1209 * $(LINK2 ./common/canvas/outlinecolor.html, OutlineColor) $(BR) 1210 * $(LINK2 ./common/canvas/outlinedash.html, OutlineDash) $(BR) 1211 * $(LINK2 ./common/canvas/outlinewidth.html, OutlineWidth) $(BR) 1212 * ) 1213 * 1214 * See_Also: 1215 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 1216 */ 1217 class CanvasRectangle : CanvasItem 1218 { 1219 /** 1220 * Create a rectangle from four coordinates. 1221 * Use colors from the preset color $(LINK2 ../../color.html, list) or a web style hex color. 1222 * 1223 * Params: 1224 * coords = The coordinates where to draw the rectangle. 1225 * fillColor = The fill color. 1226 * outlineColor = The outline color. 1227 * outlineWidth = The outline width. 1228 * 1229 * See_Also: 1230 * $(LINK2 ../element/color.html, tkd.widget.color) $(BR) 1231 */ 1232 public this(double[] coords, string fillColor = Color.default_, string outlineColor = Color.black, int outlineWidth = 1) 1233 { 1234 assert(coords.length == 4, "Four coordinates are needed to draw a rectangle."); 1235 1236 this._type = "rectangle"; 1237 this._coords = coords; 1238 this._fillColor = fillColor; 1239 this._outlineColor = outlineColor; 1240 this._outlineWidth = outlineWidth; 1241 } 1242 1243 /* 1244 * Initialise the item. 1245 * 1246 * Params: 1247 * parent = The parent canvas to initialise against. 1248 */ 1249 override protected void init(Canvas parent) 1250 { 1251 super.init(parent); 1252 1253 this.setActiveFillColor(this._activeFillColor); 1254 this.setActiveOutlineColor(this._activeOutlineColor); 1255 this.setActiveOutlineDash(this._activeOutlineDash); 1256 this.setActiveOutlineWidth(this._activeOutlineWidth); 1257 this.setDisabledFillColor(this._disabledFillColor); 1258 this.setDisabledOutlineColor(this._disabledOutlineColor); 1259 this.setDisabledOutlineDash(this._disabledOutlineDash); 1260 this.setDisabledOutlineWidth(this._disabledOutlineWidth); 1261 this.setFillColor(this._fillColor); 1262 this.setOutlineColor(this._outlineColor); 1263 this.setOutlineDash(this._outlineDash); 1264 this.setOutlineDashOffset(this._outlineDashOffset); 1265 this.setOutlineWidth(this._outlineWidth); 1266 } 1267 1268 /** 1269 * Mixin common commands. 1270 */ 1271 mixin FillColor; 1272 mixin OutlineColor; 1273 mixin OutlineDash; 1274 mixin OutlineWidth; 1275 } 1276 1277 /** 1278 * A canvas oval item. 1279 * 1280 * Common_Commands: 1281 * These are injected common commands that can also be used with this canvas item. 1282 * $(P 1283 * $(LINK2 ./common/canvas/fillcolor.html, FillColor) $(BR) 1284 * $(LINK2 ./common/canvas/outlinecolor.html, OutlineColor) $(BR) 1285 * $(LINK2 ./common/canvas/outlinedash.html, OutlineDash) $(BR) 1286 * $(LINK2 ./common/canvas/outlinewidth.html, OutlineWidth) $(BR) 1287 * ) 1288 * 1289 * See_Also: 1290 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 1291 */ 1292 class CanvasOval : CanvasItem 1293 { 1294 /** 1295 * Create an oval from four coordinates. 1296 * Use colors from the preset color $(LINK2 ../element/color.html, list) or a web style hex color. 1297 * 1298 * Params: 1299 * coords = The coordinates where to draw the oval. 1300 * fillColor = The fill color. 1301 * outlineColor = The outline color. 1302 * outlineWidth = The outline width. 1303 * 1304 * See_Also: 1305 * $(LINK2 ../element/color.html, tkd.widget.color) $(BR) 1306 */ 1307 public this(double[] coords, string fillColor = Color.default_, string outlineColor = Color.black, int outlineWidth = 1) 1308 { 1309 assert(coords.length == 4, "Four coordinates are needed to draw an oval."); 1310 1311 this._type = "oval"; 1312 this._coords = coords; 1313 this._fillColor = fillColor; 1314 this._outlineColor = outlineColor; 1315 this._outlineWidth = outlineWidth; 1316 } 1317 1318 /* 1319 * Initialise the item. 1320 * 1321 * Params: 1322 * parent = The parent canvas to initialise against. 1323 */ 1324 override protected void init(Canvas parent) 1325 { 1326 super.init(parent); 1327 1328 this.setActiveFillColor(this._activeFillColor); 1329 this.setActiveOutlineColor(this._activeOutlineColor); 1330 this.setActiveOutlineDash(this._activeOutlineDash); 1331 this.setActiveOutlineWidth(this._activeOutlineWidth); 1332 this.setDisabledFillColor(this._disabledFillColor); 1333 this.setDisabledOutlineColor(this._disabledOutlineColor); 1334 this.setDisabledOutlineDash(this._disabledOutlineDash); 1335 this.setDisabledOutlineWidth(this._disabledOutlineWidth); 1336 this.setFillColor(this._fillColor); 1337 this.setOutlineColor(this._outlineColor); 1338 this.setOutlineDash(this._outlineDash); 1339 this.setOutlineDashOffset(this._outlineDashOffset); 1340 this.setOutlineWidth(this._outlineWidth); 1341 } 1342 1343 /** 1344 * Mixin common commands. 1345 */ 1346 mixin FillColor; 1347 mixin OutlineColor; 1348 mixin OutlineDash; 1349 mixin OutlineWidth; 1350 } 1351 1352 /** 1353 * A canvas polygon item. 1354 * 1355 * Common_Commands: 1356 * These are injected common commands that can also be used with this canvas item. 1357 * $(P 1358 * $(LINK2 ./common/canvas/fillcolor.html, FillColor) $(BR) 1359 * $(LINK2 ./common/canvas/outlinecolor.html, OutlineColor) $(BR) 1360 * $(LINK2 ./common/canvas/outlinedash.html, OutlineDash) $(BR) 1361 * $(LINK2 ./common/canvas/outlinewidth.html, OutlineWidth) $(BR) 1362 * $(LINK2 ./common/canvas/vertex.html, Vertex) $(BR) 1363 * ) 1364 * 1365 * See_Also: 1366 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 1367 */ 1368 class CanvasPolygon : CanvasItem 1369 { 1370 /** 1371 * Create a polygon from coordinates. 1372 * Use colors from the preset color $(LINK2 ../element/color.html, list) or a web style hex color. 1373 * 1374 * Params: 1375 * coords = The coordinates where to draw the polygon. 1376 * fillColor = The fill color. 1377 * outlineColor = The outline color. 1378 * outlineWidth = The outline width. 1379 * 1380 * See_Also: 1381 * $(LINK2 ../element/color.html, tkd.widget.color) $(BR) 1382 */ 1383 public this(double[] coords, string fillColor = Color.default_, string outlineColor = Color.black, int outlineWidth = 1) 1384 { 1385 assert(coords.length >= 3, "Three or more coordinates are needed to draw a polygon."); 1386 1387 this._type = "polygon"; 1388 this._coords = coords; 1389 this._fillColor = fillColor; 1390 this._outlineColor = outlineColor; 1391 this._outlineWidth = outlineWidth; 1392 } 1393 1394 /* 1395 * Initialise the item. 1396 * 1397 * Params: 1398 * parent = The parent canvas to initialise against. 1399 */ 1400 override protected void init(Canvas parent) 1401 { 1402 super.init(parent); 1403 1404 this.setActiveFillColor(this._activeFillColor); 1405 this.setActiveOutlineColor(this._activeOutlineColor); 1406 this.setActiveOutlineDash(this._activeOutlineDash); 1407 this.setActiveOutlineWidth(this._activeOutlineWidth); 1408 this.setDisabledFillColor(this._disabledFillColor); 1409 this.setDisabledOutlineColor(this._disabledOutlineColor); 1410 this.setDisabledOutlineDash(this._disabledOutlineDash); 1411 this.setDisabledOutlineWidth(this._disabledOutlineWidth); 1412 this.setFillColor(this._fillColor); 1413 this.setJoinStyle(this._joinStyle); 1414 this.setOutlineColor(this._outlineColor); 1415 this.setOutlineDash(this._outlineDash); 1416 this.setOutlineDashOffset(this._outlineDashOffset); 1417 this.setOutlineWidth(this._outlineWidth); 1418 this.setSmoothMethod(this._smoothMethod); 1419 this.setSmoothSplineSteps(this._splineSteps); 1420 } 1421 1422 /** 1423 * Mixin common commands. 1424 */ 1425 mixin FillColor; 1426 mixin OutlineColor; 1427 mixin OutlineDash; 1428 mixin OutlineWidth; 1429 mixin Vertex; 1430 } 1431 1432 /** 1433 * A canvas text item. 1434 * 1435 * Common_Commands: 1436 * These are injected common commands that can also be used with this canvas item. 1437 * $(P 1438 * $(LINK2 ./common/canvas/anchor.html, Anchor) $(BR) 1439 * $(LINK2 ./common/canvas/fillcolor.html, FillColor) $(BR) 1440 * $(LINK2 ./common/canvas/textspecific.html, TextSpecific) $(BR) 1441 * ) 1442 * 1443 * See_Also: 1444 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 1445 */ 1446 class CanvasText : CanvasItem 1447 { 1448 /** 1449 * Create a text item. 1450 * Use colors from the preset color $(LINK2 ../element/color.html, list) or a web style hex color. 1451 * 1452 * Params: 1453 * coords = The coordinates where to draw the polygon. 1454 * text = The text. 1455 * fillColor = The fill color. 1456 * anchor = The anchor position of the image. 1457 * 1458 * See_Also: 1459 * $(LINK2 ../element/color.html, tkd.widget.color) $(BR) 1460 */ 1461 public this(double[] coords, string text, string fillColor = Color.default_, string anchor = AnchorPosition.northWest) 1462 { 1463 assert(coords.length == 2, "Two coordinates are needed to position text."); 1464 1465 this._type = "text"; 1466 this._coords = coords; 1467 this._text = text; 1468 this._fillColor = fillColor; 1469 this._anchor = anchor; 1470 } 1471 1472 /* 1473 * Initialise the item. 1474 * 1475 * Params: 1476 * parent = The parent canvas to initialise against. 1477 */ 1478 override protected void init(Canvas parent) 1479 { 1480 super.init(parent); 1481 1482 this.setActiveFillColor(this._activeFillColor); 1483 this.setAlignment(this._alignment); 1484 this.setAnchor(this._anchor); 1485 this.setAngle(this._angle); 1486 this.setDisabledFillColor(this._disabledFillColor); 1487 this.setFillColor(this._fillColor); 1488 this.setFont(this._font); 1489 this.setMaxLineLength(this._maxLineLength); 1490 this.setText(this._text); 1491 } 1492 1493 /** 1494 * Mixin common commands. 1495 */ 1496 mixin Anchor; 1497 mixin FillColor; 1498 mixin TextSpecific; 1499 } 1500 1501 /** 1502 * A canvas widget item. 1503 * 1504 * Common_Commands: 1505 * These are injected common commands that can also be used with this canvas item. 1506 * $(P 1507 * $(LINK2 ./common/canvas/anchor.html, Anchor) $(BR) 1508 * $(LINK2 ./common/canvas/widgetspecific.html, WidgetSpecific) $(BR) 1509 * ) 1510 * 1511 * See_Also: 1512 * $(LINK2 ./canvas.html#CanvasItem, tkd.widget.canvas.CanvasItem) 1513 */ 1514 class CanvasWidget : CanvasItem 1515 { 1516 /** 1517 * Create a widget item. 1518 * 1519 * Params: 1520 * coords = The coordinates where to draw the polygon. 1521 * widget = The widget to use. 1522 * anchor = The anchor position of the image. 1523 */ 1524 public this(double[] coords, Widget widget, string anchor = AnchorPosition.northWest) 1525 { 1526 assert(coords.length == 2, "Two coordinates are needed to position a widget."); 1527 1528 this._type = "window"; 1529 this._coords = coords; 1530 this._widget = widget; 1531 this._anchor = anchor; 1532 } 1533 1534 /* 1535 * Initialise the item. 1536 * 1537 * Params: 1538 * parent = The parent canvas to initialise against. 1539 */ 1540 override protected void init(Canvas parent) 1541 { 1542 super.init(parent); 1543 1544 this.setAnchor(this._anchor); 1545 this.setHeight(this._height); 1546 this.setWidget(this._widget); 1547 this.setWidth(this._width); 1548 } 1549 1550 /** 1551 * Mixin common commands. 1552 */ 1553 mixin Anchor; 1554 mixin WidgetSpecific; 1555 }