HAAS Stereo Enhancer
[calf.git] / src / calf / gui.h
blob90fe55fbe1dfca18164a5e46fc30c6ad9e14f31d
1 /* Calf DSP Library
2 * Universal GUI module
3 * Copyright (C) 2007-2011 Krzysztof Foltman
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
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 GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02111-1307, USA.
20 #ifndef __CALF_GUI_H
21 #define __CALF_GUI_H
23 #include <expat.h>
24 #include <map>
25 #include <set>
26 #include <string>
27 #include <vector>
28 #include <gtk/gtk.h>
29 #include "giface.h"
30 #include "gui_config.h"
31 #include "jackhost.h"
33 namespace calf_plugins {
35 class window_update_controller
37 int refresh_counter;
38 public:
39 window_update_controller() : refresh_counter() {}
40 bool check_redraw(GtkWidget *toplevel);
43 class plugin_gui;
45 struct control_base
47 virtual bool is_container() { return false; };
48 GtkContainer *container;
49 std::string control_name;
50 typedef std::map<std::string, std::string> xml_attribute_map;
51 xml_attribute_map attribs;
52 plugin_gui *gui;
53 void require_attribute(const char *name);
54 void require_int_attribute(const char *name);
55 int get_int(const char *name, int def_value = 0);
56 float get_float(const char *name, float def_value = 0.f);
57 virtual void add(GtkWidget *w, control_base *base) { gtk_container_add(container, w); }
58 /// called after creation, so that all standard properties can be set
59 virtual void set_std_properties() = 0;
63 struct control_container: public control_base
65 virtual GtkWidget *create(plugin_gui *_gui, const char *element, xml_attribute_map &attributes)=0;
66 virtual void set_std_properties();
67 virtual ~control_container() {}
70 #define _GUARD_CHANGE_ if (in_change) return; guard_change __gc__(this);
72 struct param_control: public control_base
74 int param_no;
75 std::string param_variable;
76 GtkWidget *widget, *entrywin;
77 int in_change;
78 bool has_entry;
79 float old_displayed_value;
81 struct guard_change {
82 param_control *pc;
83 guard_change(param_control *_pc) : pc(_pc) { pc->in_change++; }
84 ~guard_change() { pc->in_change--; }
87 param_control();
88 inline const parameter_properties &get_props();
90 virtual void init_xml(const char *element) {}
91 /// called to create a widget for a control
92 virtual GtkWidget *create(plugin_gui *_gui, int _param_no)=0;
93 virtual void created(){};
94 /// called to transfer the value from control to parameter(s)
95 virtual void get()=0;
96 /// called to transfer the value from parameter(s) to control
97 virtual void set()=0;
98 /// called on DSSI configure()
99 virtual void configure(const char *key, const char *value) {}
100 virtual void hook_params();
101 virtual void on_idle() {}
102 virtual void set_std_properties();
103 virtual void set_visibilty(bool state);
104 virtual void add_context_menu_handler();
105 virtual ~param_control();
106 virtual void do_popup_menu();
107 static gboolean on_button_press_event(GtkWidget *widget, GdkEventButton *event, void *user_data);
108 static gboolean on_popup_menu(GtkWidget *widget, void *user_data);
109 virtual void create_value_entry(GtkWidget *widget, int x, int y);
110 virtual void destroy_value_entry();
111 static gboolean value_entry_action(GtkEntry *widget, GdkEvent *event, void *user_data);
112 static gboolean value_entry_unfocus(GtkWidget *widget, GdkEventFocus *event, void *user_data);
113 static gboolean value_entry_click(GtkWidget *widget, GdkEventButton *event, void *user_data);
117 class plugin_gui_window;
119 class plugin_gui: public send_configure_iface, public send_updates_iface
121 protected:
122 int param_count;
123 std::multimap<int, param_control *> par2ctl;
124 XML_Parser parser;
125 param_control *current_control;
126 std::vector<control_base *> container_stack;
127 std::vector<param_control *> control_stack;
128 control_base *top_container;
129 std::map<std::string, int> param_name_map;
130 int ignore_stack;
131 int last_status_serial_no;
132 std::map<int, GSList *> param_radio_groups;
133 GtkWidget *leftBox, *rightBox;
134 int context_menu_param_no;
135 uint32_t context_menu_last_designator;
137 struct automation_menu_entry {
138 plugin_gui *gui;
139 int source;
140 automation_menu_entry(plugin_gui *_gui, int _source)
141 : gui(_gui), source(_source) {}
143 std::vector<automation_menu_entry *> automation_menu_callback_data;
145 static void on_automation_add(GtkWidget *widget, void *user_data);
146 static void on_automation_delete(GtkWidget *widget, void *user_data);
147 static void on_automation_set_lower(GtkWidget *widget, void *user_data);
148 static void on_automation_set_upper(GtkWidget *widget, void *user_data);
149 void on_automation_set_lower_or_upper(automation_menu_entry *ame, bool is_upper);
150 public:
151 plugin_gui_window *window;
152 GtkWidget *container;
153 const char *effect_name;
154 plugin_ctl_iface *plugin;
155 preset_access_iface *preset_access;
156 std::vector<param_control *> params;
157 std::vector<int> read_serials;
159 plugin_gui(plugin_gui_window *_window);
160 GtkWidget *create_from_xml(plugin_ctl_iface *_plugin, const char *xml);
161 param_control *create_control_from_xml(const char *element, const char *attributes[]);
162 control_container *create_container_from_xml(const char *element, const char *attributes[]);
164 void add_param_ctl(int param, param_control *ctl) { par2ctl.insert(std::pair<int, param_control *>(param, ctl)); }
165 void refresh();
166 void refresh(int param_no, param_control *originator = NULL);
167 int get_param_no_by_name(std::string param_name);
168 void xml_element_start(const char *element, const char *attributes[]);
169 void set_param_value(int param_no, float value, param_control *originator = NULL);
170 /// Called on change of configure variable
171 void send_configure(const char *key, const char *value);
172 /// Called on change of status variable
173 void send_status(const char *key, const char *value);
174 void on_idle();
175 /// Get a radio button group (if it exists) for a parameter
176 GSList *get_radio_group(int param);
177 /// Set a radio button group for a parameter
178 void set_radio_group(int param, GSList *group);
179 /// Show rack ear widgets
180 void show_rack_ears(bool show);
181 /// Pop-up a context menu for a control
182 void on_control_popup(param_control *ctl, int param_no);
183 /// Clean up callback data allocated for the automation pop-up menu
184 void cleanup_automation_entries();
185 ~plugin_gui();
186 static void xml_element_start(void *data, const char *element, const char *attributes[]);
187 static void xml_element_end(void *data, const char *element);
190 class main_window_iface;
191 class main_window_owner_iface;
193 /// A class used to inform the plugin GUIs about the environment they run in
194 /// (currently: what plugin features are accessible)
195 struct gui_environment_iface
197 virtual bool check_condition(const char *name) = 0;
198 virtual calf_utils::config_db_iface *get_config_db() = 0;
199 virtual calf_utils::gui_config *get_config() = 0;
200 virtual ~gui_environment_iface() {}
203 /// An interface that wraps UI-dependent elements of the session
204 struct session_environment_iface
206 /// Called to initialise the UI libraries
207 virtual void init_gui(int &argc, char **&argv) = 0;
208 /// Create an appropriate version of the main window
209 virtual main_window_iface *create_main_window() = 0;
210 /// Called to start the UI loop
211 virtual void start_gui_loop() = 0;
212 /// Called from within event handlers to finish the UI loop
213 virtual void quit_gui_loop() = 0;
214 virtual ~session_environment_iface() {}
217 /// Trivial implementation of gui_environment_iface
218 class gui_environment: public gui_environment_iface
220 private:
221 GKeyFile *keyfile;
222 calf_utils::config_db_iface *config_db;
223 calf_utils::gui_config gui_config;
225 public:
226 std::set<std::string> conditions;
228 public:
229 gui_environment();
230 virtual bool check_condition(const char *name) { return conditions.count(name) != 0; }
231 virtual calf_utils::config_db_iface *get_config_db() { return config_db; }
232 virtual calf_utils::gui_config *get_config() { return &gui_config; }
233 ~gui_environment();
236 /// Interface used by the plugin to communicate with the main hosting window
237 struct main_window_iface: public progress_report_iface
239 /// Set owner pointer
240 virtual void set_owner(main_window_owner_iface *owner) = 0;
241 /// Add a condition to the list of conditions supported by the host
242 virtual void add_condition(const std::string &name) = 0;
243 /// Create the actual window associated with this interface
244 virtual void create() = 0;
245 /// Add the plugin to the window
246 virtual void add_plugin(jack_host *plugin) = 0;
247 /// Remove the plugin from the window
248 virtual void del_plugin(plugin_ctl_iface *plugin) = 0;
249 /// Refresh the plugin UI
250 virtual void refresh_plugin(plugin_ctl_iface *plugin) = 0;
251 /// Bind the plugin window to the plugin
252 virtual void set_window(plugin_ctl_iface *plugin, plugin_gui_window *window) = 0;
253 /// Refresh preset lists on all windows (if, for example, a new preset has been created)
254 virtual void refresh_all_presets(bool builtin_too) = 0;
255 /// Default open file operation
256 virtual void open_file() = 0;
257 /// Default save file operation
258 virtual bool save_file() = 0;
259 /// Called to clean up when host quits
260 virtual void on_closed() = 0;
261 /// Show an error message
262 virtual void show_error(const std::string &text) = 0;
265 virtual ~main_window_iface() {}
268 struct main_window_owner_iface
270 virtual void new_plugin(const char *name) = 0;
271 virtual void remove_plugin(plugin_ctl_iface *plugin) = 0;
272 virtual char *open_file(const char *name) = 0;
273 virtual char *save_file(const char *name) = 0;
274 virtual void reorder_plugins() = 0;
275 /// Return JACK client name (or its counterpart) to put in window title bars
276 virtual std::string get_client_name() const = 0;
277 /// Called on 'destroy' event of the main window
278 virtual void on_main_window_destroy() = 0;
279 /// Called from idle handler
280 virtual void on_idle() = 0;
281 /// Get the file name of the current rack
282 virtual std::string get_current_filename() const = 0;
283 /// Set the file name of the current rack
284 virtual void set_current_filename(const std::string &name) = 0;
285 virtual ~main_window_owner_iface() {}
288 class plugin_gui_window: public calf_utils::config_listener_iface
290 private:
291 void cleanup();
292 window_update_controller refresh_controller;
293 public:
294 plugin_gui *gui;
295 GtkWindow *toplevel;
296 GtkUIManager *ui_mgr;
297 GtkActionGroup *std_actions, *builtin_preset_actions, *user_preset_actions, *command_actions;
298 gui_environment_iface *environment;
299 main_window_iface *main;
300 int source_id;
301 calf_utils::config_notifier_iface *notifier;
303 plugin_gui_window(gui_environment_iface *_env, main_window_iface *_main);
304 std::string make_gui_preset_list(GtkActionGroup *grp, bool builtin, char &ch);
305 std::string make_gui_command_list(GtkActionGroup *grp);
306 void fill_gui_presets(bool builtin, char &ch);
307 void create(plugin_ctl_iface *_plugin, const char *title, const char *effect);
308 void close();
309 virtual void on_config_change();
310 static gboolean on_idle(void *data);
311 static void on_window_destroyed(GtkWidget *window, gpointer data);
312 ~plugin_gui_window();
316 inline const parameter_properties &param_control::get_props()
318 return *gui->plugin->get_metadata_iface()->get_param_props(param_no);
321 class null_audio_module;
323 struct activate_command_params
325 typedef void (*CommandFunc)(null_audio_module *);
326 plugin_gui *gui;
327 int function_idx;
329 activate_command_params(plugin_gui *_gui, int _idx)
330 : gui(_gui), function_idx(_idx)
335 void activate_command(GtkAction *action, activate_command_params *params);
339 #endif