1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 20 окт. 2015 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 #ifndef _UI_PLUGIN_UI_H_ 23 #define _UI_PLUGIN_UI_H_ 24 25 #include <metadata/metadata.h> 26 27 #include <data/cvector.h> 28 29 #include <ui/ws/ws.h> 30 #include <core/io/IInStream.h> 31 #include <core/files/config.h> 32 #include <core/port_data.h> 33 34 namespace lsp 35 { 36 class plugin_ui: public CtlRegistry 37 { 38 private: 39 plugin_ui &operator = (const plugin_ui &); 40 41 protected: 42 typedef struct preset_t 43 { 44 char *name; 45 char *path; 46 LSPWidget *item; 47 } preset_t; 48 49 class ConfigHandler: public config::IConfigHandler 50 { 51 private: 52 plugin_ui *pUI; 53 cvector<CtlPort> &hPorts; 54 KVTStorage *pKVT; 55 cvector<char> vNotify; 56 bool bPreset; 57 io::Path *pBasePath; 58 59 protected: 60 void add_notification(const char *id); 61 62 public: ConfigHandler(plugin_ui * ui,cvector<CtlPort> & ports,KVTStorage * kvt,bool preset,io::Path * base)63 explicit ConfigHandler(plugin_ui *ui, cvector<CtlPort> &ports, 64 KVTStorage *kvt, bool preset, io::Path *base 65 ): 66 pUI(ui), hPorts(ports), pKVT(kvt), bPreset(preset), pBasePath(base) {} 67 virtual ~ConfigHandler(); 68 69 public: 70 virtual status_t handle_parameter(const char *name, const char *value, size_t flags); 71 72 virtual status_t handle_kvt_parameter(const char *name, const kvt_param_t *param, size_t flags); 73 74 void notify_all(); 75 }; 76 77 class ConfigSource: public config::IConfigSource 78 { 79 private: 80 plugin_ui *pUI; 81 cvector<CtlPort> &hPorts; 82 LSPString *pComment; 83 KVTIterator *pIter; 84 size_t nPortID; 85 io::Path *pBasePath; 86 87 public: ConfigSource(plugin_ui * ui,cvector<CtlPort> & ports,KVTStorage * kvt,LSPString * comment,io::Path * base)88 explicit ConfigSource(plugin_ui *ui, cvector<CtlPort> &ports, 89 KVTStorage *kvt, LSPString *comment, io::Path *base 90 ): 91 pUI(ui), hPorts(ports), pComment(comment), nPortID(0) { 92 pIter = (kvt != NULL) ? kvt->enum_all() : NULL; 93 pBasePath = base; 94 } 95 96 public: 97 virtual status_t get_head_comment(LSPString *comment); 98 99 virtual status_t get_parameter(LSPString *name, LSPString *value, LSPString *comment, int *flags); 100 }; 101 102 class ConfigSink: public LSPTextDataSink 103 { 104 private: 105 plugin_ui *pUI; 106 107 public: ConfigSink(plugin_ui * ui)108 explicit ConfigSink(plugin_ui *ui): pUI(ui) {} 109 virtual ~ConfigSink(); 110 111 void unbind(); 112 113 public: 114 virtual status_t on_complete(status_t code, const LSPString *data); 115 }; 116 117 protected: 118 const plugin_metadata_t *pMetadata; 119 IUIWrapper *pWrapper; 120 LSPWindow *pRoot; 121 CtlPluginWindow *pRootCtl; 122 void *pRootWidget; 123 124 LSPDisplay sDisplay; 125 126 cvector<CtlPort> vPorts; 127 cvector<CtlPort> vCustomPorts; 128 cvector<CtlPort> vSortedPorts; 129 cvector<CtlPort> vConfigPorts; 130 cvector<CtlValuePort> vTimePorts; 131 cvector<LSPWidget> vWidgets; 132 cvector<CtlSwitchedPort> vSwitched; 133 cvector<CtlPortAlias> vAliases; 134 cvector<CtlKvtListener> vKvtListeners; 135 136 cstorage<preset_t> vPresets; 137 ConfigSink *pConfigSink; 138 139 protected: 140 static const port_t vConfigMetadata[]; 141 static const port_t vTimeMetadata[]; 142 143 protected: 144 size_t rebuild_sorted_ports(); 145 CtlWidget *build_widget(widget_ctl_t w_class); 146 io::File *open_config_file(bool write); 147 bool apply_changes(const char *key, const char *value, cvector<CtlPort> &ports, bool preset, const io::Path *base); 148 status_t scan_presets(); 149 void build_config_header(LSPString &c); 150 void destroy_presets(); 151 status_t paste_from_clipboard(const LSPString *data); 152 153 static status_t slot_preset_select(LSPWidget *sender, void *ptr, void *data); 154 155 public: 156 explicit plugin_ui(const plugin_metadata_t *mdata, void *root_widget); 157 virtual ~plugin_ui(); 158 159 virtual void destroy(); 160 161 public: metadata()162 inline const plugin_metadata_t *metadata() const { return pMetadata; }; wrapper()163 inline IUIWrapper *wrapper() { return pWrapper; }; 164 165 public: 166 CtlWidget *create_widget(const char *w_ctl); 167 CtlWidget *create_widget(widget_ctl_t w_class); 168 169 public: 170 /** Initialize UI 171 * 172 * @param root_widget root widget to use as a base 173 * @param wrapper plugin wrapper 174 * @param argc number of arguments 175 * @param argv list of arguments 176 * @return status of operation 177 */ 178 virtual status_t init(IUIWrapper *wrapper, int argc, const char **argv); 179 180 /** 181 * Build UI from the XML schema 182 * @return status of operation 183 */ 184 virtual status_t build(); 185 186 /** Method executed when the time position of plugin was updated 187 * 188 */ 189 void position_updated(const position_t *pos); 190 191 /** Add plugin port to UI 192 * 193 * @param port UI port to communicate with plugin 194 * @return status of operation 195 */ 196 status_t add_port(CtlPort *port); 197 198 /** Add custom port to UI 199 * 200 * @param port custom UI port 201 * @return status of operation 202 */ 203 status_t add_custom_port(CtlPort *port); 204 205 /** Export settings of the UI to the file 206 * 207 * @param filename file name 208 * @param relative use relative paths 209 * @return status of operation 210 */ 211 status_t export_settings(const char *filename, bool relative); 212 213 /** Import settings of the UI from the file 214 * 215 * @param filename file name 216 * @param preset indicator that the source is preset 217 * @return status of operation 218 */ 219 status_t import_settings(const char *filename, bool preset); 220 221 /** 222 * Export settings to clipboard 223 * @return status of operation 224 */ 225 status_t export_settings_to_clipboard(); 226 227 /** 228 * Import settings from clipboard 229 * @return status of operation 230 */ 231 status_t import_settings_from_clipboard(); 232 233 /** Save global configuration file 234 * 235 * @return status of operation 236 */ 237 status_t save_global_config(); 238 239 /** Load global configuration file 240 * 241 * @return status of operation 242 */ 243 status_t load_global_config(); 244 245 /** Get INTERNAL port by name 246 * 247 * @param name port name 248 * @return internal port 249 */ 250 CtlPort *port(const char *name); 251 252 /** 253 * Get port by index 254 * @param idx index of the port 255 * @return internal port by index 256 */ 257 CtlPort *port_by_index(size_t idx); 258 259 /** Get port count 260 * 261 * @return number of ports 262 */ ports_count()263 inline size_t ports_count() 264 { 265 return vPorts.size(); 266 } 267 268 /** Show UI 269 * 270 */ show()271 inline void show() 272 { 273 if (pRoot != NULL) 274 pRoot->show(); 275 } 276 277 /** Hide UI 278 * 279 */ hide()280 inline void hide() 281 { 282 if (pRoot != NULL) 283 pRoot->hide(); 284 } 285 286 /** Get width of main plugin window 287 * 288 * @return width of main plugin window 289 */ width()290 inline size_t width() { return (pRoot != NULL) ? pRoot->width() : 0; } 291 292 /** Get height of main plugin window 293 * 294 * @return height of main plugin window 295 */ height()296 inline size_t height() { return (pRoot != NULL) ? pRoot->height() : 0; } 297 298 /** Get Display 299 * 300 * @return display 301 */ display()302 inline LSPDisplay *display() { return &sDisplay; }; 303 304 /** Main UI function 305 * 306 * @return main function 307 */ main()308 inline status_t main() { return sDisplay.main(); }; 309 310 /** Main iteration 311 * 312 * @return main iteration 313 */ main_iteration()314 inline status_t main_iteration() { return sDisplay.main_iteration(); } 315 316 /** 317 * Synchronize state of meta ports 318 */ 319 void sync_meta_ports(); 320 321 /** Return root window 322 * 323 * @return root window (if exists) 324 */ root_window()325 inline LSPWindow *root_window() { return pRoot; } 326 327 /** 328 * Set title of the main window 329 * @param title title of the main window 330 */ 331 void set_title(const char *title); 332 333 /** 334 * Notify the write of the KVT parameter 335 * @param storage KVT storage 336 * @param id kvt parameter identifier 337 * @param value KVT parameter value 338 */ 339 virtual void kvt_write(KVTStorage *storage, const char *id, const kvt_param_t *value); 340 341 /** 342 * Lock the KVT storage 343 * @return pointer to KVT storage or NULL 344 */ 345 virtual KVTStorage *kvt_lock(); 346 347 /** 348 * Try to lock the KVT storage 349 * @return pointer to KVT storage or NULL if not locked/not supported 350 */ 351 virtual KVTStorage *kvt_trylock(); 352 353 /** 354 * Release the KVT storage 355 */ 356 virtual void kvt_release(); 357 358 /** 359 * Add KVT listener 360 * @param listener listener to add 361 * @return status of operation 362 */ 363 virtual status_t add_kvt_listener(CtlKvtListener *listener); 364 365 /** 366 * Request state dump 367 */ 368 void request_state_dump(); 369 }; 370 371 } /* namespace lsp */ 372 373 #endif /* _UI_PLUGIN_UI_H_ */ 374