| 1 | /**************************************************************************/ | 
|---|
| 2 | /*  editor_audio_buses.cpp                                                */ | 
|---|
| 3 | /**************************************************************************/ | 
|---|
| 4 | /*                         This file is part of:                          */ | 
|---|
| 5 | /*                             GODOT ENGINE                               */ | 
|---|
| 6 | /*                        https://godotengine.org                         */ | 
|---|
| 7 | /**************************************************************************/ | 
|---|
| 8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
|---|
| 9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
|---|
| 10 | /*                                                                        */ | 
|---|
| 11 | /* Permission is hereby granted, free of charge, to any person obtaining  */ | 
|---|
| 12 | /* a copy of this software and associated documentation files (the        */ | 
|---|
| 13 | /* "Software"), to deal in the Software without restriction, including    */ | 
|---|
| 14 | /* without limitation the rights to use, copy, modify, merge, publish,    */ | 
|---|
| 15 | /* distribute, sublicense, and/or sell copies of the Software, and to     */ | 
|---|
| 16 | /* permit persons to whom the Software is furnished to do so, subject to  */ | 
|---|
| 17 | /* the following conditions:                                              */ | 
|---|
| 18 | /*                                                                        */ | 
|---|
| 19 | /* The above copyright notice and this permission notice shall be         */ | 
|---|
| 20 | /* included in all copies or substantial portions of the Software.        */ | 
|---|
| 21 | /*                                                                        */ | 
|---|
| 22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | 
|---|
| 23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | 
|---|
| 24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | 
|---|
| 25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ | 
|---|
| 26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ | 
|---|
| 27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ | 
|---|
| 28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ | 
|---|
| 29 | /**************************************************************************/ | 
|---|
| 30 |  | 
|---|
| 31 | #include "editor_audio_buses.h" | 
|---|
| 32 |  | 
|---|
| 33 | #include "core/config/project_settings.h" | 
|---|
| 34 | #include "core/input/input.h" | 
|---|
| 35 | #include "core/io/resource_saver.h" | 
|---|
| 36 | #include "core/os/keyboard.h" | 
|---|
| 37 | #include "editor/editor_node.h" | 
|---|
| 38 | #include "editor/editor_scale.h" | 
|---|
| 39 | #include "editor/editor_settings.h" | 
|---|
| 40 | #include "editor/editor_string_names.h" | 
|---|
| 41 | #include "editor/editor_undo_redo_manager.h" | 
|---|
| 42 | #include "editor/filesystem_dock.h" | 
|---|
| 43 | #include "editor/gui/editor_file_dialog.h" | 
|---|
| 44 | #include "scene/gui/separator.h" | 
|---|
| 45 | #include "scene/resources/font.h" | 
|---|
| 46 | #include "servers/audio_server.h" | 
|---|
| 47 |  | 
|---|
| 48 | void EditorAudioBus::_update_visible_channels() { | 
|---|
| 49 | int i = 0; | 
|---|
| 50 | for (; i < cc; i++) { | 
|---|
| 51 | if (!channel[i].vu_l->is_visible()) { | 
|---|
| 52 | channel[i].vu_l->show(); | 
|---|
| 53 | } | 
|---|
| 54 | if (!channel[i].vu_r->is_visible()) { | 
|---|
| 55 | channel[i].vu_r->show(); | 
|---|
| 56 | } | 
|---|
| 57 | } | 
|---|
| 58 |  | 
|---|
| 59 | for (; i < CHANNELS_MAX; i++) { | 
|---|
| 60 | if (channel[i].vu_l->is_visible()) { | 
|---|
| 61 | channel[i].vu_l->hide(); | 
|---|
| 62 | } | 
|---|
| 63 | if (channel[i].vu_r->is_visible()) { | 
|---|
| 64 | channel[i].vu_r->hide(); | 
|---|
| 65 | } | 
|---|
| 66 | } | 
|---|
| 67 | } | 
|---|
| 68 |  | 
|---|
| 69 | void EditorAudioBus::_notification(int p_what) { | 
|---|
| 70 | switch (p_what) { | 
|---|
| 71 | case NOTIFICATION_ENTER_TREE: | 
|---|
| 72 | case NOTIFICATION_THEME_CHANGED: { | 
|---|
| 73 | Ref<Texture2D> active_bus_texture = get_editor_theme_icon(SNAME( "BusVuActive")); | 
|---|
| 74 | for (int i = 0; i < CHANNELS_MAX; i++) { | 
|---|
| 75 | channel[i].vu_l->set_under_texture(active_bus_texture); | 
|---|
| 76 | channel[i].vu_l->set_tint_under(Color(0.75, 0.75, 0.75)); | 
|---|
| 77 | channel[i].vu_l->set_progress_texture(active_bus_texture); | 
|---|
| 78 |  | 
|---|
| 79 | channel[i].vu_r->set_under_texture(active_bus_texture); | 
|---|
| 80 | channel[i].vu_r->set_tint_under(Color(0.75, 0.75, 0.75)); | 
|---|
| 81 | channel[i].vu_r->set_progress_texture(active_bus_texture); | 
|---|
| 82 | channel[i].prev_active = true; | 
|---|
| 83 | } | 
|---|
| 84 |  | 
|---|
| 85 | disabled_vu = get_editor_theme_icon(SNAME( "BusVuFrozen")); | 
|---|
| 86 |  | 
|---|
| 87 | Color solo_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1.0, 0.89, 0.22) : Color(1.0, 0.92, 0.44); | 
|---|
| 88 | Color mute_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1.0, 0.16, 0.16) : Color(1.0, 0.44, 0.44); | 
|---|
| 89 | Color bypass_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(0.13, 0.8, 1.0) : Color(0.44, 0.87, 1.0); | 
|---|
| 90 |  | 
|---|
| 91 | solo->set_icon(get_editor_theme_icon(SNAME( "AudioBusSolo"))); | 
|---|
| 92 | solo->add_theme_color_override( "icon_pressed_color", solo_color); | 
|---|
| 93 | mute->set_icon(get_editor_theme_icon(SNAME( "AudioBusMute"))); | 
|---|
| 94 | mute->add_theme_color_override( "icon_pressed_color", mute_color); | 
|---|
| 95 | bypass->set_icon(get_editor_theme_icon(SNAME( "AudioBusBypass"))); | 
|---|
| 96 | bypass->add_theme_color_override( "icon_pressed_color", bypass_color); | 
|---|
| 97 |  | 
|---|
| 98 | bus_options->set_icon(get_editor_theme_icon(SNAME( "GuiTabMenuHl"))); | 
|---|
| 99 |  | 
|---|
| 100 | audio_value_preview_label->add_theme_color_override( "font_color", get_theme_color(SNAME( "font_color"), SNAME( "TooltipLabel"))); | 
|---|
| 101 | audio_value_preview_label->add_theme_color_override( "font_shadow_color", get_theme_color(SNAME( "font_shadow_color"), SNAME( "TooltipLabel"))); | 
|---|
| 102 | audio_value_preview_box->add_theme_style_override( "panel", get_theme_stylebox(SNAME( "panel"), SNAME( "TooltipPanel"))); | 
|---|
| 103 |  | 
|---|
| 104 | for (int i = 0; i < effect_options->get_item_count(); i++) { | 
|---|
| 105 | String class_name = effect_options->get_item_metadata(i); | 
|---|
| 106 | Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(class_name); | 
|---|
| 107 | effect_options->set_item_icon(i, icon); | 
|---|
| 108 | } | 
|---|
| 109 | } break; | 
|---|
| 110 |  | 
|---|
| 111 | case NOTIFICATION_READY: { | 
|---|
| 112 | update_bus(); | 
|---|
| 113 | set_process(true); | 
|---|
| 114 | } break; | 
|---|
| 115 |  | 
|---|
| 116 | case NOTIFICATION_DRAW: { | 
|---|
| 117 | if (is_master) { | 
|---|
| 118 | draw_style_box(get_theme_stylebox(SNAME( "disabled"), SNAME( "Button")), Rect2(Vector2(), get_size())); | 
|---|
| 119 | } else if (has_focus()) { | 
|---|
| 120 | draw_style_box(get_theme_stylebox(SNAME( "focus"), SNAME( "Button")), Rect2(Vector2(), get_size())); | 
|---|
| 121 | } else { | 
|---|
| 122 | draw_style_box(get_theme_stylebox(SNAME( "panel"), SNAME( "TabContainer")), Rect2(Vector2(), get_size())); | 
|---|
| 123 | } | 
|---|
| 124 |  | 
|---|
| 125 | if (get_index() != 0 && hovering_drop) { | 
|---|
| 126 | Color accent = get_theme_color(SNAME( "accent_color"), EditorStringName(Editor)); | 
|---|
| 127 | accent.a *= 0.7; | 
|---|
| 128 | draw_rect(Rect2(Point2(), get_size()), accent, false); | 
|---|
| 129 | } | 
|---|
| 130 | } break; | 
|---|
| 131 |  | 
|---|
| 132 | case NOTIFICATION_PROCESS: { | 
|---|
| 133 | if (cc != AudioServer::get_singleton()->get_bus_channels(get_index())) { | 
|---|
| 134 | cc = AudioServer::get_singleton()->get_bus_channels(get_index()); | 
|---|
| 135 | _update_visible_channels(); | 
|---|
| 136 | } | 
|---|
| 137 |  | 
|---|
| 138 | for (int i = 0; i < cc; i++) { | 
|---|
| 139 | float real_peak[2] = { -100, -100 }; | 
|---|
| 140 | bool activity_found = false; | 
|---|
| 141 |  | 
|---|
| 142 | if (AudioServer::get_singleton()->is_bus_channel_active(get_index(), i)) { | 
|---|
| 143 | activity_found = true; | 
|---|
| 144 | real_peak[0] = MAX(real_peak[0], AudioServer::get_singleton()->get_bus_peak_volume_left_db(get_index(), i)); | 
|---|
| 145 | real_peak[1] = MAX(real_peak[1], AudioServer::get_singleton()->get_bus_peak_volume_right_db(get_index(), i)); | 
|---|
| 146 | } | 
|---|
| 147 |  | 
|---|
| 148 | if (real_peak[0] > channel[i].peak_l) { | 
|---|
| 149 | channel[i].peak_l = real_peak[0]; | 
|---|
| 150 | } else { | 
|---|
| 151 | channel[i].peak_l -= get_process_delta_time() * 60.0; | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 | if (real_peak[1] > channel[i].peak_r) { | 
|---|
| 155 | channel[i].peak_r = real_peak[1]; | 
|---|
| 156 | } else { | 
|---|
| 157 | channel[i].peak_r -= get_process_delta_time() * 60.0; | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | channel[i].vu_l->set_value(channel[i].peak_l); | 
|---|
| 161 | channel[i].vu_r->set_value(channel[i].peak_r); | 
|---|
| 162 |  | 
|---|
| 163 | if (activity_found != channel[i].prev_active) { | 
|---|
| 164 | if (activity_found) { | 
|---|
| 165 | channel[i].vu_l->set_over_texture(Ref<Texture2D>()); | 
|---|
| 166 | channel[i].vu_r->set_over_texture(Ref<Texture2D>()); | 
|---|
| 167 | } else { | 
|---|
| 168 | channel[i].vu_l->set_over_texture(disabled_vu); | 
|---|
| 169 | channel[i].vu_r->set_over_texture(disabled_vu); | 
|---|
| 170 | } | 
|---|
| 171 |  | 
|---|
| 172 | channel[i].prev_active = activity_found; | 
|---|
| 173 | } | 
|---|
| 174 | } | 
|---|
| 175 | } break; | 
|---|
| 176 |  | 
|---|
| 177 | case NOTIFICATION_VISIBILITY_CHANGED: { | 
|---|
| 178 | for (int i = 0; i < CHANNELS_MAX; i++) { | 
|---|
| 179 | channel[i].peak_l = -100; | 
|---|
| 180 | channel[i].peak_r = -100; | 
|---|
| 181 | channel[i].prev_active = true; | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | set_process(is_visible_in_tree()); | 
|---|
| 185 | } break; | 
|---|
| 186 |  | 
|---|
| 187 | case NOTIFICATION_MOUSE_EXIT: | 
|---|
| 188 | case NOTIFICATION_DRAG_END: { | 
|---|
| 189 | if (hovering_drop) { | 
|---|
| 190 | hovering_drop = false; | 
|---|
| 191 | queue_redraw(); | 
|---|
| 192 | } | 
|---|
| 193 | } break; | 
|---|
| 194 | } | 
|---|
| 195 | } | 
|---|
| 196 |  | 
|---|
| 197 | void EditorAudioBus::update_send() { | 
|---|
| 198 | send->clear(); | 
|---|
| 199 | if (is_master) { | 
|---|
| 200 | send->set_disabled(true); | 
|---|
| 201 | send->set_text(TTR( "Speakers")); | 
|---|
| 202 | } else { | 
|---|
| 203 | send->set_disabled(false); | 
|---|
| 204 | StringName current_send = AudioServer::get_singleton()->get_bus_send(get_index()); | 
|---|
| 205 | int current_send_index = 0; //by default to master | 
|---|
| 206 |  | 
|---|
| 207 | for (int i = 0; i < get_index(); i++) { | 
|---|
| 208 | StringName send_name = AudioServer::get_singleton()->get_bus_name(i); | 
|---|
| 209 | send->add_item(send_name); | 
|---|
| 210 | if (send_name == current_send) { | 
|---|
| 211 | current_send_index = i; | 
|---|
| 212 | } | 
|---|
| 213 | } | 
|---|
| 214 |  | 
|---|
| 215 | send->select(current_send_index); | 
|---|
| 216 | } | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | void EditorAudioBus::update_bus() { | 
|---|
| 220 | if (updating_bus) { | 
|---|
| 221 | return; | 
|---|
| 222 | } | 
|---|
| 223 |  | 
|---|
| 224 | updating_bus = true; | 
|---|
| 225 |  | 
|---|
| 226 | int index = get_index(); | 
|---|
| 227 |  | 
|---|
| 228 | float db_value = AudioServer::get_singleton()->get_bus_volume_db(index); | 
|---|
| 229 | slider->set_value(_scaled_db_to_normalized_volume(db_value)); | 
|---|
| 230 | track_name->set_text(AudioServer::get_singleton()->get_bus_name(index)); | 
|---|
| 231 | if (is_master) { | 
|---|
| 232 | track_name->set_editable(false); | 
|---|
| 233 | } | 
|---|
| 234 |  | 
|---|
| 235 | solo->set_pressed(AudioServer::get_singleton()->is_bus_solo(index)); | 
|---|
| 236 | mute->set_pressed(AudioServer::get_singleton()->is_bus_mute(index)); | 
|---|
| 237 | bypass->set_pressed(AudioServer::get_singleton()->is_bus_bypassing_effects(index)); | 
|---|
| 238 | // effects.. | 
|---|
| 239 | effects->clear(); | 
|---|
| 240 |  | 
|---|
| 241 | TreeItem *root = effects->create_item(); | 
|---|
| 242 | for (int i = 0; i < AudioServer::get_singleton()->get_bus_effect_count(index); i++) { | 
|---|
| 243 | Ref<AudioEffect> afx = AudioServer::get_singleton()->get_bus_effect(index, i); | 
|---|
| 244 |  | 
|---|
| 245 | TreeItem *fx = effects->create_item(root); | 
|---|
| 246 | fx->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); | 
|---|
| 247 | fx->set_editable(0, true); | 
|---|
| 248 | fx->set_checked(0, AudioServer::get_singleton()->is_bus_effect_enabled(index, i)); | 
|---|
| 249 | fx->set_text(0, afx->get_name()); | 
|---|
| 250 | fx->set_metadata(0, i); | 
|---|
| 251 | } | 
|---|
| 252 |  | 
|---|
| 253 | TreeItem *add = effects->create_item(root); | 
|---|
| 254 | add->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM); | 
|---|
| 255 | add->set_editable(0, true); | 
|---|
| 256 | add->set_selectable(0, false); | 
|---|
| 257 | add->set_text(0, TTR( "Add Effect")); | 
|---|
| 258 |  | 
|---|
| 259 | update_send(); | 
|---|
| 260 |  | 
|---|
| 261 | updating_bus = false; | 
|---|
| 262 | } | 
|---|
| 263 |  | 
|---|
| 264 | void EditorAudioBus::_name_changed(const String &p_new_name) { | 
|---|
| 265 | if (updating_bus) { | 
|---|
| 266 | return; | 
|---|
| 267 | } | 
|---|
| 268 | updating_bus = true; | 
|---|
| 269 | track_name->release_focus(); | 
|---|
| 270 |  | 
|---|
| 271 | if (p_new_name == AudioServer::get_singleton()->get_bus_name(get_index())) { | 
|---|
| 272 | updating_bus = false; | 
|---|
| 273 | return; | 
|---|
| 274 | } | 
|---|
| 275 |  | 
|---|
| 276 | String attempt = p_new_name; | 
|---|
| 277 | int attempts = 1; | 
|---|
| 278 |  | 
|---|
| 279 | while (true) { | 
|---|
| 280 | bool name_free = true; | 
|---|
| 281 | for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { | 
|---|
| 282 | if (AudioServer::get_singleton()->get_bus_name(i) == attempt) { | 
|---|
| 283 | name_free = false; | 
|---|
| 284 | break; | 
|---|
| 285 | } | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|
| 288 | if (name_free) { | 
|---|
| 289 | break; | 
|---|
| 290 | } | 
|---|
| 291 |  | 
|---|
| 292 | attempts++; | 
|---|
| 293 | attempt = p_new_name + " "+ itos(attempts); | 
|---|
| 294 | } | 
|---|
| 295 |  | 
|---|
| 296 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 297 |  | 
|---|
| 298 | StringName current = AudioServer::get_singleton()->get_bus_name(get_index()); | 
|---|
| 299 |  | 
|---|
| 300 | ur->create_action(TTR( "Rename Audio Bus")); | 
|---|
| 301 | ur->add_do_method(buses, "_set_renaming_buses", true); | 
|---|
| 302 | ur->add_undo_method(buses, "_set_renaming_buses", true); | 
|---|
| 303 |  | 
|---|
| 304 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_name", get_index(), attempt); | 
|---|
| 305 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_name", get_index(), current); | 
|---|
| 306 |  | 
|---|
| 307 | for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { | 
|---|
| 308 | if (AudioServer::get_singleton()->get_bus_send(i) == current) { | 
|---|
| 309 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_send", i, attempt); | 
|---|
| 310 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_send", i, current); | 
|---|
| 311 | } | 
|---|
| 312 | } | 
|---|
| 313 |  | 
|---|
| 314 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 315 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 316 |  | 
|---|
| 317 | ur->add_do_method(buses, "_update_sends"); | 
|---|
| 318 | ur->add_undo_method(buses, "_update_sends"); | 
|---|
| 319 |  | 
|---|
| 320 | ur->add_do_method(buses, "_set_renaming_buses", false); | 
|---|
| 321 | ur->add_undo_method(buses, "_set_renaming_buses", false); | 
|---|
| 322 | ur->commit_action(); | 
|---|
| 323 |  | 
|---|
| 324 | updating_bus = false; | 
|---|
| 325 | } | 
|---|
| 326 |  | 
|---|
| 327 | void EditorAudioBus::_volume_changed(float p_normalized) { | 
|---|
| 328 | if (updating_bus) { | 
|---|
| 329 | return; | 
|---|
| 330 | } | 
|---|
| 331 |  | 
|---|
| 332 | updating_bus = true; | 
|---|
| 333 |  | 
|---|
| 334 | const float p_db = this->_normalized_volume_to_scaled_db(p_normalized); | 
|---|
| 335 |  | 
|---|
| 336 | if (Input::get_singleton()->is_key_pressed(Key::CTRL)) { | 
|---|
| 337 | // Snap the value when holding Ctrl for easier editing. | 
|---|
| 338 | // To do so, it needs to be converted back to normalized volume (as the slider uses that unit). | 
|---|
| 339 | slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db))); | 
|---|
| 340 | } | 
|---|
| 341 |  | 
|---|
| 342 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 343 | ur->create_action(TTR( "Change Audio Bus Volume"), UndoRedo::MERGE_ENDS); | 
|---|
| 344 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", get_index(), p_db); | 
|---|
| 345 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", get_index(), AudioServer::get_singleton()->get_bus_volume_db(get_index())); | 
|---|
| 346 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 347 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 348 | ur->commit_action(); | 
|---|
| 349 |  | 
|---|
| 350 | updating_bus = false; | 
|---|
| 351 | } | 
|---|
| 352 |  | 
|---|
| 353 | float EditorAudioBus::_normalized_volume_to_scaled_db(float normalized) { | 
|---|
| 354 | /* There are three different formulas for the conversion from normalized | 
|---|
| 355 | * values to relative decibal values. | 
|---|
| 356 | * One formula is an exponential graph which intends to counteract | 
|---|
| 357 | * the logarithmic nature of human hearing. This is an approximation | 
|---|
| 358 | * of the behavior of a 'logarithmic potentiometer' found on most | 
|---|
| 359 | * musical instruments and also emulated in popular software. | 
|---|
| 360 | * The other two equations are hand-tuned linear tapers that intend to | 
|---|
| 361 | * try to ease the exponential equation in areas where it makes sense.*/ | 
|---|
| 362 |  | 
|---|
| 363 | if (normalized > 0.6f) { | 
|---|
| 364 | return 22.22f * normalized - 16.2f; | 
|---|
| 365 | } else if (normalized < 0.05f) { | 
|---|
| 366 | return 830.72 * normalized - 80.0f; | 
|---|
| 367 | } else { | 
|---|
| 368 | return 45.0f * Math::pow(normalized - 1.0, 3); | 
|---|
| 369 | } | 
|---|
| 370 | } | 
|---|
| 371 |  | 
|---|
| 372 | float EditorAudioBus::_scaled_db_to_normalized_volume(float db) { | 
|---|
| 373 | /* Inversion of equations found in _normalized_volume_to_scaled_db. | 
|---|
| 374 | * IMPORTANT: If one function changes, the other much change to reflect it. */ | 
|---|
| 375 | if (db > -2.88) { | 
|---|
| 376 | return (db + 16.2f) / 22.22f; | 
|---|
| 377 | } else if (db < -38.602f) { | 
|---|
| 378 | return (db + 80.00f) / 830.72f; | 
|---|
| 379 | } else { | 
|---|
| 380 | if (db < 0.0) { | 
|---|
| 381 | /* To accommodate for NaN on negative numbers for root, we will mirror the | 
|---|
| 382 | * results of the positive db range in order to get the desired numerical | 
|---|
| 383 | * value on the negative side. */ | 
|---|
| 384 | float positive_x = Math::pow(Math::abs(db) / 45.0f, 1.0f / 3.0f) + 1.0f; | 
|---|
| 385 | Vector2 translation = Vector2(1.0f, 0.0f) - Vector2(positive_x, Math::abs(db)); | 
|---|
| 386 | Vector2 reflected_position = Vector2(1.0, 0.0f) + translation; | 
|---|
| 387 | return reflected_position.x; | 
|---|
| 388 | } else { | 
|---|
| 389 | return Math::pow(db / 45.0f, 1.0f / 3.0f) + 1.0f; | 
|---|
| 390 | } | 
|---|
| 391 | } | 
|---|
| 392 | } | 
|---|
| 393 |  | 
|---|
| 394 | void EditorAudioBus::_show_value(float slider_value) { | 
|---|
| 395 | float db; | 
|---|
| 396 | if (Input::get_singleton()->is_key_pressed(Key::CTRL)) { | 
|---|
| 397 | // Display the correct (snapped) value when holding Ctrl | 
|---|
| 398 | db = Math::round(_normalized_volume_to_scaled_db(slider_value)); | 
|---|
| 399 | } else { | 
|---|
| 400 | db = _normalized_volume_to_scaled_db(slider_value); | 
|---|
| 401 | } | 
|---|
| 402 |  | 
|---|
| 403 | String text; | 
|---|
| 404 | if (Math::is_zero_approx(Math::snapped(db, 0.1))) { | 
|---|
| 405 | // Prevent displaying `-0.0 dB` and show ` 0.0 dB` instead. | 
|---|
| 406 | // The leading space makes the text visually line up with its positive/negative counterparts. | 
|---|
| 407 | text = " 0.0 dB"; | 
|---|
| 408 | } else { | 
|---|
| 409 | // Show an explicit `+` sign if positive. | 
|---|
| 410 | text = vformat( "%+.1f dB", db); | 
|---|
| 411 | } | 
|---|
| 412 |  | 
|---|
| 413 | // Also set the preview text as a standard Control tooltip. | 
|---|
| 414 | // This way, it can be seen when the slider is merely hovered (instead of dragged). | 
|---|
| 415 | slider->set_tooltip_text(text); | 
|---|
| 416 | audio_value_preview_label->set_text(text); | 
|---|
| 417 | const Vector2 slider_size = slider->get_size(); | 
|---|
| 418 | const Vector2 slider_position = slider->get_global_position(); | 
|---|
| 419 | const float vert_padding = 10.0f; | 
|---|
| 420 | const Vector2 box_position = Vector2(slider_size.x, (slider_size.y - vert_padding) * (1.0f - slider->get_value()) - vert_padding); | 
|---|
| 421 | audio_value_preview_box->set_position(slider_position + box_position); | 
|---|
| 422 | audio_value_preview_box->set_size(audio_value_preview_label->get_size()); | 
|---|
| 423 | if (slider->has_focus() && !audio_value_preview_box->is_visible()) { | 
|---|
| 424 | audio_value_preview_box->show(); | 
|---|
| 425 | } | 
|---|
| 426 | preview_timer->start(); | 
|---|
| 427 | } | 
|---|
| 428 |  | 
|---|
| 429 | void EditorAudioBus::_hide_value_preview() { | 
|---|
| 430 | audio_value_preview_box->hide(); | 
|---|
| 431 | } | 
|---|
| 432 |  | 
|---|
| 433 | void EditorAudioBus::_solo_toggled() { | 
|---|
| 434 | updating_bus = true; | 
|---|
| 435 |  | 
|---|
| 436 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 437 | ur->create_action(TTR( "Toggle Audio Bus Solo")); | 
|---|
| 438 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_solo", get_index(), solo->is_pressed()); | 
|---|
| 439 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_solo", get_index(), AudioServer::get_singleton()->is_bus_solo(get_index())); | 
|---|
| 440 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 441 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 442 | ur->commit_action(); | 
|---|
| 443 |  | 
|---|
| 444 | updating_bus = false; | 
|---|
| 445 | } | 
|---|
| 446 |  | 
|---|
| 447 | void EditorAudioBus::_mute_toggled() { | 
|---|
| 448 | updating_bus = true; | 
|---|
| 449 |  | 
|---|
| 450 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 451 | ur->create_action(TTR( "Toggle Audio Bus Mute")); | 
|---|
| 452 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_mute", get_index(), mute->is_pressed()); | 
|---|
| 453 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_mute", get_index(), AudioServer::get_singleton()->is_bus_mute(get_index())); | 
|---|
| 454 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 455 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 456 | ur->commit_action(); | 
|---|
| 457 |  | 
|---|
| 458 | updating_bus = false; | 
|---|
| 459 | } | 
|---|
| 460 |  | 
|---|
| 461 | void EditorAudioBus::_bypass_toggled() { | 
|---|
| 462 | updating_bus = true; | 
|---|
| 463 |  | 
|---|
| 464 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 465 | ur->create_action(TTR( "Toggle Audio Bus Bypass Effects")); | 
|---|
| 466 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_bypass_effects", get_index(), bypass->is_pressed()); | 
|---|
| 467 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_bypass_effects", get_index(), AudioServer::get_singleton()->is_bus_bypassing_effects(get_index())); | 
|---|
| 468 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 469 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 470 | ur->commit_action(); | 
|---|
| 471 |  | 
|---|
| 472 | updating_bus = false; | 
|---|
| 473 | } | 
|---|
| 474 |  | 
|---|
| 475 | void EditorAudioBus::_send_selected(int p_which) { | 
|---|
| 476 | updating_bus = true; | 
|---|
| 477 |  | 
|---|
| 478 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 479 | ur->create_action(TTR( "Select Audio Bus Send")); | 
|---|
| 480 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_send", get_index(), send->get_item_text(p_which)); | 
|---|
| 481 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_send", get_index(), AudioServer::get_singleton()->get_bus_send(get_index())); | 
|---|
| 482 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 483 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 484 | ur->commit_action(); | 
|---|
| 485 |  | 
|---|
| 486 | updating_bus = false; | 
|---|
| 487 | } | 
|---|
| 488 |  | 
|---|
| 489 | void EditorAudioBus::_effect_selected() { | 
|---|
| 490 | TreeItem *effect = effects->get_selected(); | 
|---|
| 491 | if (!effect) { | 
|---|
| 492 | return; | 
|---|
| 493 | } | 
|---|
| 494 | updating_bus = true; | 
|---|
| 495 |  | 
|---|
| 496 | if (effect->get_metadata(0) != Variant()) { | 
|---|
| 497 | int index = effect->get_metadata(0); | 
|---|
| 498 | Ref<AudioEffect> effect2 = AudioServer::get_singleton()->get_bus_effect(get_index(), index); | 
|---|
| 499 | if (effect2.is_valid()) { | 
|---|
| 500 | EditorNode::get_singleton()->push_item(effect2.ptr()); | 
|---|
| 501 | } | 
|---|
| 502 | } | 
|---|
| 503 |  | 
|---|
| 504 | updating_bus = false; | 
|---|
| 505 | } | 
|---|
| 506 |  | 
|---|
| 507 | void EditorAudioBus::_effect_edited() { | 
|---|
| 508 | if (updating_bus) { | 
|---|
| 509 | return; | 
|---|
| 510 | } | 
|---|
| 511 |  | 
|---|
| 512 | TreeItem *effect = effects->get_edited(); | 
|---|
| 513 | if (!effect) { | 
|---|
| 514 | return; | 
|---|
| 515 | } | 
|---|
| 516 |  | 
|---|
| 517 | if (effect->get_metadata(0) == Variant()) { | 
|---|
| 518 | Rect2 area = effects->get_item_rect(effect); | 
|---|
| 519 |  | 
|---|
| 520 | effect_options->set_position(effects->get_screen_position() + area.position + Vector2(0, area.size.y)); | 
|---|
| 521 | effect_options->reset_size(); | 
|---|
| 522 | effect_options->popup(); | 
|---|
| 523 | //add effect | 
|---|
| 524 | } else { | 
|---|
| 525 | int index = effect->get_metadata(0); | 
|---|
| 526 | updating_bus = true; | 
|---|
| 527 |  | 
|---|
| 528 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 529 | ur->create_action(TTR( "Select Audio Bus Send")); | 
|---|
| 530 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_effect_enabled", get_index(), index, effect->is_checked(0)); | 
|---|
| 531 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_effect_enabled", get_index(), index, AudioServer::get_singleton()->is_bus_effect_enabled(get_index(), index)); | 
|---|
| 532 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 533 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 534 | ur->commit_action(); | 
|---|
| 535 |  | 
|---|
| 536 | updating_bus = false; | 
|---|
| 537 | } | 
|---|
| 538 | } | 
|---|
| 539 |  | 
|---|
| 540 | void EditorAudioBus::_effect_add(int p_which) { | 
|---|
| 541 | if (updating_bus) { | 
|---|
| 542 | return; | 
|---|
| 543 | } | 
|---|
| 544 |  | 
|---|
| 545 | StringName name = effect_options->get_item_metadata(p_which); | 
|---|
| 546 |  | 
|---|
| 547 | Object *fx = ClassDB::instantiate(name); | 
|---|
| 548 | ERR_FAIL_NULL(fx); | 
|---|
| 549 | AudioEffect *afx = Object::cast_to<AudioEffect>(fx); | 
|---|
| 550 | ERR_FAIL_NULL(afx); | 
|---|
| 551 | Ref<AudioEffect> afxr = Ref<AudioEffect>(afx); | 
|---|
| 552 |  | 
|---|
| 553 | afxr->set_name(effect_options->get_item_text(p_which)); | 
|---|
| 554 |  | 
|---|
| 555 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 556 | ur->create_action(TTR( "Add Audio Bus Effect")); | 
|---|
| 557 | ur->add_do_method(AudioServer::get_singleton(), "add_bus_effect", get_index(), afxr, -1); | 
|---|
| 558 | ur->add_undo_method(AudioServer::get_singleton(), "remove_bus_effect", get_index(), AudioServer::get_singleton()->get_bus_effect_count(get_index())); | 
|---|
| 559 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 560 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 561 | ur->commit_action(); | 
|---|
| 562 | } | 
|---|
| 563 |  | 
|---|
| 564 | void EditorAudioBus::gui_input(const Ref<InputEvent> &p_event) { | 
|---|
| 565 | ERR_FAIL_COND(p_event.is_null()); | 
|---|
| 566 |  | 
|---|
| 567 | Ref<InputEventMouseButton> mb = p_event; | 
|---|
| 568 | if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { | 
|---|
| 569 | bus_popup->set_position(get_screen_position() + mb->get_position()); | 
|---|
| 570 | bus_popup->reset_size(); | 
|---|
| 571 | bus_popup->popup(); | 
|---|
| 572 | } | 
|---|
| 573 | } | 
|---|
| 574 |  | 
|---|
| 575 | void EditorAudioBus::_effects_gui_input(Ref<InputEvent> p_event) { | 
|---|
| 576 | Ref<InputEventKey> k = p_event; | 
|---|
| 577 | if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::KEY_DELETE) { | 
|---|
| 578 | TreeItem *current_effect = effects->get_selected(); | 
|---|
| 579 | if (current_effect && current_effect->get_metadata(0).get_type() == Variant::INT) { | 
|---|
| 580 | _delete_effect_pressed(0); | 
|---|
| 581 | accept_event(); | 
|---|
| 582 | } | 
|---|
| 583 | } | 
|---|
| 584 | } | 
|---|
| 585 |  | 
|---|
| 586 | void EditorAudioBus::(int p_option) { | 
|---|
| 587 | if (p_option == 2) { | 
|---|
| 588 | // Reset volume | 
|---|
| 589 | emit_signal(SNAME( "vol_reset_request")); | 
|---|
| 590 | } else if (p_option == 1) { | 
|---|
| 591 | emit_signal(SNAME( "delete_request")); | 
|---|
| 592 | } else if (p_option == 0) { | 
|---|
| 593 | //duplicate | 
|---|
| 594 | emit_signal(SNAME( "duplicate_request"), get_index()); | 
|---|
| 595 | } | 
|---|
| 596 | } | 
|---|
| 597 |  | 
|---|
| 598 | Variant EditorAudioBus::get_drag_data(const Point2 &p_point) { | 
|---|
| 599 | if (get_index() == 0) { | 
|---|
| 600 | return Variant(); | 
|---|
| 601 | } | 
|---|
| 602 |  | 
|---|
| 603 | Control *c = memnew(Control); | 
|---|
| 604 | Panel *p = memnew(Panel); | 
|---|
| 605 | c->add_child(p); | 
|---|
| 606 | p->set_modulate(Color(1, 1, 1, 0.7)); | 
|---|
| 607 | p->add_theme_style_override( "panel", get_theme_stylebox(SNAME( "focus"), SNAME( "Button"))); | 
|---|
| 608 | p->set_size(get_size()); | 
|---|
| 609 | p->set_position(-p_point); | 
|---|
| 610 | set_drag_preview(c); | 
|---|
| 611 | Dictionary d; | 
|---|
| 612 | d[ "type"] = "move_audio_bus"; | 
|---|
| 613 | d[ "index"] = get_index(); | 
|---|
| 614 |  | 
|---|
| 615 | if (get_index() < AudioServer::get_singleton()->get_bus_count() - 1) { | 
|---|
| 616 | emit_signal(SNAME( "drop_end_request")); | 
|---|
| 617 | } | 
|---|
| 618 |  | 
|---|
| 619 | return d; | 
|---|
| 620 | } | 
|---|
| 621 |  | 
|---|
| 622 | bool EditorAudioBus::can_drop_data(const Point2 &p_point, const Variant &p_data) const { | 
|---|
| 623 | if (get_index() == 0) { | 
|---|
| 624 | return false; | 
|---|
| 625 | } | 
|---|
| 626 |  | 
|---|
| 627 | Dictionary d = p_data; | 
|---|
| 628 | if (d.has( "type") && String(d[ "type"]) == "move_audio_bus"&& (int)d[ "index"] != get_index()) { | 
|---|
| 629 | hovering_drop = true; | 
|---|
| 630 | return true; | 
|---|
| 631 | } | 
|---|
| 632 |  | 
|---|
| 633 | return false; | 
|---|
| 634 | } | 
|---|
| 635 |  | 
|---|
| 636 | void EditorAudioBus::drop_data(const Point2 &p_point, const Variant &p_data) { | 
|---|
| 637 | Dictionary d = p_data; | 
|---|
| 638 | emit_signal(SNAME( "dropped"), d[ "index"], get_index()); | 
|---|
| 639 | } | 
|---|
| 640 |  | 
|---|
| 641 | Variant EditorAudioBus::get_drag_data_fw(const Point2 &p_point, Control *p_from) { | 
|---|
| 642 | TreeItem *item = effects->get_item_at_position(p_point); | 
|---|
| 643 | if (!item) { | 
|---|
| 644 | return Variant(); | 
|---|
| 645 | } | 
|---|
| 646 |  | 
|---|
| 647 | Variant md = item->get_metadata(0); | 
|---|
| 648 | if (md.get_type() == Variant::INT) { | 
|---|
| 649 | Dictionary fxd; | 
|---|
| 650 | fxd[ "type"] = "audio_bus_effect"; | 
|---|
| 651 | fxd[ "bus"] = get_index(); | 
|---|
| 652 | fxd[ "effect"] = md; | 
|---|
| 653 |  | 
|---|
| 654 | Label *l = memnew(Label); | 
|---|
| 655 | l->set_text(item->get_text(0)); | 
|---|
| 656 | effects->set_drag_preview(l); | 
|---|
| 657 |  | 
|---|
| 658 | return fxd; | 
|---|
| 659 | } | 
|---|
| 660 |  | 
|---|
| 661 | return Variant(); | 
|---|
| 662 | } | 
|---|
| 663 |  | 
|---|
| 664 | bool EditorAudioBus::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { | 
|---|
| 665 | Dictionary d = p_data; | 
|---|
| 666 | if (!d.has( "type") || String(d[ "type"]) != "audio_bus_effect") { | 
|---|
| 667 | return false; | 
|---|
| 668 | } | 
|---|
| 669 |  | 
|---|
| 670 | TreeItem *item = effects->get_item_at_position(p_point); | 
|---|
| 671 | if (!item) { | 
|---|
| 672 | return false; | 
|---|
| 673 | } | 
|---|
| 674 |  | 
|---|
| 675 | effects->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN); | 
|---|
| 676 |  | 
|---|
| 677 | return true; | 
|---|
| 678 | } | 
|---|
| 679 |  | 
|---|
| 680 | void EditorAudioBus::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { | 
|---|
| 681 | Dictionary d = p_data; | 
|---|
| 682 |  | 
|---|
| 683 | TreeItem *item = effects->get_item_at_position(p_point); | 
|---|
| 684 | if (!item) { | 
|---|
| 685 | return; | 
|---|
| 686 | } | 
|---|
| 687 | int pos = effects->get_drop_section_at_position(p_point); | 
|---|
| 688 | Variant md = item->get_metadata(0); | 
|---|
| 689 |  | 
|---|
| 690 | int paste_at; | 
|---|
| 691 | int bus = d[ "bus"]; | 
|---|
| 692 | int effect = d[ "effect"]; | 
|---|
| 693 |  | 
|---|
| 694 | if (md.get_type() == Variant::INT) { | 
|---|
| 695 | paste_at = md; | 
|---|
| 696 | if (pos > 0) { | 
|---|
| 697 | paste_at++; | 
|---|
| 698 | } | 
|---|
| 699 |  | 
|---|
| 700 | if (bus == get_index() && paste_at > effect) { | 
|---|
| 701 | paste_at--; | 
|---|
| 702 | } | 
|---|
| 703 | } else { | 
|---|
| 704 | paste_at = -1; | 
|---|
| 705 | } | 
|---|
| 706 |  | 
|---|
| 707 | bool enabled = AudioServer::get_singleton()->is_bus_effect_enabled(bus, effect); | 
|---|
| 708 |  | 
|---|
| 709 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 710 | ur->create_action(TTR( "Move Bus Effect")); | 
|---|
| 711 | ur->add_do_method(AudioServer::get_singleton(), "remove_bus_effect", bus, effect); | 
|---|
| 712 | ur->add_do_method(AudioServer::get_singleton(), "add_bus_effect", get_index(), AudioServer::get_singleton()->get_bus_effect(bus, effect), paste_at); | 
|---|
| 713 |  | 
|---|
| 714 | if (paste_at == -1) { | 
|---|
| 715 | paste_at = AudioServer::get_singleton()->get_bus_effect_count(get_index()); | 
|---|
| 716 | if (bus == get_index()) { | 
|---|
| 717 | paste_at--; | 
|---|
| 718 | } | 
|---|
| 719 | } | 
|---|
| 720 | if (!enabled) { | 
|---|
| 721 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_effect_enabled", get_index(), paste_at, false); | 
|---|
| 722 | } | 
|---|
| 723 |  | 
|---|
| 724 | ur->add_undo_method(AudioServer::get_singleton(), "remove_bus_effect", get_index(), paste_at); | 
|---|
| 725 | ur->add_undo_method(AudioServer::get_singleton(), "add_bus_effect", bus, AudioServer::get_singleton()->get_bus_effect(bus, effect), effect); | 
|---|
| 726 | if (!enabled) { | 
|---|
| 727 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_effect_enabled", bus, effect, false); | 
|---|
| 728 | } | 
|---|
| 729 |  | 
|---|
| 730 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 731 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 732 | if (get_index() != bus) { | 
|---|
| 733 | ur->add_do_method(buses, "_update_bus", bus); | 
|---|
| 734 | ur->add_undo_method(buses, "_update_bus", bus); | 
|---|
| 735 | } | 
|---|
| 736 | ur->commit_action(); | 
|---|
| 737 | } | 
|---|
| 738 |  | 
|---|
| 739 | void EditorAudioBus::_delete_effect_pressed(int p_option) { | 
|---|
| 740 | TreeItem *item = effects->get_selected(); | 
|---|
| 741 | if (!item) { | 
|---|
| 742 | return; | 
|---|
| 743 | } | 
|---|
| 744 |  | 
|---|
| 745 | if (item->get_metadata(0).get_type() != Variant::INT) { | 
|---|
| 746 | return; | 
|---|
| 747 | } | 
|---|
| 748 |  | 
|---|
| 749 | int index = item->get_metadata(0); | 
|---|
| 750 |  | 
|---|
| 751 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 752 | ur->create_action(TTR( "Delete Bus Effect")); | 
|---|
| 753 | ur->add_do_method(AudioServer::get_singleton(), "remove_bus_effect", get_index(), index); | 
|---|
| 754 | ur->add_undo_method(AudioServer::get_singleton(), "add_bus_effect", get_index(), AudioServer::get_singleton()->get_bus_effect(get_index(), index), index); | 
|---|
| 755 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_effect_enabled", get_index(), index, AudioServer::get_singleton()->is_bus_effect_enabled(get_index(), index)); | 
|---|
| 756 | ur->add_do_method(buses, "_update_bus", get_index()); | 
|---|
| 757 | ur->add_undo_method(buses, "_update_bus", get_index()); | 
|---|
| 758 | ur->commit_action(); | 
|---|
| 759 | } | 
|---|
| 760 |  | 
|---|
| 761 | void EditorAudioBus::_effect_rmb(const Vector2 &p_pos, MouseButton p_button) { | 
|---|
| 762 | if (p_button != MouseButton::RIGHT) { | 
|---|
| 763 | return; | 
|---|
| 764 | } | 
|---|
| 765 |  | 
|---|
| 766 | TreeItem *item = effects->get_selected(); | 
|---|
| 767 | if (!item) { | 
|---|
| 768 | return; | 
|---|
| 769 | } | 
|---|
| 770 |  | 
|---|
| 771 | if (item->get_metadata(0).get_type() != Variant::INT) { | 
|---|
| 772 | return; | 
|---|
| 773 | } | 
|---|
| 774 |  | 
|---|
| 775 | delete_effect_popup->set_position(get_screen_position() + get_local_mouse_position()); | 
|---|
| 776 | delete_effect_popup->reset_size(); | 
|---|
| 777 | delete_effect_popup->popup(); | 
|---|
| 778 | } | 
|---|
| 779 |  | 
|---|
| 780 | void EditorAudioBus::_bind_methods() { | 
|---|
| 781 | ClassDB::bind_method( "update_bus", &EditorAudioBus::update_bus); | 
|---|
| 782 | ClassDB::bind_method( "update_send", &EditorAudioBus::update_send); | 
|---|
| 783 |  | 
|---|
| 784 | ADD_SIGNAL(MethodInfo( "duplicate_request")); | 
|---|
| 785 | ADD_SIGNAL(MethodInfo( "delete_request")); | 
|---|
| 786 | ADD_SIGNAL(MethodInfo( "vol_reset_request")); | 
|---|
| 787 | ADD_SIGNAL(MethodInfo( "drop_end_request")); | 
|---|
| 788 | ADD_SIGNAL(MethodInfo( "dropped")); | 
|---|
| 789 | } | 
|---|
| 790 |  | 
|---|
| 791 | EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { | 
|---|
| 792 | buses = p_buses; | 
|---|
| 793 | is_master = p_is_master; | 
|---|
| 794 |  | 
|---|
| 795 | set_tooltip_text(TTR( "Drag & drop to rearrange.")); | 
|---|
| 796 |  | 
|---|
| 797 | VBoxContainer *vb = memnew(VBoxContainer); | 
|---|
| 798 | add_child(vb); | 
|---|
| 799 |  | 
|---|
| 800 | set_v_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 801 |  | 
|---|
| 802 | track_name = memnew(LineEdit); | 
|---|
| 803 | track_name->connect( "text_submitted", callable_mp(this, &EditorAudioBus::_name_changed)); | 
|---|
| 804 | track_name->connect( "focus_exited", callable_mp(this, &EditorAudioBus::_name_focus_exit)); | 
|---|
| 805 | vb->add_child(track_name); | 
|---|
| 806 |  | 
|---|
| 807 | HBoxContainer *hbc = memnew(HBoxContainer); | 
|---|
| 808 | vb->add_child(hbc); | 
|---|
| 809 | solo = memnew(Button); | 
|---|
| 810 | solo->set_flat(true); | 
|---|
| 811 | solo->set_toggle_mode(true); | 
|---|
| 812 | solo->set_tooltip_text(TTR( "Solo")); | 
|---|
| 813 | solo->set_focus_mode(FOCUS_NONE); | 
|---|
| 814 | solo->connect( "pressed", callable_mp(this, &EditorAudioBus::_solo_toggled)); | 
|---|
| 815 | hbc->add_child(solo); | 
|---|
| 816 | mute = memnew(Button); | 
|---|
| 817 | mute->set_flat(true); | 
|---|
| 818 | mute->set_toggle_mode(true); | 
|---|
| 819 | mute->set_tooltip_text(TTR( "Mute")); | 
|---|
| 820 | mute->set_focus_mode(FOCUS_NONE); | 
|---|
| 821 | mute->connect( "pressed", callable_mp(this, &EditorAudioBus::_mute_toggled)); | 
|---|
| 822 | hbc->add_child(mute); | 
|---|
| 823 | bypass = memnew(Button); | 
|---|
| 824 | bypass->set_flat(true); | 
|---|
| 825 | bypass->set_toggle_mode(true); | 
|---|
| 826 | bypass->set_tooltip_text(TTR( "Bypass")); | 
|---|
| 827 | bypass->set_focus_mode(FOCUS_NONE); | 
|---|
| 828 | bypass->connect( "pressed", callable_mp(this, &EditorAudioBus::_bypass_toggled)); | 
|---|
| 829 | hbc->add_child(bypass); | 
|---|
| 830 | hbc->add_spacer(); | 
|---|
| 831 |  | 
|---|
| 832 | Ref<StyleBoxEmpty> sbempty = memnew(StyleBoxEmpty); | 
|---|
| 833 | for (int i = 0; i < hbc->get_child_count(); i++) { | 
|---|
| 834 | Control *child = Object::cast_to<Control>(hbc->get_child(i)); | 
|---|
| 835 | child->add_theme_style_override( "normal", sbempty); | 
|---|
| 836 | child->add_theme_style_override( "hover", sbempty); | 
|---|
| 837 | child->add_theme_style_override( "focus", sbempty); | 
|---|
| 838 | child->add_theme_style_override( "pressed", sbempty); | 
|---|
| 839 | } | 
|---|
| 840 |  | 
|---|
| 841 | HSeparator *separator = memnew(HSeparator); | 
|---|
| 842 | separator->set_mouse_filter(MOUSE_FILTER_PASS); | 
|---|
| 843 | vb->add_child(separator); | 
|---|
| 844 |  | 
|---|
| 845 | HBoxContainer *hb = memnew(HBoxContainer); | 
|---|
| 846 | vb->add_child(hb); | 
|---|
| 847 | slider = memnew(VSlider); | 
|---|
| 848 | slider->set_min(0.0); | 
|---|
| 849 | slider->set_max(1.0); | 
|---|
| 850 | slider->set_step(0.0001); | 
|---|
| 851 | slider->set_clip_contents(false); | 
|---|
| 852 |  | 
|---|
| 853 | audio_value_preview_box = memnew(Panel); | 
|---|
| 854 | slider->add_child(audio_value_preview_box); | 
|---|
| 855 | audio_value_preview_box->set_as_top_level(true); | 
|---|
| 856 | audio_value_preview_box->set_mouse_filter(MOUSE_FILTER_PASS); | 
|---|
| 857 | audio_value_preview_box->hide(); | 
|---|
| 858 |  | 
|---|
| 859 | HBoxContainer *audioprev_hbc = memnew(HBoxContainer); | 
|---|
| 860 | audioprev_hbc->set_v_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 861 | audioprev_hbc->set_h_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 862 | audio_value_preview_box->add_child(audioprev_hbc); | 
|---|
| 863 |  | 
|---|
| 864 | audio_value_preview_label = memnew(Label); | 
|---|
| 865 | audio_value_preview_label->set_v_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 866 | audio_value_preview_label->set_h_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 867 | audio_value_preview_label->set_mouse_filter(MOUSE_FILTER_PASS); | 
|---|
| 868 | audioprev_hbc->add_child(audio_value_preview_label); | 
|---|
| 869 |  | 
|---|
| 870 | preview_timer = memnew(Timer); | 
|---|
| 871 | preview_timer->set_wait_time(0.8f); | 
|---|
| 872 | preview_timer->set_one_shot(true); | 
|---|
| 873 | add_child(preview_timer); | 
|---|
| 874 |  | 
|---|
| 875 | slider->connect( "value_changed", callable_mp(this, &EditorAudioBus::_volume_changed)); | 
|---|
| 876 | slider->connect( "value_changed", callable_mp(this, &EditorAudioBus::_show_value)); | 
|---|
| 877 | preview_timer->connect( "timeout", callable_mp(this, &EditorAudioBus::_hide_value_preview)); | 
|---|
| 878 | hb->add_child(slider); | 
|---|
| 879 |  | 
|---|
| 880 | cc = 0; | 
|---|
| 881 | for (int i = 0; i < CHANNELS_MAX; i++) { | 
|---|
| 882 | channel[i].vu_l = memnew(TextureProgressBar); | 
|---|
| 883 | channel[i].vu_l->set_fill_mode(TextureProgressBar::FILL_BOTTOM_TO_TOP); | 
|---|
| 884 | hb->add_child(channel[i].vu_l); | 
|---|
| 885 | channel[i].vu_l->set_min(-80); | 
|---|
| 886 | channel[i].vu_l->set_max(24); | 
|---|
| 887 | channel[i].vu_l->set_step(0.1); | 
|---|
| 888 |  | 
|---|
| 889 | channel[i].vu_r = memnew(TextureProgressBar); | 
|---|
| 890 | channel[i].vu_r->set_fill_mode(TextureProgressBar::FILL_BOTTOM_TO_TOP); | 
|---|
| 891 | hb->add_child(channel[i].vu_r); | 
|---|
| 892 | channel[i].vu_r->set_min(-80); | 
|---|
| 893 | channel[i].vu_r->set_max(24); | 
|---|
| 894 | channel[i].vu_r->set_step(0.1); | 
|---|
| 895 |  | 
|---|
| 896 | channel[i].peak_l = 0.0f; | 
|---|
| 897 | channel[i].peak_r = 0.0f; | 
|---|
| 898 | } | 
|---|
| 899 |  | 
|---|
| 900 | EditorAudioMeterNotches *scale = memnew(EditorAudioMeterNotches); | 
|---|
| 901 |  | 
|---|
| 902 | for (float db = 6.0f; db >= -80.0f; db -= 6.0f) { | 
|---|
| 903 | bool renderNotch = (db >= -6.0f || db == -24.0f || db == -72.0f); | 
|---|
| 904 | scale->add_notch(_scaled_db_to_normalized_volume(db), db, renderNotch); | 
|---|
| 905 | } | 
|---|
| 906 | scale->set_mouse_filter(MOUSE_FILTER_PASS); | 
|---|
| 907 | hb->add_child(scale); | 
|---|
| 908 |  | 
|---|
| 909 | effects = memnew(Tree); | 
|---|
| 910 | effects->set_hide_root(true); | 
|---|
| 911 | effects->set_custom_minimum_size(Size2(0, 80) * EDSCALE); | 
|---|
| 912 | effects->set_hide_folding(true); | 
|---|
| 913 | effects->set_v_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 914 | vb->add_child(effects); | 
|---|
| 915 | effects->connect( "item_edited", callable_mp(this, &EditorAudioBus::_effect_edited)); | 
|---|
| 916 | effects->connect( "cell_selected", callable_mp(this, &EditorAudioBus::_effect_selected)); | 
|---|
| 917 | effects->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); | 
|---|
| 918 | SET_DRAG_FORWARDING_GCD(effects, EditorAudioBus); | 
|---|
| 919 | effects->connect( "item_mouse_selected", callable_mp(this, &EditorAudioBus::_effect_rmb)); | 
|---|
| 920 | effects->set_allow_rmb_select(true); | 
|---|
| 921 | effects->set_focus_mode(FOCUS_CLICK); | 
|---|
| 922 | effects->set_allow_reselect(true); | 
|---|
| 923 | effects->connect( "gui_input", callable_mp(this, &EditorAudioBus::_effects_gui_input)); | 
|---|
| 924 |  | 
|---|
| 925 | send = memnew(OptionButton); | 
|---|
| 926 | send->set_clip_text(true); | 
|---|
| 927 | send->connect( "item_selected", callable_mp(this, &EditorAudioBus::_send_selected)); | 
|---|
| 928 | vb->add_child(send); | 
|---|
| 929 |  | 
|---|
| 930 | set_focus_mode(FOCUS_CLICK); | 
|---|
| 931 |  | 
|---|
| 932 | effect_options = memnew(PopupMenu); | 
|---|
| 933 | effect_options->connect( "index_pressed", callable_mp(this, &EditorAudioBus::_effect_add)); | 
|---|
| 934 | add_child(effect_options); | 
|---|
| 935 | List<StringName> effect_list; | 
|---|
| 936 | ClassDB::get_inheriters_from_class( "AudioEffect", &effect_list); | 
|---|
| 937 | effect_list.sort_custom<StringName::AlphCompare>(); | 
|---|
| 938 | for (const StringName &E : effect_list) { | 
|---|
| 939 | if (!ClassDB::can_instantiate(E) || ClassDB::is_virtual(E)) { | 
|---|
| 940 | continue; | 
|---|
| 941 | } | 
|---|
| 942 |  | 
|---|
| 943 | String name = E.operator String().replace( "AudioEffect", ""); | 
|---|
| 944 | effect_options->add_item(name); | 
|---|
| 945 | effect_options->set_item_metadata(-1, E); | 
|---|
| 946 | } | 
|---|
| 947 |  | 
|---|
| 948 | bus_options = memnew(MenuButton); | 
|---|
| 949 | bus_options->set_shortcut_context(this); | 
|---|
| 950 | bus_options->set_h_size_flags(SIZE_SHRINK_END); | 
|---|
| 951 | bus_options->set_anchor(SIDE_RIGHT, 0.0); | 
|---|
| 952 | bus_options->set_tooltip_text(TTR( "Bus Options")); | 
|---|
| 953 | hbc->add_child(bus_options); | 
|---|
| 954 |  | 
|---|
| 955 | bus_popup = bus_options->get_popup(); | 
|---|
| 956 | bus_popup->add_shortcut(ED_SHORTCUT( "audio_bus_editor/duplicate_selected_bus", TTR( "Duplicate Bus"), KeyModifierMask::CMD_OR_CTRL | Key::D)); | 
|---|
| 957 | bus_popup->add_shortcut(ED_SHORTCUT( "audio_bus_editor/delete_selected_bus", TTR( "Delete Bus"), Key::KEY_DELETE)); | 
|---|
| 958 | bus_popup->set_item_disabled(1, is_master); | 
|---|
| 959 | bus_popup->add_item(TTR( "Reset Volume")); | 
|---|
| 960 | bus_popup->connect( "index_pressed", callable_mp(this, &EditorAudioBus::_bus_popup_pressed)); | 
|---|
| 961 |  | 
|---|
| 962 | delete_effect_popup = memnew(PopupMenu); | 
|---|
| 963 | delete_effect_popup->add_item(TTR( "Delete Effect")); | 
|---|
| 964 | add_child(delete_effect_popup); | 
|---|
| 965 | delete_effect_popup->connect( "index_pressed", callable_mp(this, &EditorAudioBus::_delete_effect_pressed)); | 
|---|
| 966 | } | 
|---|
| 967 |  | 
|---|
| 968 | void EditorAudioBusDrop::_notification(int p_what) { | 
|---|
| 969 | switch (p_what) { | 
|---|
| 970 | case NOTIFICATION_DRAW: { | 
|---|
| 971 | draw_style_box(get_theme_stylebox(SNAME( "normal"), SNAME( "Button")), Rect2(Vector2(), get_size())); | 
|---|
| 972 |  | 
|---|
| 973 | if (hovering_drop) { | 
|---|
| 974 | Color accent = get_theme_color(SNAME( "accent_color"), EditorStringName(Editor)); | 
|---|
| 975 | accent.a *= 0.7; | 
|---|
| 976 | draw_rect(Rect2(Point2(), get_size()), accent, false); | 
|---|
| 977 | } | 
|---|
| 978 | } break; | 
|---|
| 979 |  | 
|---|
| 980 | case NOTIFICATION_MOUSE_ENTER: { | 
|---|
| 981 | if (!hovering_drop) { | 
|---|
| 982 | hovering_drop = true; | 
|---|
| 983 | queue_redraw(); | 
|---|
| 984 | } | 
|---|
| 985 | } break; | 
|---|
| 986 |  | 
|---|
| 987 | case NOTIFICATION_MOUSE_EXIT: | 
|---|
| 988 | case NOTIFICATION_DRAG_END: { | 
|---|
| 989 | if (hovering_drop) { | 
|---|
| 990 | hovering_drop = false; | 
|---|
| 991 | queue_redraw(); | 
|---|
| 992 | } | 
|---|
| 993 | } break; | 
|---|
| 994 | } | 
|---|
| 995 | } | 
|---|
| 996 |  | 
|---|
| 997 | bool EditorAudioBusDrop::can_drop_data(const Point2 &p_point, const Variant &p_data) const { | 
|---|
| 998 | Dictionary d = p_data; | 
|---|
| 999 | return (d.has( "type") && String(d[ "type"]) == "move_audio_bus"); | 
|---|
| 1000 | } | 
|---|
| 1001 |  | 
|---|
| 1002 | void EditorAudioBusDrop::drop_data(const Point2 &p_point, const Variant &p_data) { | 
|---|
| 1003 | Dictionary d = p_data; | 
|---|
| 1004 | emit_signal(SNAME( "dropped"), d[ "index"], AudioServer::get_singleton()->get_bus_count()); | 
|---|
| 1005 | } | 
|---|
| 1006 |  | 
|---|
| 1007 | void EditorAudioBusDrop::_bind_methods() { | 
|---|
| 1008 | ADD_SIGNAL(MethodInfo( "dropped")); | 
|---|
| 1009 | } | 
|---|
| 1010 |  | 
|---|
| 1011 | EditorAudioBusDrop::EditorAudioBusDrop() { | 
|---|
| 1012 | } | 
|---|
| 1013 |  | 
|---|
| 1014 | void EditorAudioBuses::_set_renaming_buses(bool p_renaming) { | 
|---|
| 1015 | renaming_buses = p_renaming; | 
|---|
| 1016 | } | 
|---|
| 1017 |  | 
|---|
| 1018 | void EditorAudioBuses::_update_buses() { | 
|---|
| 1019 | if (renaming_buses) { | 
|---|
| 1020 | // This case will be handled more gracefully, no need to trigger a full rebuild. | 
|---|
| 1021 | // This is possibly a mistake in the AudioServer, which fires bus_layout_changed | 
|---|
| 1022 | // on a rename. This may not be intended, but no way to tell at the moment. | 
|---|
| 1023 | return; | 
|---|
| 1024 | } | 
|---|
| 1025 |  | 
|---|
| 1026 | for (int i = bus_hb->get_child_count() - 1; i >= 0; i--) { | 
|---|
| 1027 | EditorAudioBus *audio_bus = Object::cast_to<EditorAudioBus>(bus_hb->get_child(i)); | 
|---|
| 1028 | if (audio_bus) { | 
|---|
| 1029 | bus_hb->remove_child(audio_bus); | 
|---|
| 1030 | audio_bus->queue_free(); | 
|---|
| 1031 | } | 
|---|
| 1032 | } | 
|---|
| 1033 |  | 
|---|
| 1034 | if (drop_end) { | 
|---|
| 1035 | bus_hb->remove_child(drop_end); | 
|---|
| 1036 | drop_end->queue_free(); | 
|---|
| 1037 | drop_end = nullptr; | 
|---|
| 1038 | } | 
|---|
| 1039 |  | 
|---|
| 1040 | for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { | 
|---|
| 1041 | bool is_master = (i == 0); | 
|---|
| 1042 | EditorAudioBus *audio_bus = memnew(EditorAudioBus(this, is_master)); | 
|---|
| 1043 | bus_hb->add_child(audio_bus); | 
|---|
| 1044 | audio_bus->connect( "delete_request", callable_mp(this, &EditorAudioBuses::_delete_bus).bind(audio_bus), CONNECT_DEFERRED); | 
|---|
| 1045 | audio_bus->connect( "duplicate_request", callable_mp(this, &EditorAudioBuses::_duplicate_bus), CONNECT_DEFERRED); | 
|---|
| 1046 | audio_bus->connect( "vol_reset_request", callable_mp(this, &EditorAudioBuses::_reset_bus_volume).bind(audio_bus), CONNECT_DEFERRED); | 
|---|
| 1047 | audio_bus->connect( "drop_end_request", callable_mp(this, &EditorAudioBuses::_request_drop_end)); | 
|---|
| 1048 | audio_bus->connect( "dropped", callable_mp(this, &EditorAudioBuses::_drop_at_index), CONNECT_DEFERRED); | 
|---|
| 1049 | } | 
|---|
| 1050 | } | 
|---|
| 1051 |  | 
|---|
| 1052 | EditorAudioBuses *EditorAudioBuses::register_editor() { | 
|---|
| 1053 | EditorAudioBuses *audio_buses = memnew(EditorAudioBuses); | 
|---|
| 1054 | EditorNode::get_singleton()->add_bottom_panel_item(TTR( "Audio"), audio_buses); | 
|---|
| 1055 | return audio_buses; | 
|---|
| 1056 | } | 
|---|
| 1057 |  | 
|---|
| 1058 | void EditorAudioBuses::_notification(int p_what) { | 
|---|
| 1059 | switch (p_what) { | 
|---|
| 1060 | case NOTIFICATION_ENTER_TREE: | 
|---|
| 1061 | case NOTIFICATION_THEME_CHANGED: { | 
|---|
| 1062 | bus_scroll->add_theme_style_override( "panel", get_theme_stylebox(SNAME( "panel"), SNAME( "Tree"))); | 
|---|
| 1063 | } break; | 
|---|
| 1064 |  | 
|---|
| 1065 | case NOTIFICATION_READY: { | 
|---|
| 1066 | _update_buses(); | 
|---|
| 1067 | } break; | 
|---|
| 1068 |  | 
|---|
| 1069 | case NOTIFICATION_DRAG_END: { | 
|---|
| 1070 | if (drop_end) { | 
|---|
| 1071 | bus_hb->remove_child(drop_end); | 
|---|
| 1072 | drop_end->queue_free(); | 
|---|
| 1073 | drop_end = nullptr; | 
|---|
| 1074 | } | 
|---|
| 1075 | } break; | 
|---|
| 1076 |  | 
|---|
| 1077 | case NOTIFICATION_PROCESS: { | 
|---|
| 1078 | // Check if anything was edited. | 
|---|
| 1079 | bool edited = AudioServer::get_singleton()->is_edited(); | 
|---|
| 1080 | for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { | 
|---|
| 1081 | for (int j = 0; j < AudioServer::get_singleton()->get_bus_effect_count(i); j++) { | 
|---|
| 1082 | Ref<AudioEffect> effect = AudioServer::get_singleton()->get_bus_effect(i, j); | 
|---|
| 1083 | if (effect->is_edited()) { | 
|---|
| 1084 | edited = true; | 
|---|
| 1085 | effect->set_edited(false); | 
|---|
| 1086 | } | 
|---|
| 1087 | } | 
|---|
| 1088 | } | 
|---|
| 1089 |  | 
|---|
| 1090 | AudioServer::get_singleton()->set_edited(false); | 
|---|
| 1091 |  | 
|---|
| 1092 | if (edited) { | 
|---|
| 1093 | save_timer->start(); | 
|---|
| 1094 | } | 
|---|
| 1095 | } break; | 
|---|
| 1096 | } | 
|---|
| 1097 | } | 
|---|
| 1098 |  | 
|---|
| 1099 | void EditorAudioBuses::_add_bus() { | 
|---|
| 1100 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 1101 |  | 
|---|
| 1102 | ur->create_action(TTR( "Add Audio Bus")); | 
|---|
| 1103 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_count", AudioServer::get_singleton()->get_bus_count() + 1); | 
|---|
| 1104 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_count", AudioServer::get_singleton()->get_bus_count()); | 
|---|
| 1105 | ur->add_do_method(this, "_update_buses"); | 
|---|
| 1106 | ur->add_undo_method(this, "_update_buses"); | 
|---|
| 1107 | ur->commit_action(); | 
|---|
| 1108 | } | 
|---|
| 1109 |  | 
|---|
| 1110 | void EditorAudioBuses::_update_bus(int p_index) { | 
|---|
| 1111 | if (p_index >= bus_hb->get_child_count()) { | 
|---|
| 1112 | return; | 
|---|
| 1113 | } | 
|---|
| 1114 |  | 
|---|
| 1115 | bus_hb->get_child(p_index)->call( "update_bus"); | 
|---|
| 1116 | } | 
|---|
| 1117 |  | 
|---|
| 1118 | void EditorAudioBuses::_update_sends() { | 
|---|
| 1119 | for (int i = 0; i < bus_hb->get_child_count(); i++) { | 
|---|
| 1120 | bus_hb->get_child(i)->call( "update_send"); | 
|---|
| 1121 | } | 
|---|
| 1122 | } | 
|---|
| 1123 |  | 
|---|
| 1124 | void EditorAudioBuses::_delete_bus(Object *p_which) { | 
|---|
| 1125 | EditorAudioBus *bus = Object::cast_to<EditorAudioBus>(p_which); | 
|---|
| 1126 | int index = bus->get_index(); | 
|---|
| 1127 | if (index == 0) { | 
|---|
| 1128 | EditorNode::get_singleton()->show_warning(TTR( "Master bus can't be deleted!")); | 
|---|
| 1129 | return; | 
|---|
| 1130 | } | 
|---|
| 1131 |  | 
|---|
| 1132 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 1133 |  | 
|---|
| 1134 | ur->create_action(TTR( "Delete Audio Bus")); | 
|---|
| 1135 | ur->add_do_method(AudioServer::get_singleton(), "remove_bus", index); | 
|---|
| 1136 | ur->add_undo_method(AudioServer::get_singleton(), "add_bus", index); | 
|---|
| 1137 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_name", index, AudioServer::get_singleton()->get_bus_name(index)); | 
|---|
| 1138 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", index, AudioServer::get_singleton()->get_bus_volume_db(index)); | 
|---|
| 1139 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_send", index, AudioServer::get_singleton()->get_bus_send(index)); | 
|---|
| 1140 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_solo", index, AudioServer::get_singleton()->is_bus_solo(index)); | 
|---|
| 1141 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_mute", index, AudioServer::get_singleton()->is_bus_mute(index)); | 
|---|
| 1142 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_bypass_effects", index, AudioServer::get_singleton()->is_bus_bypassing_effects(index)); | 
|---|
| 1143 | for (int i = 0; i < AudioServer::get_singleton()->get_bus_effect_count(index); i++) { | 
|---|
| 1144 | ur->add_undo_method(AudioServer::get_singleton(), "add_bus_effect", index, AudioServer::get_singleton()->get_bus_effect(index, i)); | 
|---|
| 1145 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_effect_enabled", index, i, AudioServer::get_singleton()->is_bus_effect_enabled(index, i)); | 
|---|
| 1146 | } | 
|---|
| 1147 | ur->add_do_method(this, "_update_buses"); | 
|---|
| 1148 | ur->add_undo_method(this, "_update_buses"); | 
|---|
| 1149 | ur->commit_action(); | 
|---|
| 1150 | } | 
|---|
| 1151 |  | 
|---|
| 1152 | void EditorAudioBuses::_duplicate_bus(int p_which) { | 
|---|
| 1153 | int add_at_pos = p_which + 1; | 
|---|
| 1154 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 1155 | ur->create_action(TTR( "Duplicate Audio Bus")); | 
|---|
| 1156 | ur->add_do_method(AudioServer::get_singleton(), "add_bus", add_at_pos); | 
|---|
| 1157 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_name", add_at_pos, AudioServer::get_singleton()->get_bus_name(p_which) + " Copy"); | 
|---|
| 1158 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", add_at_pos, AudioServer::get_singleton()->get_bus_volume_db(p_which)); | 
|---|
| 1159 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_send", add_at_pos, AudioServer::get_singleton()->get_bus_send(p_which)); | 
|---|
| 1160 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_solo", add_at_pos, AudioServer::get_singleton()->is_bus_solo(p_which)); | 
|---|
| 1161 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_mute", add_at_pos, AudioServer::get_singleton()->is_bus_mute(p_which)); | 
|---|
| 1162 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_bypass_effects", add_at_pos, AudioServer::get_singleton()->is_bus_bypassing_effects(p_which)); | 
|---|
| 1163 | for (int i = 0; i < AudioServer::get_singleton()->get_bus_effect_count(p_which); i++) { | 
|---|
| 1164 | ur->add_do_method(AudioServer::get_singleton(), "add_bus_effect", add_at_pos, AudioServer::get_singleton()->get_bus_effect(p_which, i)); | 
|---|
| 1165 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_effect_enabled", add_at_pos, i, AudioServer::get_singleton()->is_bus_effect_enabled(p_which, i)); | 
|---|
| 1166 | } | 
|---|
| 1167 | ur->add_undo_method(AudioServer::get_singleton(), "remove_bus", add_at_pos); | 
|---|
| 1168 | ur->add_do_method(this, "_update_buses"); | 
|---|
| 1169 | ur->add_undo_method(this, "_update_buses"); | 
|---|
| 1170 | ur->commit_action(); | 
|---|
| 1171 | } | 
|---|
| 1172 |  | 
|---|
| 1173 | void EditorAudioBuses::_reset_bus_volume(Object *p_which) { | 
|---|
| 1174 | EditorAudioBus *bus = Object::cast_to<EditorAudioBus>(p_which); | 
|---|
| 1175 | int index = bus->get_index(); | 
|---|
| 1176 |  | 
|---|
| 1177 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 1178 | ur->create_action(TTR( "Reset Bus Volume")); | 
|---|
| 1179 | ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", index, 0.f); | 
|---|
| 1180 | ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", index, AudioServer::get_singleton()->get_bus_volume_db(index)); | 
|---|
| 1181 | ur->add_do_method(this, "_update_buses"); | 
|---|
| 1182 | ur->add_undo_method(this, "_update_buses"); | 
|---|
| 1183 | ur->commit_action(); | 
|---|
| 1184 | } | 
|---|
| 1185 |  | 
|---|
| 1186 | void EditorAudioBuses::_request_drop_end() { | 
|---|
| 1187 | if (!drop_end && bus_hb->get_child_count()) { | 
|---|
| 1188 | drop_end = memnew(EditorAudioBusDrop); | 
|---|
| 1189 |  | 
|---|
| 1190 | bus_hb->add_child(drop_end); | 
|---|
| 1191 | drop_end->set_custom_minimum_size(Object::cast_to<Control>(bus_hb->get_child(0))->get_size()); | 
|---|
| 1192 | drop_end->connect( "dropped", callable_mp(this, &EditorAudioBuses::_drop_at_index), CONNECT_DEFERRED); | 
|---|
| 1193 | } | 
|---|
| 1194 | } | 
|---|
| 1195 |  | 
|---|
| 1196 | void EditorAudioBuses::_drop_at_index(int p_bus, int p_index) { | 
|---|
| 1197 | EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); | 
|---|
| 1198 | ur->create_action(TTR( "Move Audio Bus")); | 
|---|
| 1199 |  | 
|---|
| 1200 | ur->add_do_method(AudioServer::get_singleton(), "move_bus", p_bus, p_index); | 
|---|
| 1201 | int real_bus = p_index > p_bus ? p_bus : p_bus + 1; | 
|---|
| 1202 | int real_index = p_index > p_bus ? p_index - 1 : p_index; | 
|---|
| 1203 | ur->add_undo_method(AudioServer::get_singleton(), "move_bus", real_index, real_bus); | 
|---|
| 1204 |  | 
|---|
| 1205 | ur->add_do_method(this, "_update_buses"); | 
|---|
| 1206 | ur->add_undo_method(this, "_update_buses"); | 
|---|
| 1207 | ur->commit_action(); | 
|---|
| 1208 | } | 
|---|
| 1209 |  | 
|---|
| 1210 | void EditorAudioBuses::_server_save() { | 
|---|
| 1211 | Ref<AudioBusLayout> state = AudioServer::get_singleton()->generate_bus_layout(); | 
|---|
| 1212 | ResourceSaver::save(state, edited_path); | 
|---|
| 1213 | } | 
|---|
| 1214 |  | 
|---|
| 1215 | void EditorAudioBuses::_select_layout() { | 
|---|
| 1216 | FileSystemDock::get_singleton()->select_file(edited_path); | 
|---|
| 1217 | } | 
|---|
| 1218 |  | 
|---|
| 1219 | void EditorAudioBuses::_save_as_layout() { | 
|---|
| 1220 | file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); | 
|---|
| 1221 | file_dialog->set_title(TTR( "Save Audio Bus Layout As...")); | 
|---|
| 1222 | file_dialog->set_current_path(edited_path); | 
|---|
| 1223 | file_dialog->popup_file_dialog(); | 
|---|
| 1224 | new_layout = false; | 
|---|
| 1225 | } | 
|---|
| 1226 |  | 
|---|
| 1227 | void EditorAudioBuses::_new_layout() { | 
|---|
| 1228 | file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); | 
|---|
| 1229 | file_dialog->set_title(TTR( "Location for New Layout...")); | 
|---|
| 1230 | file_dialog->set_current_path(edited_path); | 
|---|
| 1231 | file_dialog->popup_file_dialog(); | 
|---|
| 1232 | new_layout = true; | 
|---|
| 1233 | } | 
|---|
| 1234 |  | 
|---|
| 1235 | void EditorAudioBuses::_load_layout() { | 
|---|
| 1236 | file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); | 
|---|
| 1237 | file_dialog->set_title(TTR( "Open Audio Bus Layout")); | 
|---|
| 1238 | file_dialog->set_current_path(edited_path); | 
|---|
| 1239 | file_dialog->popup_file_dialog(); | 
|---|
| 1240 | new_layout = false; | 
|---|
| 1241 | } | 
|---|
| 1242 |  | 
|---|
| 1243 | void EditorAudioBuses::_load_default_layout() { | 
|---|
| 1244 | String layout_path = GLOBAL_GET( "audio/buses/default_bus_layout"); | 
|---|
| 1245 |  | 
|---|
| 1246 | Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); | 
|---|
| 1247 | if (state.is_null()) { | 
|---|
| 1248 | EditorNode::get_singleton()->show_warning(vformat(TTR( "There is no '%s' file."), layout_path)); | 
|---|
| 1249 | return; | 
|---|
| 1250 | } | 
|---|
| 1251 |  | 
|---|
| 1252 | edited_path = layout_path; | 
|---|
| 1253 | file->set_text(String(TTR( "Layout:")) + " "+ layout_path.get_file()); | 
|---|
| 1254 | AudioServer::get_singleton()->set_bus_layout(state); | 
|---|
| 1255 | _update_buses(); | 
|---|
| 1256 | EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY); | 
|---|
| 1257 | call_deferred(SNAME( "_select_layout")); | 
|---|
| 1258 | } | 
|---|
| 1259 |  | 
|---|
| 1260 | void EditorAudioBuses::_file_dialog_callback(const String &p_string) { | 
|---|
| 1261 | if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_OPEN_FILE) { | 
|---|
| 1262 | Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", ResourceFormatLoader::CACHE_MODE_IGNORE); | 
|---|
| 1263 | if (state.is_null()) { | 
|---|
| 1264 | EditorNode::get_singleton()->show_warning(TTR( "Invalid file, not an audio bus layout.")); | 
|---|
| 1265 | return; | 
|---|
| 1266 | } | 
|---|
| 1267 |  | 
|---|
| 1268 | edited_path = p_string; | 
|---|
| 1269 | file->set_text(String(TTR( "Layout:")) + " "+ p_string.get_file()); | 
|---|
| 1270 | AudioServer::get_singleton()->set_bus_layout(state); | 
|---|
| 1271 | _update_buses(); | 
|---|
| 1272 | EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY); | 
|---|
| 1273 | call_deferred(SNAME( "_select_layout")); | 
|---|
| 1274 |  | 
|---|
| 1275 | } else if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) { | 
|---|
| 1276 | if (new_layout) { | 
|---|
| 1277 | Ref<AudioBusLayout> empty_state; | 
|---|
| 1278 | empty_state.instantiate(); | 
|---|
| 1279 | AudioServer::get_singleton()->set_bus_layout(empty_state); | 
|---|
| 1280 | } | 
|---|
| 1281 |  | 
|---|
| 1282 | Error err = ResourceSaver::save(AudioServer::get_singleton()->generate_bus_layout(), p_string); | 
|---|
| 1283 |  | 
|---|
| 1284 | if (err != OK) { | 
|---|
| 1285 | EditorNode::get_singleton()->show_warning(vformat(TTR( "Error saving file: %s"), p_string)); | 
|---|
| 1286 | return; | 
|---|
| 1287 | } | 
|---|
| 1288 |  | 
|---|
| 1289 | edited_path = p_string; | 
|---|
| 1290 | file->set_text(String(TTR( "Layout:")) + " "+ p_string.get_file()); | 
|---|
| 1291 | _update_buses(); | 
|---|
| 1292 | EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY); | 
|---|
| 1293 | call_deferred(SNAME( "_select_layout")); | 
|---|
| 1294 | } | 
|---|
| 1295 | } | 
|---|
| 1296 |  | 
|---|
| 1297 | void EditorAudioBuses::_bind_methods() { | 
|---|
| 1298 | ClassDB::bind_method( "_set_renaming_buses", &EditorAudioBuses::_set_renaming_buses); | 
|---|
| 1299 | ClassDB::bind_method( "_update_buses", &EditorAudioBuses::_update_buses); | 
|---|
| 1300 | ClassDB::bind_method( "_update_bus", &EditorAudioBuses::_update_bus); | 
|---|
| 1301 | ClassDB::bind_method( "_update_sends", &EditorAudioBuses::_update_sends); | 
|---|
| 1302 | ClassDB::bind_method( "_select_layout", &EditorAudioBuses::_select_layout); | 
|---|
| 1303 | } | 
|---|
| 1304 |  | 
|---|
| 1305 | EditorAudioBuses::EditorAudioBuses() { | 
|---|
| 1306 | top_hb = memnew(HBoxContainer); | 
|---|
| 1307 | add_child(top_hb); | 
|---|
| 1308 |  | 
|---|
| 1309 | file = memnew(Label); | 
|---|
| 1310 | String layout_path = GLOBAL_GET( "audio/buses/default_bus_layout"); | 
|---|
| 1311 | file->set_text(String(TTR( "Layout:")) + " "+ layout_path.get_file()); | 
|---|
| 1312 | file->set_clip_text(true); | 
|---|
| 1313 | file->set_h_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 1314 | top_hb->add_child(file); | 
|---|
| 1315 |  | 
|---|
| 1316 | add = memnew(Button); | 
|---|
| 1317 | top_hb->add_child(add); | 
|---|
| 1318 | add->set_text(TTR( "Add Bus")); | 
|---|
| 1319 | add->set_tooltip_text(TTR( "Add a new Audio Bus to this layout.")); | 
|---|
| 1320 | add->connect( "pressed", callable_mp(this, &EditorAudioBuses::_add_bus)); | 
|---|
| 1321 |  | 
|---|
| 1322 | VSeparator *separator = memnew(VSeparator); | 
|---|
| 1323 | top_hb->add_child(separator); | 
|---|
| 1324 |  | 
|---|
| 1325 | load = memnew(Button); | 
|---|
| 1326 | load->set_text(TTR( "Load")); | 
|---|
| 1327 | load->set_tooltip_text(TTR( "Load an existing Bus Layout.")); | 
|---|
| 1328 | top_hb->add_child(load); | 
|---|
| 1329 | load->connect( "pressed", callable_mp(this, &EditorAudioBuses::_load_layout)); | 
|---|
| 1330 |  | 
|---|
| 1331 | save_as = memnew(Button); | 
|---|
| 1332 | save_as->set_text(TTR( "Save As")); | 
|---|
| 1333 | save_as->set_tooltip_text(TTR( "Save this Bus Layout to a file.")); | 
|---|
| 1334 | top_hb->add_child(save_as); | 
|---|
| 1335 | save_as->connect( "pressed", callable_mp(this, &EditorAudioBuses::_save_as_layout)); | 
|---|
| 1336 |  | 
|---|
| 1337 | _default = memnew(Button); | 
|---|
| 1338 | _default->set_text(TTR( "Load Default")); | 
|---|
| 1339 | _default->set_tooltip_text(TTR( "Load the default Bus Layout.")); | 
|---|
| 1340 | top_hb->add_child(_default); | 
|---|
| 1341 | _default->connect( "pressed", callable_mp(this, &EditorAudioBuses::_load_default_layout)); | 
|---|
| 1342 |  | 
|---|
| 1343 | _new = memnew(Button); | 
|---|
| 1344 | _new->set_text(TTR( "Create")); | 
|---|
| 1345 | _new->set_tooltip_text(TTR( "Create a new Bus Layout.")); | 
|---|
| 1346 | top_hb->add_child(_new); | 
|---|
| 1347 | _new->connect( "pressed", callable_mp(this, &EditorAudioBuses::_new_layout)); | 
|---|
| 1348 |  | 
|---|
| 1349 | bus_scroll = memnew(ScrollContainer); | 
|---|
| 1350 | bus_scroll->set_v_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 1351 | bus_scroll->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); | 
|---|
| 1352 | add_child(bus_scroll); | 
|---|
| 1353 | bus_hb = memnew(HBoxContainer); | 
|---|
| 1354 | bus_hb->set_v_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 1355 | bus_scroll->add_child(bus_hb); | 
|---|
| 1356 |  | 
|---|
| 1357 | save_timer = memnew(Timer); | 
|---|
| 1358 | save_timer->set_wait_time(0.8); | 
|---|
| 1359 | save_timer->set_one_shot(true); | 
|---|
| 1360 | add_child(save_timer); | 
|---|
| 1361 | save_timer->connect( "timeout", callable_mp(this, &EditorAudioBuses::_server_save)); | 
|---|
| 1362 |  | 
|---|
| 1363 | set_v_size_flags(SIZE_EXPAND_FILL); | 
|---|
| 1364 |  | 
|---|
| 1365 | edited_path = GLOBAL_GET( "audio/buses/default_bus_layout"); | 
|---|
| 1366 |  | 
|---|
| 1367 | file_dialog = memnew(EditorFileDialog); | 
|---|
| 1368 | List<String> ext; | 
|---|
| 1369 | ResourceLoader::get_recognized_extensions_for_type( "AudioBusLayout", &ext); | 
|---|
| 1370 | for (const String &E : ext) { | 
|---|
| 1371 | file_dialog->add_filter( "*."+ E, TTR( "Audio Bus Layout")); | 
|---|
| 1372 | } | 
|---|
| 1373 | add_child(file_dialog); | 
|---|
| 1374 | file_dialog->connect( "file_selected", callable_mp(this, &EditorAudioBuses::_file_dialog_callback)); | 
|---|
| 1375 |  | 
|---|
| 1376 | AudioServer::get_singleton()->connect( "bus_layout_changed", callable_mp(this, &EditorAudioBuses::_update_buses)); | 
|---|
| 1377 |  | 
|---|
| 1378 | set_process(true); | 
|---|
| 1379 | } | 
|---|
| 1380 |  | 
|---|
| 1381 | void EditorAudioBuses::open_layout(const String &p_path) { | 
|---|
| 1382 | EditorNode::get_singleton()->make_bottom_panel_item_visible(this); | 
|---|
| 1383 |  | 
|---|
| 1384 | Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); | 
|---|
| 1385 | if (state.is_null()) { | 
|---|
| 1386 | EditorNode::get_singleton()->show_warning(TTR( "Invalid file, not an audio bus layout.")); | 
|---|
| 1387 | return; | 
|---|
| 1388 | } | 
|---|
| 1389 |  | 
|---|
| 1390 | edited_path = p_path; | 
|---|
| 1391 | file->set_text(p_path.get_file()); | 
|---|
| 1392 | AudioServer::get_singleton()->set_bus_layout(state); | 
|---|
| 1393 | _update_buses(); | 
|---|
| 1394 | EditorUndoRedoManager::get_singleton()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY); | 
|---|
| 1395 | call_deferred(SNAME( "_select_layout")); | 
|---|
| 1396 | } | 
|---|
| 1397 |  | 
|---|
| 1398 | void AudioBusesEditorPlugin::edit(Object *p_node) { | 
|---|
| 1399 | if (Object::cast_to<AudioBusLayout>(p_node)) { | 
|---|
| 1400 | String path = Object::cast_to<AudioBusLayout>(p_node)->get_path(); | 
|---|
| 1401 | if (path.is_resource_file()) { | 
|---|
| 1402 | audio_bus_editor->open_layout(path); | 
|---|
| 1403 | } | 
|---|
| 1404 | } | 
|---|
| 1405 | } | 
|---|
| 1406 |  | 
|---|
| 1407 | bool AudioBusesEditorPlugin::handles(Object *p_node) const { | 
|---|
| 1408 | return (Object::cast_to<AudioBusLayout>(p_node) != nullptr); | 
|---|
| 1409 | } | 
|---|
| 1410 |  | 
|---|
| 1411 | void AudioBusesEditorPlugin::make_visible(bool p_visible) { | 
|---|
| 1412 | } | 
|---|
| 1413 |  | 
|---|
| 1414 | AudioBusesEditorPlugin::AudioBusesEditorPlugin(EditorAudioBuses *p_node) { | 
|---|
| 1415 | audio_bus_editor = p_node; | 
|---|
| 1416 | } | 
|---|
| 1417 |  | 
|---|
| 1418 | AudioBusesEditorPlugin::~AudioBusesEditorPlugin() { | 
|---|
| 1419 | } | 
|---|
| 1420 |  | 
|---|
| 1421 | void EditorAudioMeterNotches::add_notch(float p_normalized_offset, float p_db_value, bool p_render_value) { | 
|---|
| 1422 | notches.push_back(AudioNotch(p_normalized_offset, p_db_value, p_render_value)); | 
|---|
| 1423 | } | 
|---|
| 1424 |  | 
|---|
| 1425 | Size2 EditorAudioMeterNotches::get_minimum_size() const { | 
|---|
| 1426 | Ref<Font> font = get_theme_font(SNAME( "font"), SNAME( "Label")); | 
|---|
| 1427 | int font_size = get_theme_font_size(SNAME( "font_size"), SNAME( "Label")); | 
|---|
| 1428 | float font_height = font->get_height(font_size); | 
|---|
| 1429 |  | 
|---|
| 1430 | float width = 0; | 
|---|
| 1431 | float height = top_padding + btm_padding; | 
|---|
| 1432 |  | 
|---|
| 1433 | for (int i = 0; i < notches.size(); i++) { | 
|---|
| 1434 | if (notches[i].render_db_value) { | 
|---|
| 1435 | width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x); | 
|---|
| 1436 | height += font_height; | 
|---|
| 1437 | } | 
|---|
| 1438 | } | 
|---|
| 1439 | width += line_length + label_space; | 
|---|
| 1440 |  | 
|---|
| 1441 | return Size2(width, height); | 
|---|
| 1442 | } | 
|---|
| 1443 |  | 
|---|
| 1444 | void EditorAudioMeterNotches::_update_theme_item_cache() { | 
|---|
| 1445 | Control::_update_theme_item_cache(); | 
|---|
| 1446 |  | 
|---|
| 1447 | theme_cache.notch_color = get_theme_color(SNAME( "font_color"), EditorStringName(Editor)); | 
|---|
| 1448 |  | 
|---|
| 1449 | theme_cache.font = get_theme_font(SNAME( "font"), SNAME( "Label")); | 
|---|
| 1450 | theme_cache.font_size = get_theme_font_size(SNAME( "font_size"), SNAME( "Label")); | 
|---|
| 1451 | } | 
|---|
| 1452 |  | 
|---|
| 1453 | void EditorAudioMeterNotches::_bind_methods() { | 
|---|
| 1454 | ClassDB::bind_method( "add_notch", &EditorAudioMeterNotches::add_notch); | 
|---|
| 1455 | ClassDB::bind_method( "_draw_audio_notches", &EditorAudioMeterNotches::_draw_audio_notches); | 
|---|
| 1456 | } | 
|---|
| 1457 |  | 
|---|
| 1458 | void EditorAudioMeterNotches::_notification(int p_what) { | 
|---|
| 1459 | switch (p_what) { | 
|---|
| 1460 | case NOTIFICATION_DRAW: { | 
|---|
| 1461 | _draw_audio_notches(); | 
|---|
| 1462 | } break; | 
|---|
| 1463 | } | 
|---|
| 1464 | } | 
|---|
| 1465 |  | 
|---|
| 1466 | void EditorAudioMeterNotches::_draw_audio_notches() { | 
|---|
| 1467 | float font_height = theme_cache.font->get_height(theme_cache.font_size); | 
|---|
| 1468 |  | 
|---|
| 1469 | for (int i = 0; i < notches.size(); i++) { | 
|---|
| 1470 | AudioNotch n = notches[i]; | 
|---|
| 1471 | draw_line(Vector2(0, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding), | 
|---|
| 1472 | Vector2(line_length * EDSCALE, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding), | 
|---|
| 1473 | theme_cache.notch_color, | 
|---|
| 1474 | Math::round(EDSCALE)); | 
|---|
| 1475 |  | 
|---|
| 1476 | if (n.render_db_value) { | 
|---|
| 1477 | draw_string(theme_cache.font, | 
|---|
| 1478 | Vector2((line_length + label_space) * EDSCALE, | 
|---|
| 1479 | (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + (font_height / 4) + top_padding), | 
|---|
| 1480 | String::num(Math::abs(n.db_value)) + "dB", | 
|---|
| 1481 | HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size, | 
|---|
| 1482 | theme_cache.notch_color); | 
|---|
| 1483 | } | 
|---|
| 1484 | } | 
|---|
| 1485 | } | 
|---|
| 1486 |  | 
|---|