1 /// Basic implementation of clipboard I/O without communicating with the system. Exchanges clipboard data 2 /// only between nodes with access, and does not transfer them to other apps. 3 module fluid.clipboard_chain; 4 5 import fluid.node; 6 import fluid.types; 7 import fluid.utils; 8 import fluid.node_chain; 9 10 import fluid.io.clipboard; 11 12 @safe: 13 14 alias clipboardChain = nodeBuilder!ClipboardChain; 15 16 /// Local clipboard provider. Makes it possible to copy and paste text between nodes in the same branch. 17 /// 18 /// `ClipboardChain` does not communicate with the system, so the clipboard will *not* be accessible to other apps. 19 /// This makes this node suitable for testing. 20 class ClipboardChain : NodeChain, ClipboardIO { 21 22 mixin controlIO; 23 24 private { 25 string _value; 26 } 27 28 this(Node next = null) { 29 super(next); 30 } 31 32 /// Returns: 33 /// Current clipboard content. 34 string value() const { 35 return _value; 36 } 37 38 /// Replace the clipboard contents. 39 /// Params: 40 /// newValue = New clipboard content. 41 /// Returns: 42 /// Same text as passed into the function. 43 string value(string newValue) { 44 return _value = newValue; 45 } 46 47 override void beforeResize(Vector2) { 48 startIO(); 49 } 50 51 override void afterResize(Vector2) { 52 stopIO(); 53 } 54 55 override bool writeClipboard(string text) { 56 _value = text; 57 return true; 58 } 59 60 char[] readClipboard(return scope char[] buffer, ref int offset) nothrow { 61 62 import std.algorithm : min; 63 64 // Read the entire text, nothing remains to be read 65 if (offset >= _value.length) return null; 66 67 // Get remaining text 68 const text = _value[offset .. $]; 69 const length = min(text.length, buffer.length); 70 71 offset += length; 72 return buffer[0 .. length] = text[0 .. length]; 73 74 } 75 76 } 77 78 /// 79 @("Example of basic ClipboardChain usage compiles and works") 80 unittest { 81 82 import fluid; 83 84 TextInput first, second; 85 86 // Children of a ClipboardChain will share the same clipboard 87 auto root = clipboardChain( 88 vspace( 89 first = textInput(), 90 second = textInput(), 91 ), 92 ); 93 root.draw(); 94 95 // Text copied by the first input... 96 first.value = "Hello!"; 97 first.selectAll(); 98 first.copy(); 99 100 // ... can now be pasted into the other 101 second.paste(); 102 assert(second.value == "Hello!"); 103 104 }