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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373 | -- SPDX-License-Identifier: GPL-3.0-or-later
-- SPDX-FileCopyrightText: Copyright 2024 Stephen Merrony
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Containers; use Ada.Containers;
with Ada.Directories;
with Ada.Exceptions; use Ada.Exceptions;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Glib; use Glib;
with Gtk.About_Dialog; use Gtk.About_Dialog;
with Gtk.Box; use Gtk.Box;
with Gtk.Dialog; use Gtk.Dialog;
with Gtk.Menu; use Gtk.Menu;
with Gtk.Menu_Item; use Gtk.Menu_Item;
with Gtk.Separator_Menu_Item; use Gtk.Separator_Menu_Item;
with Gtk.Widget; use Gtk.Widget;
with Gtkada.Dialogs; use Gtkada.Dialogs;
with Gtkada.File_Selection; use Gtkada.File_Selection;
with Midi_Files;
-- with Players; use Players;
with Session; use Session;
with GUI.Tracks; use GUI.Tracks;
package body GUI.Menu is
function Check_Session_Desc return Boolean is
Unused_Buttons : Message_Dialog_Buttons;
begin
if Session_Desc_Entry.Get_Text /= "" then
return True;
else
Unused_Buttons := Message_Dialog (Msg => "You must enter the Session description, cannot save yet.",
Dialog_Type => Warning,
Title => App_Title & " - Warning");
return False;
end if;
end Check_Session_Desc;
procedure Session_New_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
Prev_MIDI_Port : constant Unbounded_String := Sess.MIDI_Port;
begin
Clear_Session;
Session_Desc_Entry.Set_Text ("");
Session_Comment_Entry.Set_Text ("");
Sess.MIDI_Port := Prev_MIDI_Port;
Track_Modifiers_Check_Item.Set_Active (True);
Clear_Tracks_Display;
Display_Empty_Track (1);
Tracks_Grid.Show_All;
Session_Desc_Entry.Grab_Focus;
end Session_New_CB;
procedure Session_Open_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
Filename : constant String :=
File_Selection_Dialog (Title => App_Title & " Open Session",
Dir_Only => False,
Must_Exist => True);
Unused_Buttons : Message_Dialog_Buttons;
begin
if Filename'Length > 1 then
Load_Session (Filename);
Sess.Filename := To_Unbounded_String (Filename);
Session_Desc_Entry.Set_Text (To_String (Sess.Desc));
Session_Comment_Entry.Set_Text (To_String (Sess.Comment));
if Sess.MIDI_Port /= Null_Unbounded_String then
Midi_Files.Create_Notes_Off_MIDI;
end if;
if Sess.Tracks.Length > 0 then
Display_Tracks;
end if;
GUI.Resize_Font (Font_Size'Value (To_String (Sess.Font_Size)));
end if;
exception
when E : others =>
Unused_Buttons := Message_Dialog (Msg => "Could not open Session TOML file. " & Exception_Message (E),
Dialog_Type => Warning,
Title => App_Title & " - Error");
Sess.Filename := Null_Unbounded_String;
end Session_Open_CB;
procedure Session_Save_As is
-- Helper proc for Save callbacks.
Filename : constant String :=
File_Selection_Dialog (Title => App_Title & " - Save Session As...",
Dir_Only => False,
Must_Exist => False);
Unused_Buttons : Message_Dialog_Buttons;
begin
if Check_Session_Desc then
if Filename'Length > 0 then
if Ada.Directories.Exists (Filename) then
Unused_Buttons := Message_Dialog (Msg => "Session TOML file already exists, " & CR & LF
& "Use 'Save' to overwrite.",
Dialog_Type => Warning,
Title => App_Title & " - Oops");
else
Save_Session (Filename);
end if;
end if;
end if;
end Session_Save_As;
procedure Session_Save_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
-- Save the current session, performs Save As... if not already saved.
pragma Unreferenced (Self);
Unused_Buttons : Message_Dialog_Buttons;
begin
if Check_Session_Desc then
if Sess.Filename = Null_Unbounded_String then
Session_Save_As;
else
Save_Session (To_String (Sess.Filename));
end if;
end if;
end Session_Save_CB;
procedure Session_Save_As_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
begin
Session_Save_As;
end Session_Save_As_CB;
procedure Session_Audio_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
Dialog : Gtk_Dialog;
Dlg_Box : Gtk_Box;
Dlg_Silence_Label : Gtk_Label;
Silence_Entry : Gtk_Entry;
Cancel_Unused,
Save_Unused : Gtk_Widget;
Unused_Buttons : Message_Dialog_Buttons;
begin
Gtk_New (Dialog);
Dialog.Set_Destroy_With_Parent (True);
Dialog.Set_Modal (True);
Dialog.Set_Title (App_Title & " - Session Audio Settings");
Dlg_Box := Dialog.Get_Content_Area;
Dlg_Silence_Label := Gtk_Label_New ("Lead-in Silence (seconds):");
Dlg_Box.Pack_Start (Child => Dlg_Silence_Label, Expand => True, Fill => True, Padding => 5);
Silence_Entry := Gtk_Entry_New;
Silence_Entry.Set_Text (Trim (Sess.Lead_In_Silence'Image, Left));
Silence_Entry.Set_Tooltip_Text ("Number of seconds silence to play before each audio track. " & CR & LF
& "Must be 0 or a positive integer.");
Dlg_Box.Pack_Start (Child => Silence_Entry, Expand => True, Fill => True, Padding => 5);
Cancel_Unused := Dialog.Add_Button ("Cancel", Gtk_Response_Cancel);
Save_Unused := Dialog.Add_Button ("Save", Gtk_Response_Accept);
Dialog.Set_Default_Response (Gtk_Response_Accept);
Dialog.Show_All;
if Dialog.Run = Gtk_Response_Accept then
if Silence_Entry.Get_Text_Length > 0 then
Sess.Lead_In_Silence := Integer'Value (Silence_Entry.Get_Text);
end if;
end if;
Dialog.Destroy;
end Session_Audio_CB;
procedure Session_MIDI_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
Dialog : Gtk_Dialog;
Dlg_Box : Gtk_Box;
Dlg_Port_Label : Gtk_Label;
Port_Entry : Gtk_Entry;
Cancel_Unused,
Save_Unused : Gtk_Widget;
Unused_Buttons : Message_Dialog_Buttons;
begin
Gtk_New (Dialog);
Dialog.Set_Destroy_With_Parent (True);
Dialog.Set_Modal (True);
Dialog.Set_Title (App_Title & " - Session MIDI Port");
Dlg_Box := Dialog.Get_Content_Area;
Dlg_Port_Label := Gtk_Label_New ("MIDI Out Port:");
Dlg_Box.Pack_Start (Child => Dlg_Port_Label, Expand => True, Fill => True, Padding => 5);
Port_Entry := Gtk_Entry_New;
if Sess.MIDI_Port /= Null_Unbounded_String then
Port_Entry.Set_Text (To_String (Sess.MIDI_Port));
end if;
Port_Entry.Set_Tooltip_Text ("MIDI port suitable for aplaymidi to use in form nn:n. " & CR & LF
& "Use aplaymidi -l to see list");
Dlg_Box.Pack_Start (Child => Port_Entry, Expand => True, Fill => True, Padding => 5);
Cancel_Unused := Dialog.Add_Button ("Cancel", Gtk_Response_Cancel);
Save_Unused := Dialog.Add_Button ("Save", Gtk_Response_Accept);
Dialog.Set_Default_Response (Gtk_Response_Accept);
Dialog.Show_All;
if Dialog.Run = Gtk_Response_Accept then
if Port_Entry.Get_Text_Length > 0 then
Sess.MIDI_Port := To_Unbounded_String (Port_Entry.Get_Text);
end if;
end if;
Dialog.Destroy;
end Session_MIDI_CB;
procedure Track_Modifiers_CB (Self : access Gtk_Check_Menu_Item_Record'Class) is
begin
Show_Track_Modifiers := Self.Get_Active;
Display_Tracks;
Main_Window.Resize (1, 1);
end Track_Modifiers_CB;
procedure About_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
Dialog : Gtk_About_Dialog;
Dummy_Response : Gtk_Response_Type;
begin
Gtk_New (Dialog);
Dialog.Set_Destroy_With_Parent (True);
Dialog.Set_Modal (True);
Dialog.Set_Logo (Icon_PB);
Dialog.Set_Authors ([new String'(App_Author)]);
Dialog.Set_Copyright (App_Copyright);
Dialog.Set_Comments (App_Comment);
Dialog.Set_Program_Name (App_Title);
Dialog.Set_Version (App_SemVer);
Dialog.Set_Website (App_Website);
Dummy_Response := Dialog.Run;
Dialog.Destroy;
end About_CB;
procedure Quit_CB (Self : access Gtk.Menu_Item.Gtk_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
begin
if Really_Quit then
-- Removing the main window closes the application...
App.Remove_Window (Main_Window);
end if;
end Quit_CB;
procedure View_Size_CB (Self : access Gtk_Check_Menu_Item_Record'Class) is
pragma Unreferenced (Self);
New_Size : Font_Size;
begin
if View_S_Radio_Item.Get_Active then
New_Size := S;
elsif View_M_Radio_Item.Get_Active then
New_Size := M;
elsif View_L_Radio_Item.Get_Active then
New_Size := L;
elsif View_XL_Radio_Item.Get_Active then
New_Size := XL;
elsif View_XXL_Radio_Item.Get_Active then
New_Size := XXL;
end if;
GUI.Resize_Font (New_Size);
end View_Size_CB;
function Create_Menu_Bar return Gtk_Menu_Bar is
Menu_Bar : Gtk_Menu_Bar;
Sep_Item : Gtk_Separator_Menu_Item;
File_Menu, View_Menu, Session_Menu, Help_Menu : Gtk_Menu;
Menu_Item : Gtk_Menu_Item;
Session_Open_Item, Session_Save_Item, Session_Save_As_Item, Session_New_Item,
Session_Audio_Item, Session_MIDI_Item,
Quit_Item : Gtk_Menu_Item;
Group : Widget_SList.GSlist;
About_Item : Gtk_Menu_Item;
begin
-- Log (DEBUG, "Starting to Create_Menu_Bar");
Gtk_New (Menu_Bar);
-- File
Gtk_New (Menu_Item, "File");
Menu_Bar.Append (Menu_Item);
Gtk_New (File_Menu);
Menu_Item.Set_Submenu (File_Menu);
-- Session New
Gtk_New (Session_New_Item, "New Session");
File_Menu.Append (Session_New_Item);
Session_New_Item.On_Activate (Session_New_CB'Access);
-- Session Open
Gtk_New (Session_Open_Item, "Open Session");
File_Menu.Append (Session_Open_Item);
Session_Open_Item.On_Activate (Session_Open_CB'Access);
Gtk_New (Sep_Item);
File_Menu.Append (Sep_Item);
-- Session Save
Gtk_New (Session_Save_Item, "Save Session");
File_Menu.Append (Session_Save_Item);
Session_Save_Item.On_Activate (Session_Save_CB'Access);
-- Session Save As
Gtk_New (Session_Save_As_Item, "Save Session As...");
File_Menu.Append (Session_Save_As_Item);
Session_Save_As_Item.On_Activate (Session_Save_As_CB'Access);
Gtk_New (Sep_Item);
File_Menu.Append (Sep_Item);
Gtk_New (Quit_Item, "Quit");
File_Menu.Append (Quit_Item);
Quit_Item.On_Activate (Quit_CB'Access);
-- View
Gtk_New (Menu_Item, "View");
Menu_Bar.Append (Menu_Item);
Gtk_New (View_Menu);
Menu_Item.Set_Submenu (View_Menu);
View_S_Radio_Item := Gtk_Radio_Menu_Item_New_With_Label (Widget_SList.Null_List, "Small");
View_Menu.Append (View_S_Radio_Item);
View_S_Radio_Item.On_Toggled (View_Size_CB'Access);
Group := Gtk.Radio_Menu_Item.Get_Group (View_S_Radio_Item);
View_M_Radio_Item := Gtk_Radio_Menu_Item_New_With_Label (Group, "Medium");
View_Menu.Append (View_M_Radio_Item);
View_M_Radio_Item.On_Toggled (View_Size_CB'Access);
View_M_Radio_Item.Set_Active (True);
View_L_Radio_Item := Gtk_Radio_Menu_Item_New_With_Label (Group, "Large");
View_Menu.Append (View_L_Radio_Item);
View_L_Radio_Item.On_Toggled (View_Size_CB'Access);
View_XL_Radio_Item := Gtk_Radio_Menu_Item_New_With_Label (Group, "X-Large");
View_Menu.Append (View_XL_Radio_Item);
View_XL_Radio_Item.On_Toggled (View_Size_CB'Access);
View_XXL_Radio_Item := Gtk_Radio_Menu_Item_New_With_Label (Group, "XX-Large");
View_Menu.Append (View_XXL_Radio_Item);
View_XXL_Radio_Item.On_Toggled (View_Size_CB'Access);
Gtk_New (Sep_Item);
View_Menu.Append (Sep_Item);
-- Modifiers visibility
Gtk_New (Track_Modifiers_Check_Item, "Track Editing");
Track_Modifiers_Check_Item.Set_Active (Show_Track_Modifiers);
View_Menu.Append (Track_Modifiers_Check_Item);
Track_Modifiers_Check_Item.On_Toggled (Track_Modifiers_CB'Access);
-- Session
Gtk_New (Menu_Item, "Session");
Menu_Bar.Append (Menu_Item);
Gtk_New (Session_Menu);
Menu_Item.Set_Submenu (Session_Menu);
-- Session Audio Settings
Gtk_New (Session_Audio_Item, "Audio Settings");
Session_Menu.Append (Session_Audio_Item);
Session_Audio_Item.On_Activate (Session_Audio_CB'Access);
-- Session MIDI Settings
Gtk_New (Session_MIDI_Item, "MIDI Settings");
Session_Menu.Append (Session_MIDI_Item);
Session_MIDI_Item.On_Activate (Session_MIDI_CB'Access);
-- Help
Gtk_New (Menu_Item, "Help");
Menu_Bar.Append (Menu_Item);
Gtk_New (Help_Menu);
Menu_Item.Set_Submenu (Help_Menu);
-- About
Gtk_New (About_Item, "About");
Help_Menu.Append (About_Item);
About_Item.On_Activate (About_CB'Access);
return Menu_Bar;
end Create_Menu_Bar;
end GUI.Menu;
|