1 /*
2    ScheduleGUI.h
3    Copyright (C) 2006-2009  Bret Logan
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #ifndef _SCHEDULE_GUI_
20 #define _SCHEDULE_GUI_
21 
22 #include <gtk/gtk.h>    //put here so ScheduleXML gets it; natively, it doesn't need it
23 
24 #define SG_SELECTED                         TRUE
25 #define SG_UNSELECTED                       FALSE
26 //#define SG_VISIBLE                          TRUE
27 //#define SG_INVISIBLE                        FALSE
28 
29 //I do this hack solely to grab a few defines (BB_VOICETYPE_*, BB_AUDIBLE, etc.)
30 #include "BinauralBeat.h"
31 
32 #define SG_GRAPHTYPE_BEATFREQ               1
33 #define SG_GRAPHTYPE_BASEFREQ               3
34 #define SG_GRAPHTYPE_VOLUME                 7
35 #define SG_GRAPHTYPE_VOLUME_BALANCE         15
36 
37 //Define SG_GNAURALDBG accordingly to spit out debug info. Here are two versions:
38 #define SG_GNAURALDBG if (TRUE == SG_DebugFlag)
39 //#define SG_GNAURALDBG
40 
41 #define SG_DBGOUT_STR(a,b)  SG_GNAURALDBG  fprintf(stderr,"%s %d: %s %s\n",__FILE__,__LINE__,a, b);
42 #define SG_DBGOUT_INT(a,b)  SG_GNAURALDBG  fprintf(stderr,"%s %d: %s %d\n",__FILE__,__LINE__,a, b);
43 #define SG_DBGOUT_FLT(a,b)  SG_GNAURALDBG  fprintf(stderr,"%s %d: %s %g\n",__FILE__,__LINE__,a, b);
44 #define SG_DBGOUT_PNT(a,b)  SG_GNAURALDBG  fprintf(stderr,"%s %d: %s %p\n",__FILE__,__LINE__,a,b);
45 #define SG_DBGOUT(a)        SG_GNAURALDBG  fprintf(stderr,"%s %d: %s\n",__FILE__,__LINE__,a);
46 #define SG_DBG()            SG_GNAURALDBG  fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
47 #define SG_ERROUT(a)        fprintf(stderr,"%s %d: #Error# %s\n",__FILE__,__LINE__,a);
48 #define SG_ERROUT_INT(a,b)  fprintf(stderr,"%s %d: #Error# %s %d\n",__FILE__,__LINE__,a,b);
49 
50 //data structures:
51 typedef struct SG_DataPoint_type
52 {
53  double x;
54  double y;
55  double duration;               //duration of the datapoint's event in seconds
56  double volume_left;            //a value between 0 and 1
57  double volume_right;           //a value between 0 and 1
58  double basefreq;               //the frequency basis (in Hz) for the beatfreq's offset value
59  double beatfreq;               //the difference (in Hz) between the right and left audio channel (with basefreq as basis)
60  int state;                     //masks: SG_SELECTED and SG_UNSELECTED
61  struct SG_DataPoint_type *NextDataPoint;
62  struct SG_DataPoint_type *PrevDataPoint;
63  void *parent;                  //currently always a pointer to an SG_Voice *
64 } SG_DataPoint;
65 
66 typedef struct SG_Voice_type
67 {
68  int ID;                        // 0,1,2,... Not necessarily sequential, but assumed only to go lower to higher down linked list
69  int type;                      //masks: BB_VOICETYPE_BINAURALBEAT, BB_VOICETYPE_PINKNOISE, BB_VOICETYPE_PCM
70  int state;                     //SG_SELECTED or SG_UNSELECTED
71  int hide;                      //TRUE or FALSE
72  int mute;                      //TRUE or FALSE
73  int mono;                      //TRUE or FALSE [20100614]
74  char *description;             //Holds a string, usually a description, but a filename if BB_VOICETYPE_PCM
75  SG_DataPoint *FirstDataPoint;
76  struct SG_Voice_type *NextVoice;
77  struct SG_Voice_type *PrevVoice;
78 } SG_Voice;
79 
80 typedef struct
81 {
82  int status;                    //live=1, dead=0
83  int startX;
84  int startY;
85  int endX;
86  int endY;
87 } SG_SelectionBox_type;
88 
89 //this is very important: it not only holds all Undo/Redo and
90 //Copy/Paste info, but is also used to load the graph with BB data:
91 typedef struct
92 {
93  int TotalVoices;               //total number of voices in the schedule
94  int TotalDataPoints;           //the total number of DataPoints held by DPdata
95  int OrigWidth;
96  int OrigHeight;
97  double OrigSG_TotalScheduleDuration;
98  //Following is allotted to the number of voices in order to store Voice-
99  //specific data, since SG_BackupData is streamlined to hold SG_DataPoint data:
100  SG_Voice *Voice;
101  SG_DataPoint *DPdata;          //this will hold all the raw data points
102 } SG_BackupData;
103 
104 //global vars to be shared with any external code:
105 extern SG_Voice *SG_FirstVoice;
106 extern SG_DataPoint *SG_CurrentDataPoint;
107 extern SG_SelectionBox_type SG_SelectionBox;
108 extern double SG_TotalScheduleDuration;
109 extern int SG_GraphType;        //Informs program what type of graph to draw/gather-data-through; can be SG_GRAPHTYPE_BASEFREQ, SG_GRAPHTYPE_BEATFREQ, SG_GRAPHTYPE_VOLUME, SG_GRAPHTYPE_VOLUME_BALANCE.
110 extern gboolean SG_GraphHasChanged;     //lets any external code know when graph was cosmetically changed
111 extern gboolean SG_DataHasChanged;      //lets any external code know when it should reload data
112 extern SG_BackupData SG_UndoRedo;       //needed to be shared to serve as intermediary between SG and XML
113 extern int SG_DebugFlag;        //set to true to spit-out debug info
114 extern int SG_GraphFontSize;    //[20100405] THIS IS IN PIXELS!!!!
115 extern int SG_DataPointSize;    //[20100408]
116 extern PangoLayout *SG_PangoLayout;     //controls the fonts associated with the main drawing area
117 extern gboolean SG_MagneticPointerflag;
118 
119 //functions:
120 void SG_Init (GdkPixmap * pixmap);      //MUST be called with a valid pixmap for ScheduleGUI to draw on
121 void SG_Cleanup ();
122 void SG_SetupDefaultDataPoints (int numberofvoices);    //just puts something (small) in ScheduleGUI in case it is found empty
123 void SG_DeselectDataPoints ();
124 void SG_DrawGraph (GtkWidget * widget);
125 void SG_DrawGrid (GtkWidget * widget, double vscale, char *vtext);
126 void SG_DrawGridFast (GtkWidget * widget, double y_var);
127 void SG_CleanupDataPoints (SG_DataPoint * firstDataPoint);      //caller must be sure to NULL firstDataPoint when done!
128 SG_DataPoint *SG_AddNewDataPointToEnd (SG_DataPoint * FirstDP,
129                                        SG_Voice * voice, double duration,
130                                        double beatfreq, double volume_left,
131                                        double volume_right, double basefreq,
132                                        int state);
133 SG_DataPoint *SG_InsertNewDataPointXY (GtkWidget * widget, SG_Voice * voice,
134                                        double x, double y);
135 inline void SG_GetScheduleLimits (void);        //fills maxduration and maxbeatfrequency global variables
136 void SG_ConvertDataToXY (GtkWidget * widget);   //call this, and it calls the right one below according to SG_GraphType's value
137 void SG_ConvertXToDuration_AllPoints (GtkWidget * widget);
138 void SG_ConvertYToData_SelectedPoints (GtkWidget * widget);
139 void SG_MoveDataPoint (GtkWidget * widget, SG_DataPoint * curDP, double newx,
140                        double newy);
141 void SG_MoveSelectedDataPoints (GtkWidget * widget, double moveX,
142                                 double moveY);
143 gboolean SG_SwapLinks_left (SG_DataPoint * curDP);      //swaps datapoint with its left neighbor
144 gboolean SG_SwapLinks (SG_DataPoint * curDP1, SG_DataPoint * curDP2);   //swaps any two existing links
145 gboolean SG_DialogNewVoice (GtkWidget * widget, SG_DataPoint * curDP);
146 gboolean SG_DataPointPropertiesDialog (GtkWidget * widget,
147                                        SG_DataPoint * curDP);
148 void SG_CleanupVoice (SG_Voice * curVoice);     // internal use only, merely frees memory; user should call SG_DeleteVoice()
149 void SG_CleanupVoices (SG_Voice * FirstVoice);  //Remember to NULL stuff after you send it here!
150 void SG_DeleteVoice (SG_Voice * curVoice);
151 SG_Voice *SG_AddNewVoiceToEnd (int type, int ID);       //ID added and SG_Voice removed 20100625
152 SG_Voice *SG_SelectVoice (SG_Voice * voice);
153 
154 void SG_DeleteDataPoint (SG_DataPoint * curDP, gboolean DeleteTime);
155 void SG_DeleteDataPoints (GtkWidget * widget, gboolean DeleteTime,
156                           gboolean selected_only);
157 void SG_DeleteDuplicateDataPoints (GtkWidget * widget);
158 
159 void SG_BackupDataPoints (GtkWidget * widget);  //user should call this before any action they want to be able to undo
160 void SG_RestoreDataPoints (GtkWidget * widget, gboolean SG_MergeRestore);
161 void SG_CopySelectedDataPoints (GtkWidget * widget);
162 void SG_PasteSelectedDataPoints (GtkWidget * widget, gboolean predeselect);
163 void SG_CopyDataPoints (GtkWidget * widget, SG_BackupData * backupdata,
164                         gboolean selected_only);
165 void SG_PasteDataPoints (GtkWidget * widget, SG_BackupData * backupdata,
166                          gboolean predeselect);
167 void SG_CleanupBackupData (SG_BackupData * Bdata);
168 int SG_AllocateBackupData (SG_BackupData * Bdata, int TotalVoiceCount,
169                            int TotalDataPointCount);
170 int SG_VoiceCount ();
171 
172 //char *SG_StringAllocateAndCopy (const char *tmpstr);    //just an easy way to copy a string; user still has to free result
173 void SG_StringAllocateAndCopy (char **dest, const char *tmpstr);        //just an easy way to copy a string; if (*dest) != NULL, this free's it first
174 gboolean SG_MessageBox (char *question);
175 void SG_VoiceTestLegalSelection ();
176 
177 //Local Handlers (to be called from calling code):
178 //gboolean SG_realize( GtkWidget *widget, GdkEventConfigure *event);
179 //gboolean SG_expose_event( GtkWidget *widget, GdkEventExpose *event);
180 //gboolean SG_delete_event(GtkWidget* window, GdkEvent* e, gpointer data);
181 gboolean SG_button_release_event (GtkWidget * widget, GdkEventButton * event);
182 gboolean SG_button_press_event (GtkWidget * widget, GdkEventButton * event);
183 gboolean SG_configure_event (GtkWidget * widget, GdkEventConfigure * event);
184 gboolean SG_motion_notify_event (GtkWidget * widget, GdkEventMotion * event);
185 void SG_DrawCurrentPointInGraph (GtkWidget * widget);
186 void SG_SelectDataPoints_All (gboolean select);
187 void SG_SelectDataPoints_Voice (SG_Voice * curVoice, gboolean select);
188 void SG_SelectDataPoints (int startX, int startY, int endX, int endY,
189                           gboolean select);
190 void SG_SelectIntervalDataPoints_Voice (SG_Voice * curVoice, int interval,
191                                         gboolean select,
192                                         gboolean inverse_on_others);
193 void SG_SelectIntervalDataPoints_All (int interval, gboolean select,
194                                       gboolean inverse_on_others);
195 void SG_SelectInvertDataPoints_All ();
196 void SG_SelectInvertDataPoints_Voice (SG_Voice * curVoice);
197 void SG_SelectNeighboringDataPoints (gboolean next, gboolean deselect);
198 void SG_AlignDataPoints (GtkWidget * widget);
199 void SG_ScaleDataPoints_Time (GtkWidget * widget, double scalar);
200 void SG_ScaleDataPoints_Y (GtkWidget * widget, double scalar);
201 int SG_MagneticPointer (GtkWidget * widget, int x, int y);
202 void SG_TestDataPointGraphLimits (GtkWidget * widget, SG_DataPoint * curDP);
203 void SG_AddToDataPoints (GtkWidget * widget, double limit,
204                          gboolean x_flag, gboolean y_flag,
205                          gboolean rand_flag);
206 void SG_DuplicateSelectedVoice ();
207 void SG_ReverseVoice (GtkWidget * widget);
208 void SG_CountAllData (int *voicecount_all, int *voicecount_selecteddp,
209                       int *dpcount_all, int *dpcount_selected);
210 void SG_CountVoiceDPs (SG_Voice * curVoice, int *dpcount_all,
211                        int *dpcount_selected);
212 gboolean SG_SwapLinks (SG_DataPoint * curDP1, SG_DataPoint * curDP2);
213 void SG_SelectLastDP (SG_Voice * curVoice);
214 void SG_SelectLastDP_All ();
215 void SG_SelectFirstDP_All ();
216 void SG_TruncateSchedule (GtkWidget * widget, double endtime);
217 void SG_PasteDataPointsAtEnd (GtkWidget * widget);
218 SG_DataPoint *SG_GetLeftmostSelectedDP ();
219 void SG_InvertY (GtkWidget * widget);
220 void SG_SelectDuration (GtkWidget * widget, double duration);
221 void SG_SelectProximity_All (double threshold);
222 void SG_SelectProximity_SingleDP (SG_DataPoint * innerDP, double threshold);
223 void SG_RoundValues_All (GtkWidget * widget, double roundingval,
224                          int parameter);
225 void SG_RoundValues_Voice (GtkWidget * widget, SG_Voice * curVoice,
226                            double roundingval, int parameter);
227 void SG_FontSetup (GtkWidget * widget); //[20100405]
228 #endif
229