make midimap obey channels
[galan.git] / plugins / libctrl.c
blob83f29b7cfc571d704623b8c98d198ee4fcfd152c
1 /* gAlan - Graphical Audio Language
2 * Copyright (C) 1999 Tony Garnock-Jones
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <stddef.h>
24 #include <gdk/gdk.h>
25 #include <gtk/gtk.h>
27 #include "global.h"
28 #include "generator.h"
29 #include "comp.h"
30 #include "control.h"
31 #include "gencomp.h"
32 #include "msgbox.h"
34 #define GENERATOR_CLASS_NAME "ctrl"
35 #define GENERATOR_CLASS_PATH "Controls/Control"
37 #define EVT_VALUE 0
38 #define EVT_DISP 1
39 #define EVT_NORM 2
40 #define EVT_OUTPUT 0
42 typedef struct Data {
43 gdouble min, max, step, page;
44 gdouble value;
45 } Data;
47 PRIVATE int init_instance(Generator *g) {
48 Data *data = safe_malloc(sizeof(Data));
49 g->data = data;
51 data->min = data->value = 0;
52 data->max = 100;
53 data->step = data->page = 1;
55 return 1;
58 PRIVATE void destroy_instance(Generator *g) {
59 free(g->data);
62 PRIVATE void unpickle_instance(Generator *g, ObjectStoreItem *item, ObjectStore *db) {
63 Data *data = safe_malloc(sizeof(Data));
64 g->data = data;
66 data->min = objectstore_item_get_double(item, "ctrl_min", 0);
67 data->max = objectstore_item_get_double(item, "ctrl_max", 0);
68 data->step = objectstore_item_get_double(item, "ctrl_step", 0);
69 data->page = objectstore_item_get_double(item, "ctrl_page", 0);
70 data->value = objectstore_item_get_double(item, "ctrl_value", 0);
73 PRIVATE void pickle_instance(Generator *g, ObjectStoreItem *item, ObjectStore *db) {
74 Data *data = g->data;
75 objectstore_item_set_double(item, "ctrl_min", data->min);
76 objectstore_item_set_double(item, "ctrl_max", data->max);
77 objectstore_item_set_double(item, "ctrl_step", data->step);
78 objectstore_item_set_double(item, "ctrl_page", data->page);
79 objectstore_item_set_double(item, "ctrl_value", data->value);
82 PRIVATE void ctrl_setrange(Control *c) {
83 Data *data= c->g->data;
85 c->min = data->min;
86 c->max = data->max;
87 c->step = data->step;
88 c->page = data->page;
91 PRIVATE void evt_value_handler(Generator *g, AEvent *event) {
92 Data *data = g->data;
95 data->value = event->d.number;
96 gen_update_controls(g, -1);
97 gen_send_events(g, EVT_OUTPUT, -1, event);
100 PRIVATE void evt_disp_handler(Generator *g, AEvent *event) {
101 Data *data = g->data;
103 data->value = event->d.number;
104 gen_update_controls(g, -1);
107 PRIVATE void evt_normal_value_handler(Generator *g, AEvent *event) {
108 Data *data = g->data;
110 if( event->kind == AE_NUMBER ) {
111 data->value = data->min + (event->d.number+1.0)*(data->max - data->min)/2.0;
112 event->d.number=data->value;
113 gen_update_controls(g, -1);
114 gen_send_events(g, EVT_OUTPUT, -1, event);
118 PRIVATE ControlDescriptor controls[] = {
119 { CONTROL_KIND_KNOB, "knob", 0,0,0,0,0,TRUE, 1,EVT_VALUE,
120 ctrl_setrange,NULL, control_double_updater, (gpointer) offsetof(Data, value) },
121 { CONTROL_KIND_SLIDER, "slider", 0,0,0,0,0,TRUE, 1,EVT_VALUE,
122 ctrl_setrange,NULL, control_double_updater, (gpointer) offsetof(Data, value) },
123 { CONTROL_KIND_TOGGLE, "toggle", 0,0,0,0,0,FALSE, 1,EVT_VALUE,
124 ctrl_setrange,NULL, control_double_updater, (gpointer) offsetof(Data, value) },
125 { CONTROL_KIND_BUTTON, "button", 0,0,0,0,0,FALSE, 1,EVT_VALUE,
126 ctrl_setrange,NULL, control_double_updater, (gpointer) offsetof(Data, value) },
127 { CONTROL_KIND_NONE, }
130 PRIVATE GtkWidget *build_entry(GtkWidget *vbox, char *text, gdouble value) {
131 GtkWidget *hbox = gtk_hbox_new(FALSE, 2);
132 GtkWidget *label = gtk_label_new(text);
133 GtkWidget *entry = gtk_entry_new();
134 char buf[128];
136 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
137 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
138 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
139 gtk_widget_show(label);
140 gtk_widget_show(entry);
141 gtk_widget_show(hbox);
143 sprintf(buf, "%g", value);
144 gtk_entry_set_text(GTK_ENTRY(entry), buf);
146 return entry;
149 PRIVATE void props(Component *c, Generator *g) {
150 Data *data = g->data;
151 GtkWidget *min, *max, *step, *page;
152 GtkWidget *vbox;
154 vbox = gtk_vbox_new(FALSE, 2);
156 min = build_entry(vbox, "Range Minimum:", data->min);
157 max = build_entry(vbox, "Range Maximum:", data->max);
158 step = build_entry(vbox, "Step Increment:", data->step);
159 page = build_entry(vbox, "Page Increment:", data->page);
161 if (popup_dialog(g->name, MSGBOX_OK | MSGBOX_CANCEL, 0, MSGBOX_OK, vbox, NULL, 0) == MSGBOX_OK) {
162 data->min = atof(gtk_entry_get_text(GTK_ENTRY(min)));
163 data->max = atof(gtk_entry_get_text(GTK_ENTRY(max)));
164 data->step = atof(gtk_entry_get_text(GTK_ENTRY(step)));
165 data->page = atof(gtk_entry_get_text(GTK_ENTRY(page)));
167 g_list_foreach(g->controls, (GFunc) ctrl_setrange, NULL);
168 g_list_foreach(g->controls, (GFunc) control_update_range, NULL);
172 #if 0
173 PRIVATE void init_combo( Control *control ) {
177 PRIVATE void done_combo(Control *control) {
180 PRIVATE void refresh_combo(Control *control) {
182 #endif
184 PRIVATE void setup_class(void) {
185 GeneratorClass *k = gen_new_generatorclass(GENERATOR_CLASS_NAME, FALSE, 3, 1,
186 NULL, NULL, controls,
187 init_instance, destroy_instance,
188 unpickle_instance, pickle_instance);
190 gen_configure_event_input(k, EVT_VALUE, "Value", evt_value_handler);
191 gen_configure_event_input(k, EVT_DISP, "Display", evt_disp_handler);
192 gen_configure_event_input(k, EVT_NORM, "Normal Value", evt_normal_value_handler );
193 gen_configure_event_output(k, EVT_OUTPUT, "Output");
195 gencomp_register_generatorclass(k, FALSE, GENERATOR_CLASS_PATH, NULL, props);
198 PUBLIC void init_plugin(void) {
199 setup_class();