1 /* nekobee DSSI software synthesizer GUI
3 * Copyright (C) 2004 Sean Bolton
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the Free
17 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 #include <gdk/gdkkeysyms.h>
34 #include "nekobee_ports.h"
35 #include "nekobee_synth.h"
36 #include "callbacks.h"
37 #include "interface.h"
39 GtkWidget
*main_window
;
40 GtkWidget
*save_file_selection
;
42 GtkWidget
*osc1_waveform_pixmap
;
44 GtkObject
*tuning_adj
;
45 GtkObject
*polyphony_adj
;
46 GtkWidget
*monophonic_option_menu
;
47 GtkWidget
*glide_option_menu
;
48 GtkObject
*bendrange_adj
;
50 GtkObject
*voice_widget
[XSYNTH_PORTS_COUNT
];
52 #if GTK_CHECK_VERSION(2, 0, 0)
53 #define GTK20SIZEGROUP GtkSizeGroup
55 #define GTK20SIZEGROUP gpointer
59 create_voice_knob(GtkWidget
*main_window
, int index
, GtkWidget
*fixed
,
60 gint column
, gint row
, const char *text
)
63 GtkObject
*adjustment
;
65 adjustment
= gtk_adjustment_new (0, 0, 10, 0.005, 1, 0);
66 voice_widget
[index
] = adjustment
;
68 knob
= gtk_knob_new (GTK_ADJUSTMENT (adjustment
));
70 // gjcp - FIXME horrible one-off to add the tuning knob
71 if (index
== XSYNTH_PORT_TUNING
) GTK_KNOB(knob
)->knobtype
=1;
73 gtk_widget_ref (knob
);
74 gtk_object_set_data_full (GTK_OBJECT (main_window
), text
, knob
,
75 (GtkDestroyNotify
) gtk_widget_unref
);
77 gtk_widget_show (knob
);
78 gtk_fixed_put (GTK_FIXED (fixed
), knob
, column
, row
);
82 create_voice_slider(GtkWidget
*main_window
, int index
, GtkWidget
*fixed
,
83 gint column
, gint row
, const char *text
)
86 GtkObject
*adjustment
;
88 adjustment
= gtk_adjustment_new (0, 0, 10, 0.005, 1, 0);
89 voice_widget
[index
] = adjustment
;
91 knob
= gtk_slider_new (GTK_ADJUSTMENT (adjustment
));
93 gtk_widget_ref (knob
);
94 gtk_object_set_data_full (GTK_OBJECT (main_window
), text
, knob
,
95 (GtkDestroyNotify
) gtk_widget_unref
);
96 gtk_widget_show (knob
);
97 gtk_fixed_put (GTK_FIXED (fixed
), knob
, column
, row
);
103 create_main_window (const char *tag
)
108 GdkPixmap
*bg_map
= NULL
;
112 main_window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
113 gtk_object_set_data (GTK_OBJECT (main_window
), "main_window", main_window
);
114 gtk_window_set_title (GTK_WINDOW (main_window
), tag
);
116 // gjcp - FIXME - put these somewhere in a header
117 gtk_widget_set_size_request (main_window
, 600, 108);
118 gtk_window_set_default_size (GTK_WINDOW (main_window
), 600, 108);
119 gtk_window_set_resizable (GTK_WINDOW (main_window
), FALSE
);
121 gtk_widget_realize(main_window
); /* window must be realized for create_*_pixmap() */
123 // load the background up
124 bg_buf
= gdk_pixbuf_new_from_file(INSTALL_DIR
"/bg.png", NULL
);
125 gdk_pixbuf_render_pixmap_and_mask(bg_buf
, &bg_map
, NULL
, 255);
126 bg_style
= gtk_style_copy(gtk_widget_get_style(main_window
));
127 bg_style
->bg_pixmap
[GTK_STATE_NORMAL
] = bg_map
;
128 gtk_widget_set_style(main_window
, bg_style
);
130 // rather than the table layout I'm going to use fixed
131 fixed
= gtk_fixed_new ();
132 gtk_widget_show (fixed
);
133 gtk_container_add (GTK_CONTAINER (main_window
), fixed
);
137 for (i
= 0; i
< XSYNTH_PORTS_COUNT
; i
++) voice_widget
[i
] = NULL
;
139 // tuning can go from -12 to +12, so needs special poking
140 create_voice_knob(main_window
, XSYNTH_PORT_TUNING
, fixed
, 26, 46, "Tuning");
142 GTK_ADJUSTMENT(voice_widget
[XSYNTH_PORT_TUNING
])->lower
= -12.0f
;
143 GTK_ADJUSTMENT(voice_widget
[XSYNTH_PORT_TUNING
])->upper
= 12.0f
;
145 gtk_adjustment_changed (GTK_ADJUSTMENT(voice_widget
[XSYNTH_PORT_TUNING
]));
147 // wave switch also needs special poking
148 create_voice_slider(main_window
, XSYNTH_PORT_WAVEFORM
, fixed
, 116, 43, "Waveform");
149 GTK_ADJUSTMENT(voice_widget
[XSYNTH_PORT_WAVEFORM
])->upper
= 1.0f
;
150 GTK_ADJUSTMENT(voice_widget
[XSYNTH_PORT_WAVEFORM
])->step_increment
= 1.0f
;
151 gtk_adjustment_changed (GTK_ADJUSTMENT(voice_widget
[XSYNTH_PORT_WAVEFORM
]));
153 create_voice_knob(main_window
, XSYNTH_PORT_CUTOFF
, fixed
, 170, 46, "Cutoff");
154 create_voice_knob(main_window
, XSYNTH_PORT_RESONANCE
, fixed
, 242, 46, "Resonance");
155 create_voice_knob(main_window
, XSYNTH_PORT_ENVMOD
, fixed
, 314, 46, "Envmod");
156 create_voice_knob(main_window
, XSYNTH_PORT_DECAY
, fixed
, 386, 46, "Decay");
157 create_voice_knob(main_window
, XSYNTH_PORT_ACCENT
, fixed
, 458, 46, "Accent");
158 create_voice_knob(main_window
, XSYNTH_PORT_VOLUME
, fixed
, 530, 46, "Volume");
160 gtk_signal_connect(GTK_OBJECT(main_window
), "destroy",
161 GTK_SIGNAL_FUNC(gtk_main_quit
), NULL
);
162 gtk_signal_connect (GTK_OBJECT (main_window
), "delete_event",
163 (GtkSignalFunc
)on_delete_event_wrapper
,
164 (gpointer
)on_menu_quit_activate
);
167 /* connect patch edit widgets */
168 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_TUNING
]),
169 "value_changed", GTK_SIGNAL_FUNC(on_voice_slider_change
),
170 (gpointer
)XSYNTH_PORT_TUNING
);
171 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_WAVEFORM
]),
172 "value_changed", GTK_SIGNAL_FUNC(on_voice_slider_change
),
173 (gpointer
)XSYNTH_PORT_WAVEFORM
);
174 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_CUTOFF
]),
175 "value_changed", GTK_SIGNAL_FUNC (on_voice_slider_change
),
176 (gpointer
)XSYNTH_PORT_CUTOFF
);
177 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_RESONANCE
]),
178 "value_changed", GTK_SIGNAL_FUNC(on_voice_slider_change
),
179 (gpointer
)XSYNTH_PORT_RESONANCE
);
181 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_ENVMOD
]),
182 "value_changed", GTK_SIGNAL_FUNC(on_voice_slider_change
),
183 (gpointer
)XSYNTH_PORT_ENVMOD
);
184 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_DECAY
]),
185 "value_changed", GTK_SIGNAL_FUNC(on_voice_slider_change
),
186 (gpointer
)XSYNTH_PORT_DECAY
);
187 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_ACCENT
]),
188 "value_changed", GTK_SIGNAL_FUNC(on_voice_slider_change
),
189 (gpointer
)XSYNTH_PORT_ACCENT
);
190 gtk_signal_connect (GTK_OBJECT (voice_widget
[XSYNTH_PORT_VOLUME
]),
191 "value_changed", GTK_SIGNAL_FUNC(on_voice_slider_change
),
192 (gpointer
)XSYNTH_PORT_VOLUME
);
196 create_windows(const char *instance_tag
)
200 /* build a nice identifier string for the window titles */
201 if (strlen(instance_tag
) == 0) {
202 strcpy(tag
, "nekobee");
203 } else if (strstr(instance_tag
, "nekobee-DSSI") ||
204 strstr(instance_tag
, "nekobee-dssi")) {
205 if (strlen(instance_tag
) > 49) {
206 snprintf(tag
, 50, "...%s", instance_tag
+ strlen(instance_tag
) - 46); /* hope the unique info is at the end */
208 strcpy(tag
, instance_tag
);
211 if (strlen(instance_tag
) > 37) {
212 snprintf(tag
, 50, "nekobee ...%s", instance_tag
+ strlen(instance_tag
) - 34);
214 snprintf(tag
, 50, "nekobee %s", instance_tag
);
218 create_main_window(tag
);