1 /**
2  * Clipboard demo for Dcell.
3  *
4  * Copyright: Copyright 2025 Garrett D'Amore
5  * Authors: Garrett D'Amore
6  * License:
7  *   Distributed under the Boost Software License, Version 1.0.
8  *   (See accompanying file LICENSE or https://www.boost.org/LICENSE_1_0.txt)
9  *   SPDX-License-Identifier: BSL-1.0
10  */
11 module clipboard;
12 
13 import std.stdio;
14 import std.string;
15 import std.conv;
16 import std.utf;
17 
18 import dcell;
19 
20 class Demo
21 {
22     string content;
23     Screen s;
24     bool done = false;
25 
26     this(Screen scr) @safe
27     {
28         s = scr;
29     }
30 
31     void centerStr(int y, Style style, string str) @safe
32     {
33         s.style = style;
34         s.position = Coord((s.size.x - cast(int)(str.length)) / 2, y);
35         s.write(str);
36     }
37 
38     void display() @safe
39     {
40         auto size = s.size();
41         Style def;
42         def.bg = Color.black;
43         def.fg = Color.white;
44         s.clear();
45         Style style = {fg: Color.cadetBlue, bg: Color.black};
46         s.style = style;
47         centerStr(size.y / 2 - 1, style, "Press 1 to set the clipboard");
48         centerStr(size.y / 2 + 1, style, "Press 2 to get the clipboard");
49 
50         auto msg = "No clipboard data";
51         if (!content.empty)
52         {
53             auto len = content.length;
54             if (content.length >= 40)
55             {
56                 msg = format("Clipboard (length %d): %s ...", len, content[0 .. 36]);
57             }
58             else
59             {
60                 msg = format("Clipboard (length %d): %s", len, content);
61             }
62         }
63         s.style = def;
64         centerStr(size.y / 2 + 3, def, msg);
65         centerStr(size.y / 2 + 5, def, "Press ESC to Exit.");
66 
67         s.show();
68     }
69 
70     void handleEvent(Event ev)
71     {
72         switch (ev.type)
73         {
74         case EventType.key:
75             if (ev.key.key == Key.esc || ev.key.key == Key.f1)
76             {
77                 done = true;
78             }
79             else if (ev.key.key == Key.graph && ev.key.mod == Modifiers.none)
80             {
81                 switch (ev.key.ch)
82                 {
83                 case '1':
84                     s.setClipboard("Enjoy your new clipboard content!".representation);
85                     break;
86                 case '2':
87                     s.getClipboard();
88                     break;
89                 default:
90                 }
91             }
92 
93             break;
94         case EventType.paste:
95             if (ev.paste.content.length > 0)
96             {
97                 content = ev.paste.content;
98             }
99             else if (ev.paste.binary.length > 0)
100             {
101                 try
102                 {
103                     auto chars = cast(char[])(ev.paste.binary);
104                     validate(chars);
105                     content = cast(string)(chars.idup);
106                 }
107                 catch (UTFException)
108                 {
109                     content = "Invalid UTF-8";
110                 }
111             }
112             break;
113         case EventType.resize:
114             s.resize();
115             display();
116             s.sync();
117             break;
118         default:
119             break;
120         }
121     }
122 
123     void run()
124     {
125         s.start();
126         scope (exit)
127         {
128             s.stop();
129         }
130 
131         display();
132         s.enablePaste(true);
133         while (!done)
134         {
135             s.waitForEvent();
136             foreach (ev; s.events())
137             {
138                 handleEvent(ev);
139             }
140             display();
141         }
142 
143     }
144 }
145 
146 void main()
147 {
148     auto app = new Demo(newScreen());
149     app.run();
150 }