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 /// 14 /// Styles: $(UL 15 /// $(LI `style` = Default style for this node.) 16 /// ) 17 alias label = simpleConstructor!Label; 18 19 /// ditto 20 class Label : Node { 21 22 mixin DefineStyles; 23 mixin ImplHoveredRect; 24 25 public { 26 27 /// Text of this label. 28 Text!Label text; 29 30 /// If true, the content of the label should not be wrapped into new lines if it's too long to fit into one. 31 bool isWrapDisabled; 32 33 } 34 35 deprecated("Use this(NodeParams, string text) instead.") { 36 37 static foreach (index; 0 .. BasicNodeParamLength) { 38 39 /// Initialize the label with given text. 40 this(BasicNodeParam!index sup, string text = "") { 41 42 super(sup); 43 this.text = Text!Label(this, text); 44 45 } 46 47 } 48 49 } 50 51 this(NodeParams params, string text) { 52 53 super(params); 54 this.text = Text!Label(this, text); 55 56 } 57 58 deprecated("`text` is now a required parameter for label — please adjust before 0.7.0.") 59 this(NodeParams params) { 60 61 super(params); 62 this.text = Text!Label(this, text); 63 64 } 65 66 /// Set wrap on for this node. 67 This disableWrap(this This = Label)() return { 68 69 isWrapDisabled = true; 70 return cast(This) this; 71 72 } 73 74 /// Set wrap off for this node 75 This enableWrap(this This = Label)() return { 76 77 isWrapDisabled = false; 78 return cast(This) this; 79 80 } 81 82 protected override void resizeImpl(Vector2 available) { 83 84 import std.math; 85 86 text.resize(available, !isWrapDisabled); 87 minSize = text.size; 88 89 } 90 91 protected override void drawImpl(Rectangle outer, Rectangle inner) { 92 93 const style = pickStyle(); 94 style.drawBackground(tree.io, outer); 95 text.draw(style, inner); 96 97 } 98 99 override inout(Style) pickStyle() inout { 100 101 return style; 102 103 } 104 105 unittest { 106 107 auto io = new HeadlessBackend; 108 auto root = label("Hello, World!"); 109 110 root.theme = nullTheme.makeTheme!q{ 111 Label.styleAdd.textColor = color!"000"; 112 }; 113 root.io = io; 114 root.draw(); 115 116 const initialTextArea = root.text.size.x * root.text.size.y; 117 118 io.assertTexture(root.text.texture, Vector2(0, 0), color!"000"); 119 io.nextFrame; 120 121 root.text ~= " It's a nice day today!"; 122 root.draw(); 123 124 io.assertTexture(root.text.texture, Vector2(0, 0), color!"000"); 125 126 const newTextArea = root.text.size.x * root.text.size.y; 127 128 assert(newTextArea > initialTextArea); 129 130 } 131 132 } 133 134 /// 135 unittest { 136 137 // Label takes just a single argument: the text to display 138 auto myLabel = label("Hello, World!"); 139 140 // You can access and change label text 141 myLabel.text ~= " It's a nice day today!"; 142 143 // Text will automatically wrap if it's too long to fit, but you can toggle it off 144 myLabel.isWrapDisabled = true; 145 146 }