1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 | -- An Ada-oriented GUI library
-- Implementation derived from Gnoga
--
-- Copyright (C) 2022 by PragmAda Software Engineering
--
-- Released under the terms of the 3-Clause BSD License. See https://opensource.org/licenses/BSD-3-Clause
separate (Ada_GUI)
function Next_Event (Timeout : Duration := Duration'Last) return Next_Result_Info is
function Parse_Mouse_Event (Message : String) return Mouse_Event_Info is
use Ada.Strings.Fixed;
Event : Mouse_Event_Info;
S : Positive := Message'First;
F : Natural := Message'First - 1;
Button : Integer;
function Split return String;
function Split return Integer;
function Split return Boolean;
-- Split string and extract values
function Split return String is
begin
S := F + 1;
F := Index (Message, "|", From => S);
return Message (S .. F - 1);
end Split;
function Split return Integer is
S : constant String := Split;
begin
if Index (S, ".") > 0 then
return Integer (Float'Value (S) );
else
return Integer'Value (S);
end if;
exception
when E : others =>
Gnoga.Log (Message => "Error Parse_Mouse_Event converting " & S & " to Integer (forced to 0).");
Gnoga.Log (Message => Ada.Exceptions.Exception_Information (E));
return 0;
end Split;
function Split return Boolean is
begin
return Split = "true";
end Split;
Left_Button : constant := 1;
Middle_Button : constant := 2;
Right_Button : constant := 3;
begin
Event.X := Split;
Event.Y := Split;
Event.Screen_X := Split;
Event.Screen_Y := Split;
Button := Split;
Event.Left_Button := Button = Left_Button;
Event.Middle_Button := Button = Middle_Button;
Event.Right_Button := Button = Right_Button;
Event.Alt := Split;
Event.Control := Split;
Event.Shift := Split;
Event.Meta := Split;
return Event;
end Parse_Mouse_Event;
function Parse_Keyboard_Event (Message : String) return Keyboard_Event_Info is
use Ada.Strings.Fixed;
Event : Keyboard_Event_Info;
S : Integer := Message'First;
F : Integer := Message'First - 1;
function Split return String;
function Split return Integer;
function Split return Boolean;
function Split return Wide_Character;
function Split return String is
begin
S := F + 1;
F := Index (Message, "|", From => S);
return Message (S .. (F - 1));
end Split;
function Split return Integer is
S : constant String := Split;
begin
if Index (S, ".") > 0 then
return Integer (Float'Value (S));
else
return Integer'Value (S);
end if;
exception
when E : others =>
Gnoga.Log (Message => "Error Parse_Keyboard_Event converting " & S & " to Integer (forced to 0).");
Gnoga.Log (Message => Ada.Exceptions.Exception_Information (E));
return 0;
end Split;
function Split return Boolean is
begin
return Split = "true";
end Split;
function Split return Wide_Character is
begin
return Wide_Character'Val (Split);
end Split;
begin
Event.Key_Code := Split;
Event.Key_Char := Split;
Event.Alt := Split;
Event.Control := Split;
Event.Shift := Split;
Event.Meta := Split;
return Event;
end Parse_Keyboard_Event;
Resize_Text : constant String := "resize";
Left_Text : constant String := "click";
Right_Text : constant String := "contextmenu";
Double_Text : constant String := "dblclick";
Key_Text : constant String := "keypress";
Final_Time : Ada.Real_Time.Time;
Event : Gnoga.Gui.Event_Info;
use type Ada.Real_Time.Time;
begin -- Next_Event
Get_Final : begin
Final_Time := Ada.Real_Time.Clock + Ada.Real_Time.To_Time_Span (Timeout);
exception -- Get_Final
when others =>
Final_Time := Ada.Real_Time.Time_Last;
end Get_Final;
select
Dialog_Control.Block;
or
delay until Final_Time;
return (Timed_Out => True);
end select;
Skip_Invalid : loop
select
Gnoga.Gui.Event_Queue.Dequeue (Element => Event);
if Event.Event = Resize_Text and then Event.Object.all in Gnoga.Gui.Window.Window_Type then
Event.Object.Flush_Buffer;
Gnoga.Gui.Window.Window_Type (Event.Object.all).On_Resize;
Event.Object.Flush_Buffer;
elsif Event.Event = Left_Text or Event.Event = Right_Text or Event.Event = Double_Text or Event.Event = Key_Text then
Make_Event : declare
ID : constant String := Event.Object.ID;
Index : constant Natural := Ada.Strings.Fixed.Index (ID, "R"); -- R indicates a radio button
Local : Event_Info (Kind => (if Event.Event = Left_Text then Left_Click
elsif Event.Event = Right_Text then Right_Click
elsif Event.Event = Double_Text then Double_Click
else Key_Press) );
begin -- Make_Event
Local.ID := (Value => Integer'Value ( (if Index > 0 then ID (Index + 1 .. ID'Last) else ID) ) );
Local.Data := Event.Data;
if Local.Kind in Left_Click | Right_Click | Double_Click then
Local.Mouse := Parse_Mouse_Event (Ada.Strings.Unbounded.To_String (Event.Data) );
else
Local.Key := Parse_Keyboard_Event (Ada.Strings.Unbounded.To_String (Event.Data) );
end if;
return (Timed_Out => False, Event => Local);
exception -- Make_Event
when others => -- Event.Object.ID is not the image of an ID
null;
end Make_Event;
elsif Event.Event = Closed_Text then
return (Timed_Out => False, Event => (Kind => Window_Closed, others => <>) );
else
null; -- Ignore event
end if;
or
delay until Final_Time;
return (Timed_Out => True);
end select;
end loop Skip_Invalid;
end Next_Event;
|