1 /**
2  * Events module 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 dcell.event;
12 
13 import core.time;
14 import std.range;
15 
16 import dcell.key;
17 import dcell.mouse;
18 
19 enum EventType
20 {
21     none = 0,
22     closed, /// input queue is closed (no more events will be received)
23     error, /// an error condition
24     key, /// a keyboard press
25     mouse, /// a mouse event
26     paste, /// a paste event
27     resize, /// window was resized
28     focus, /// focus changed
29 }
30 
31 /**
32  * Event is the abstract from of an event.  We use structs because
33  * these will be sent by value over the message box.  Other event
34  * types should "derive" from this by using it as their first member
35  * and using alias this.
36  */
37 struct Event
38 {
39     EventType type;
40     MonoTime when;
41     union
42     {
43         MouseEvent mouse;
44         KeyEvent key;
45         ResizeEvent resize;
46         PasteEvent paste;
47         FocusEvent focus;
48     }
49 }
50 
51 /**
52  * Resize is fired when a window resize event has occurred.
53  * It is something the application should use to determine
54  * when it needs to update layouts, etc.
55  */
56 struct ResizeEvent
57 {
58 }
59 
60 /**
61  * Paste start or stop. Only one of the content or binary fields will have data.
62  */
63 struct PasteEvent
64 {
65     string content; /// string content for normal paste
66     ubyte[] binary; /// binary data via OSC 52 or similar
67 }
68 
69 /// Focus event.
70 struct FocusEvent
71 {
72     bool focused;
73 }
74 
75 /**
76  * EventQ is both an input and output range of Events that behaves as a FIFO.
77  * When adding to the output range it will wake up any reader using the
78  * delegate that was passed to it at construction.
79  */
80 class EventQ
81 {
82 
83     void put(Event ev) @safe nothrow
84     {
85         events ~= ev;
86     }
87 
88     final Event front() const nothrow pure @property @nogc @safe
89     {
90         return events.front;
91     }
92 
93     final bool empty() const nothrow pure @property @nogc @safe
94     {
95         return events.empty;
96     }
97 
98     final void popFront() nothrow pure @nogc @safe
99     {
100         events.popFront();
101     }
102 
103 private:
104     Event[] events;
105 }