1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2021 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <ags/X/ags_sheet_editor.h>
21 
22 #include <ags/i18n.h>
23 
24 void ags_sheet_editor_class_init(AgsSheetEditorClass *sheet_editor);
25 void ags_sheet_editor_connectable_interface_init(AgsConnectableInterface *connectable);
26 void ags_sheet_editor_init(AgsSheetEditor *sheet_editor);
27 void ags_sheet_editor_set_property(GObject *gobject,
28 				   guint prop_id,
29 				   const GValue *value,
30 				   GParamSpec *param_spec);
31 void ags_sheet_editor_get_property(GObject *gobject,
32 				   guint prop_id,
33 				   GValue *value,
34 				   GParamSpec *param_spec);
35 void ags_sheet_editor_connect(AgsConnectable *connectable);
36 void ags_sheet_editor_disconnect(AgsConnectable *connectable);
37 void ags_sheet_editor_finalize(GObject *gobject);
38 
39 void ags_sheet_editor_real_machine_changed(AgsSheetEditor *sheet_editor,
40 					   AgsMachine *machine);
41 
42 enum{
43   MACHINE_CHANGED,
44   LAST_SIGNAL,
45 };
46 
47 enum{
48   PROP_0,
49   PROP_SOUNDCARD,
50 };
51 
52 static gpointer ags_sheet_editor_parent_class = NULL;
53 static guint sheet_editor_signals[LAST_SIGNAL];
54 
55 /**
56  * SECTION:ags_sheet_editor
57  * @short_description: A composite widget to edit notation
58  * @title: AgsSheetEditor
59  * @section_id:
60  * @include: ags/X/ags_sheet_editor.h
61  *
62  * #AgsSheetEditor is a composite widget to edit notation. You may select machines
63  * or change sheet tool to do notation.
64  */
65 
66 GType
ags_sheet_editor_get_type(void)67 ags_sheet_editor_get_type(void)
68 {
69   static volatile gsize g_define_type_id__volatile = 0;
70 
71   if(g_once_init_enter (&g_define_type_id__volatile)){
72     GType ags_type_sheet_editor = 0;
73 
74     static const GTypeInfo ags_sheet_editor_info = {
75       sizeof (AgsSheetEditorClass),
76       NULL, /* base_init */
77       NULL, /* base_finalize */
78       (GClassInitFunc) ags_sheet_editor_class_init,
79       NULL, /* class_finalize */
80       NULL, /* class_data */
81       sizeof (AgsSheetEditor),
82       0,    /* n_preallocs */
83       (GInstanceInitFunc) ags_sheet_editor_init,
84     };
85 
86     static const GInterfaceInfo ags_connectable_interface_info = {
87       (GInterfaceInitFunc) ags_sheet_editor_connectable_interface_init,
88       NULL, /* interface_finalize */
89       NULL, /* interface_data */
90     };
91 
92     ags_type_sheet_editor = g_type_register_static(GTK_TYPE_BOX,
93 						   "AgsSheetEditor", &ags_sheet_editor_info,
94 						   0);
95 
96     g_type_add_interface_static(ags_type_sheet_editor,
97 				AGS_TYPE_CONNECTABLE,
98 				&ags_connectable_interface_info);
99 
100     g_once_init_leave(&g_define_type_id__volatile, ags_type_sheet_editor);
101   }
102 
103   return g_define_type_id__volatile;
104 }
105 
106 void
ags_sheet_editor_connectable_interface_init(AgsConnectableInterface * connectable)107 ags_sheet_editor_connectable_interface_init(AgsConnectableInterface *connectable)
108 {
109   connectable->is_ready = NULL;
110   connectable->is_connected = NULL;
111   connectable->connect = ags_sheet_editor_connect;
112   connectable->disconnect = ags_sheet_editor_disconnect;
113 }
114 
115 void
ags_sheet_editor_class_init(AgsSheetEditorClass * sheet_editor)116 ags_sheet_editor_class_init(AgsSheetEditorClass *sheet_editor)
117 {
118   GObjectClass *gobject;
119   GParamSpec *param_spec;
120 
121   ags_sheet_editor_parent_class = g_type_class_peek_parent(sheet_editor);
122 
123   /* GObjectClass */
124   gobject = (GObjectClass *) sheet_editor;
125 
126   gobject->set_property = ags_sheet_editor_set_property;
127   gobject->get_property = ags_sheet_editor_get_property;
128 
129   gobject->finalize = ags_sheet_editor_finalize;
130 
131   /* properties */
132   /**
133    * AgsSheetEditor:soundcard:
134    *
135    * The assigned #AgsSoundcard acting as default sink.
136    *
137    * Since: 3.0.0
138    */
139   param_spec = g_param_spec_object("soundcard",
140 				   i18n_pspec("assigned soundcard"),
141 				   i18n_pspec("The soundcard it is assigned with"),
142 				   G_TYPE_OBJECT,
143 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
144   g_object_class_install_property(gobject,
145 				  PROP_SOUNDCARD,
146 				  param_spec);
147 
148   /* AgsSheetClass */
149   sheet_editor->machine_changed = ags_sheet_editor_real_machine_changed;
150 
151   /* signals */
152   /**
153    * AgsSheet::machine-changed:
154    * @sheet: the object to change machine.
155    * @machine: the #AgsMachine to set
156    *
157    * The ::machine-changed signal notifies about changed machine.
158    *
159    * Since: 3.0.0
160    */
161   sheet_editor_signals[MACHINE_CHANGED] =
162     g_signal_new("machine-changed",
163                  G_TYPE_FROM_CLASS(sheet_editor),
164                  G_SIGNAL_RUN_LAST,
165 		 G_STRUCT_OFFSET(AgsSheetEditorClass, machine_changed),
166                  NULL, NULL,
167                  g_cclosure_marshal_VOID__OBJECT,
168                  G_TYPE_NONE, 1,
169 		 G_TYPE_OBJECT);
170 }
171 
172 void
ags_sheet_editor_init(AgsSheetEditor * sheet_editor)173 ags_sheet_editor_init(AgsSheetEditor *sheet_editor)
174 {
175   gtk_orientable_set_orientation(GTK_ORIENTABLE(sheet_editor),
176 				 GTK_ORIENTATION_VERTICAL);
177 
178   //TODO:JK: implement me
179 }
180 
181 void
ags_sheet_editor_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)182 ags_sheet_editor_set_property(GObject *gobject,
183 			      guint prop_id,
184 			      const GValue *value,
185 			      GParamSpec *param_spec)
186 {
187   AgsSheetEditor *sheet_editor;
188 
189   sheet_editor = AGS_SHEET_EDITOR(gobject);
190 
191   switch(prop_id){
192   case PROP_SOUNDCARD:
193     {
194       GObject *soundcard;
195 
196       soundcard = g_value_get_object(value);
197 
198       if(sheet_editor->soundcard == soundcard){
199 	return;
200       }
201 
202       if(sheet_editor->soundcard != NULL){
203 	g_object_unref(sheet_editor->soundcard);
204       }
205 
206       if(soundcard != NULL){
207 	g_object_ref(soundcard);
208       }
209 
210       sheet_editor->soundcard = soundcard;
211     }
212     break;
213   default:
214     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
215     break;
216   }
217 }
218 
219 void
ags_sheet_editor_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)220 ags_sheet_editor_get_property(GObject *gobject,
221 			      guint prop_id,
222 			      GValue *value,
223 			      GParamSpec *param_spec)
224 {
225   AgsSheetEditor *sheet_editor;
226 
227   sheet_editor = AGS_SHEET_EDITOR(gobject);
228 
229   switch(prop_id){
230   case PROP_SOUNDCARD:
231     {
232       g_value_set_object(value, sheet_editor->soundcard);
233     }
234     break;
235   default:
236     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
237     break;
238   }
239 }
240 
241 void
ags_sheet_editor_connect(AgsConnectable * connectable)242 ags_sheet_editor_connect(AgsConnectable *connectable)
243 {
244   AgsSheetEditor *sheet_editor;
245 
246   sheet_editor = AGS_SHEET_EDITOR(connectable);
247 
248   if((AGS_SHEET_EDITOR_CONNECTED & (sheet_editor->flags)) != 0){
249     return;
250   }
251 
252   sheet_editor->flags |= AGS_SHEET_EDITOR_CONNECTED;
253 
254   //  g_signal_connect((GObject *) sheet_editor->machine_selector, "changed",
255   //		   G_CALLBACK(ags_sheet_editor_machine_changed_callback), (gpointer) sheet_editor);
256 
257   /* toolbar */
258   ags_connectable_connect(AGS_CONNECTABLE(sheet_editor->sheet_toolbar));
259 
260   /* machine selector */
261   ags_connectable_connect(AGS_CONNECTABLE(sheet_editor->machine_selector));
262 
263   /* notation page */
264   //  ags_connectable_connect(AGS_CONNECTABLE(sheet_editor->notation_page));
265 }
266 
267 void
ags_sheet_editor_disconnect(AgsConnectable * connectable)268 ags_sheet_editor_disconnect(AgsConnectable *connectable)
269 {
270   AgsSheetEditor *sheet_editor;
271 
272   sheet_editor = AGS_SHEET_EDITOR(connectable);
273 
274   /* sheet toolbar */
275   ags_connectable_disconnect(AGS_CONNECTABLE(sheet_editor->sheet_toolbar));
276 
277   /* machine selector */
278   ags_connectable_disconnect(AGS_CONNECTABLE(sheet_editor->machine_selector));
279 
280   /* notation page */
281   //  ags_connectable_disconnect(AGS_CONNECTABLE(sheet_editor->notation_page));
282 }
283 
284 void
ags_sheet_editor_finalize(GObject * gobject)285 ags_sheet_editor_finalize(GObject *gobject)
286 {
287   AgsSheetEditor *sheet_editor;
288 
289   sheet_editor = AGS_SHEET_EDITOR(gobject);
290 
291   if(sheet_editor->soundcard != NULL){
292     g_object_unref(sheet_editor->soundcard);
293   }
294 
295   /* call parent */
296   G_OBJECT_CLASS(ags_sheet_editor_parent_class)->finalize(gobject);
297 }
298 
299 void
ags_sheet_editor_real_machine_changed(AgsSheetEditor * sheet_editor,AgsMachine * machine)300 ags_sheet_editor_real_machine_changed(AgsSheetEditor *sheet_editor,
301 				      AgsMachine *machine)
302 {
303   //TODO:JK: implement me
304 }
305 
306 /**
307  * ags_sheet_editor_machine_changed:
308  * @sheet_editor: an #AgsSheetEditor
309  * @machine: the new #AgsMachine
310  *
311  * Is emitted as machine changed of sheet_editor.
312  *
313  * Since: 3.0.0
314  */
315 void
ags_sheet_editor_machine_changed(AgsSheetEditor * sheet_editor,AgsMachine * machine)316 ags_sheet_editor_machine_changed(AgsSheetEditor *sheet_editor,
317 				 AgsMachine *machine)
318 {
319   g_return_if_fail(AGS_IS_SHEET_EDITOR(sheet_editor));
320 
321   g_object_ref((GObject *) sheet_editor);
322   g_signal_emit((GObject *) sheet_editor,
323 		sheet_editor_signals[MACHINE_CHANGED], 0,
324 		machine);
325   g_object_unref((GObject *) sheet_editor);
326 }
327 
328 void
ags_sheet_editor_add_note(AgsSheetEditor * sheet_editor,AgsNote * note)329 ags_sheet_editor_add_note(AgsSheetEditor *sheet_editor,
330 			  AgsNote *note)
331 {
332   //TODO:JK: implement me
333 }
334 
335 void
ags_sheet_editor_delete_note(AgsSheetEditor * sheet_editor,guint x,guint y)336 ags_sheet_editor_delete_note(AgsSheetEditor *sheet_editor,
337 			     guint x, guint y)
338 {
339   //TODO:JK: implement me
340 }
341 
342 void
ags_sheet_editor_select_region(AgsSheetEditor * sheet_editor,guint x0,guint y0,guint x1,guint y1)343 ags_sheet_editor_select_region(AgsSheetEditor *sheet_editor,
344 			       guint x0, guint y0,
345 			       guint x1, guint y1)
346 {
347   //TODO:JK: implement me
348 }
349 
350 void
ags_sheet_editor_do_feedback(AgsSheetEditor * sheet_editor)351 ags_sheet_editor_do_feedback(AgsSheetEditor *sheet_editor)
352 {
353   //TODO:JK: implement me
354 }
355 
356 void
ags_sheet_editor_select_all(AgsSheetEditor * sheet_editor)357 ags_sheet_editor_select_all(AgsSheetEditor *sheet_editor)
358 {
359   //TODO:JK: implement me
360 }
361 
362 void
ags_sheet_editor_paste(AgsSheetEditor * sheet_editor)363 ags_sheet_editor_paste(AgsSheetEditor *sheet_editor)
364 {
365   //TODO:JK: implement me
366 }
367 
368 void
ags_sheet_editor_copy(AgsSheetEditor * sheet_editor)369 ags_sheet_editor_copy(AgsSheetEditor *sheet_editor)
370 {
371   //TODO:JK: implement me
372 }
373 
374 void
ags_sheet_editor_cut(AgsSheetEditor * sheet_editor)375 ags_sheet_editor_cut(AgsSheetEditor *sheet_editor)
376 {
377   //TODO:JK: implement me
378 }
379 
380 
381 /**
382  * ags_sheet_editor_new:
383  *
384  * Creates an #AgsSheetEditor
385  *
386  * Returns: a new #AgsSheetEditor
387  *
388  * Since: 3.0.0
389  */
390 AgsSheetEditor*
ags_sheet_editor_new()391 ags_sheet_editor_new()
392 {
393   AgsSheetEditor *sheet_editor;
394 
395   sheet_editor = (AgsSheetEditor *) g_object_new(AGS_TYPE_SHEET_EDITOR,
396 						 NULL);
397 
398   return(sheet_editor);
399 }
400