1 /// 2 module fluid.label; 3 4 import fluid.node; 5 import fluid.text; 6 import fluid.utils; 7 import fluid.style; 8 import fluid.backend; 9 10 @safe: 11 12 /// A label can be used to display text on the screen. 13 alias label = simpleConstructor!Label; 14 15 /// ditto 16 class Label : Node { 17 18 public { 19 20 /// Text of this label. 21 Text text; 22 23 alias value = text; 24 25 /// If true, the content of the label should not be wrapped into new lines if it's too long to fit into one. 26 bool isWrapDisabled; 27 28 } 29 30 this(Rope text) { 31 32 this.text = Text(this, text); 33 34 } 35 36 this(const(char)[] text) { 37 38 this.text = Text(this, text); 39 40 } 41 42 /// Set wrap on for this node. 43 This disableWrap(this This = Label)() return { 44 45 isWrapDisabled = true; 46 return cast(This) this; 47 48 } 49 50 /// Set wrap off for this node 51 This enableWrap(this This = Label)() return { 52 53 isWrapDisabled = false; 54 return cast(This) this; 55 56 } 57 58 bool isEmpty() const { 59 60 return text.length == 0; 61 62 } 63 64 protected override void resizeImpl(Vector2 available) { 65 66 import std.math; 67 68 text.resize(available, !isWrapDisabled); 69 minSize = text.size; 70 71 } 72 73 protected override void drawImpl(Rectangle outer, Rectangle inner) { 74 75 const style = pickStyle(); 76 style.drawBackground(tree.io, outer); 77 text.draw(style, inner.start); 78 79 } 80 81 unittest { 82 83 auto io = new HeadlessBackend; 84 auto root = label("Hello, World!"); 85 86 with (Rule) 87 root.theme = nullTheme.derive( 88 rule!Label(textColor = color!"000"), 89 ); 90 root.io = io; 91 root.draw(); 92 93 const initialTextArea = root.text.size.x * root.text.size.y; 94 95 io.assertTexture(root.text.texture.chunks[0], Vector2(0, 0), color!"fff"); 96 io.nextFrame; 97 98 root.text ~= " It's a nice day today!"; 99 root.draw(); 100 101 io.assertTexture(root.text.texture.chunks[0], Vector2(0, 0), color!"fff"); 102 103 const newTextArea = root.text.size.x * root.text.size.y; 104 105 assert(newTextArea > initialTextArea); 106 107 } 108 109 override string toString() const { 110 111 import std.range; 112 import std.format; 113 114 return format!"Label(%(%s%))"(only(text.toString)); 115 116 } 117 118 } 119 120 /// 121 unittest { 122 123 // Label takes just a single argument: the text to display 124 auto myLabel = label("Hello, World!"); 125 126 // You can access and change label text 127 myLabel.text ~= " It's a nice day today!"; 128 129 // Text will automatically wrap if it's too long to fit, but you can toggle it off 130 myLabel.isWrapDisabled = true; 131 132 }