plugin_host窗口位置保, channel_rack控件
This commit is contained in:
parent
fbd7e63756
commit
cb3b2e0c6a
@ -12,6 +12,7 @@
|
||||
#include "spdlog/async.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/sinks/basic_file_sink.h"
|
||||
#include "thread_message/thread_message_hubs.h"
|
||||
|
||||
bool g_is_running = true;
|
||||
bool g_exit_requested = false;
|
||||
@ -50,6 +51,7 @@ void application::init(const window_params& in_window_params, int argc, char** a
|
||||
int application::run() {
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
while (!g_exit_requested) {
|
||||
g_main_thread_hub.process_messages();
|
||||
g_window_manager.tick();
|
||||
g_exit_requested = g_exit_requested || g_window_manager.should_close();
|
||||
tick(io.DeltaTime);
|
||||
|
@ -48,6 +48,10 @@ GLFWwindow* window_manager::create_plugin_host_window(plugin_host* host) {
|
||||
return host_window_map_[host];
|
||||
auto editor_size = host->get_editor_size();
|
||||
auto new_window = glfwCreateWindow(editor_size.x, editor_size.y, host->name.c_str(), nullptr, nullptr);
|
||||
if (host_window_pos_map_.contains(host)) {
|
||||
auto pos = host_window_pos_map_[host];
|
||||
glfwSetWindowPos(new_window, pos.x, pos.y);
|
||||
}
|
||||
host_window_map_[host] = new_window;
|
||||
return new_window;
|
||||
}
|
||||
@ -55,8 +59,11 @@ GLFWwindow* window_manager::create_plugin_host_window(plugin_host* host) {
|
||||
void window_manager::destroy_plugin_host_window(plugin_host* host) {
|
||||
if (!host_window_map_.contains(host))
|
||||
return;
|
||||
int x, y;
|
||||
glfwGetWindowPos(host_window_map_[host], &x, &y);
|
||||
glfwDestroyWindow(host_window_map_[host]);
|
||||
host_window_map_.erase(host);
|
||||
host_window_pos_map_[host] = ImVec2(x, y);
|
||||
}
|
||||
|
||||
void window_manager::resize_plugin_host_window(plugin_host* host, int width, int height) {
|
||||
@ -75,13 +82,11 @@ void window_manager::update_host_window() {
|
||||
std::vector<plugin_host*> host_editor_to_close;
|
||||
for (const auto& [host, window]: host_window_map_) {
|
||||
if (glfwWindowShouldClose(window)) {
|
||||
host->close_editor();
|
||||
glfwDestroyWindow(window);
|
||||
host_editor_to_close.push_back(host);
|
||||
}
|
||||
}
|
||||
for (auto host: host_editor_to_close) {
|
||||
host_window_map_.erase(host);
|
||||
host->try_close_editor();
|
||||
}
|
||||
idle_plugin_host_window();
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "misc/singleton/singleton.h"
|
||||
#include <map>
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
class plugin_host;
|
||||
|
||||
class window_manager : public singleton_t<window_manager> {
|
||||
@ -30,6 +32,7 @@ private:
|
||||
|
||||
GLFWwindow* main_window_;
|
||||
std::map<plugin_host*, GLFWwindow*> host_window_map_;
|
||||
std::map<plugin_host*, ImVec2> host_window_pos_map_;
|
||||
};
|
||||
|
||||
DEFINE_SINGLETON_INSTANCE(window_manager)
|
||||
|
@ -9,8 +9,28 @@ plugin_host::~plugin_host() {
|
||||
}
|
||||
|
||||
void plugin_host::try_open_editor() {
|
||||
if (!has_editor())
|
||||
return;
|
||||
editor_window = g_window_manager.create_plugin_host_window(this);
|
||||
open_editor(editor_window);
|
||||
editor_opened = true;
|
||||
}
|
||||
|
||||
void plugin_host::try_close_editor() {
|
||||
if (!has_editor())
|
||||
return;
|
||||
close_editor();
|
||||
editor_opened = false;
|
||||
g_window_manager.destroy_plugin_host_window(this);
|
||||
}
|
||||
|
||||
void plugin_host::toggle_editor() {
|
||||
if (!has_editor())
|
||||
return;
|
||||
if (editor_opened)
|
||||
try_close_editor();
|
||||
else
|
||||
try_open_editor();
|
||||
}
|
||||
|
||||
void plugin_host::init_channel_interface() {
|
||||
|
@ -23,8 +23,8 @@ public:
|
||||
virtual void process(uint32_t frame_num) = 0;
|
||||
|
||||
void try_open_editor();
|
||||
virtual void open_editor(GLFWwindow* window) = 0;
|
||||
virtual void close_editor() = 0;
|
||||
void try_close_editor();
|
||||
virtual void toggle_editor();
|
||||
virtual void idle_editor() {}
|
||||
|
||||
[[nodiscard]] virtual bool has_editor() const { return false; }
|
||||
@ -40,4 +40,8 @@ public:
|
||||
channel_interface* channel = nullptr;
|
||||
std::vector<mixer_track*> owner_tracks;
|
||||
GLFWwindow* editor_window = nullptr;
|
||||
bool editor_opened = false;
|
||||
protected:
|
||||
virtual void open_editor(GLFWwindow* window) = 0;
|
||||
virtual void close_editor() = 0;
|
||||
};
|
||||
|
@ -24,6 +24,28 @@ void plugin_host_manager::release() {
|
||||
}
|
||||
}
|
||||
|
||||
plugin_host* plugin_host_manager::create_instrument_plugin_host(const char* path) {
|
||||
auto host = load_plugin(path);
|
||||
if (host) {
|
||||
register_instrument_plugin(host);
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
void plugin_host_manager::remove_instrument_plugin_host(plugin_host* host) {
|
||||
g_audio_thread_hub.push_message([host, this]() {
|
||||
auto find = std::ranges::find(instrument_plugins_, host);
|
||||
if (find != instrument_plugins_.end()) {
|
||||
plugin_hosts_.erase(std::ranges::find(plugin_hosts_, host));
|
||||
instrument_plugins_.erase(find);
|
||||
g_main_thread_hub.push_message([host, this]() {
|
||||
on_instrument_removed.broadcast(host);
|
||||
delete host;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
plugin_host* plugin_host_manager::load_plugin(const char* path) {
|
||||
auto host = new vst2_plugin_host();
|
||||
try {
|
||||
@ -36,16 +58,21 @@ plugin_host* plugin_host_manager::load_plugin(const char* path) {
|
||||
host->init_channel_interface();
|
||||
host->on_update_buffer_size(g_audio_device_manager.get_buffer_size());
|
||||
host->on_update_sample_rate(g_audio_device_manager.get_sample_rate());
|
||||
plugin_hosts_.push_back(host);
|
||||
return host;
|
||||
}
|
||||
|
||||
void plugin_host_manager::register_instrument_plugin(plugin_host* host) {
|
||||
g_audio_thread_hub.push_message([this, host]() {
|
||||
instrument_track* instrument_track = g_mixer.create_instrument_track(host);
|
||||
host->channel->set_input_channel(instrument_track->get_channel_interface()->input_channel_nodes);
|
||||
host->channel->set_output_channel(instrument_track->get_channel_interface()->output_channel_nodes);
|
||||
host->owner_tracks.push_back(instrument_track);
|
||||
host->update_channel_node_name();
|
||||
plugin_hosts_.push_back(host);
|
||||
g_main_thread_hub.push_message([host, this]() {
|
||||
on_instrument_added.broadcast(host);
|
||||
});
|
||||
});
|
||||
return host;
|
||||
}
|
||||
|
||||
void plugin_host_manager::process(uint32_t in_frames) const {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "misc/delegates.h"
|
||||
#include "misc/singleton/singleton.h"
|
||||
|
||||
class plugin_host;
|
||||
@ -9,16 +10,23 @@ public:
|
||||
void init(singleton_initliazer& initliazer) override;
|
||||
void release() override;
|
||||
|
||||
plugin_host* load_plugin(const char* path);
|
||||
|
||||
plugin_host* create_instrument_plugin_host(const char* path);
|
||||
void remove_instrument_plugin_host(plugin_host* host);
|
||||
|
||||
const std::vector<plugin_host*>& get_plugin_hosts() { return plugin_hosts_; }
|
||||
void process(uint32_t in_frames) const;
|
||||
|
||||
const char* get_name() override { return "plugin_host_manager"; }
|
||||
private:
|
||||
|
||||
multicast_delegate<plugin_host*> on_instrument_added;
|
||||
multicast_delegate<plugin_host*> on_instrument_removed;
|
||||
private:
|
||||
plugin_host* load_plugin(const char* path);
|
||||
void register_instrument_plugin(plugin_host* host);
|
||||
void on_mixer_track_removed(mixer_track* track);
|
||||
|
||||
std::vector<plugin_host*> instrument_plugins_{};
|
||||
std::vector<plugin_host*> plugin_hosts_{};
|
||||
};
|
||||
|
||||
|
@ -216,20 +216,6 @@ void vst2_plugin_host::process(uint32_t frame_num) {
|
||||
effect_->processReplacing(effect_, channel->get_input_headers(), channel->get_output_headers(), frame_num);
|
||||
}
|
||||
|
||||
void vst2_plugin_host::open_editor(GLFWwindow* window) {
|
||||
if (!has_editor())
|
||||
return;
|
||||
void* window_handle = glfwGetWindowHandle(window);
|
||||
|
||||
dispatch(effEditOpen, 0, 0, window_handle);
|
||||
}
|
||||
|
||||
void vst2_plugin_host::close_editor() {
|
||||
if (!has_editor())
|
||||
return;
|
||||
dispatch(effEditClose);
|
||||
}
|
||||
|
||||
void vst2_plugin_host::idle_editor() {
|
||||
plugin_host::idle_editor();
|
||||
dispatch(effEditIdle);
|
||||
@ -259,6 +245,19 @@ std::string vst2_plugin_host::load_vendor() const {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void vst2_plugin_host::open_editor(GLFWwindow* window) {
|
||||
if (!has_editor())
|
||||
return;
|
||||
void* window_handle = glfwGetWindowHandle(window);
|
||||
|
||||
dispatch(effEditOpen, 0, 0, window_handle);
|
||||
}
|
||||
|
||||
void vst2_plugin_host::close_editor() {
|
||||
if (!has_editor())
|
||||
return;
|
||||
dispatch(effEditClose);
|
||||
}
|
||||
|
||||
VstIntPtr vst2_plugin_host::dispatch(VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) const {
|
||||
return effect_->dispatcher(effect_, opcode, index, value, ptr, opt);
|
||||
|
@ -22,14 +22,15 @@ public:
|
||||
|
||||
void process(uint32_t frame_num) override;
|
||||
|
||||
void open_editor(GLFWwindow* window) override;
|
||||
void close_editor() override;
|
||||
void idle_editor() override;
|
||||
[[nodiscard]] bool has_editor() const override;
|
||||
[[nodiscard]] ImVec2 get_editor_size() const override;
|
||||
|
||||
[[nodiscard]] std::string load_name() const override;
|
||||
[[nodiscard]] std::string load_vendor() const override;
|
||||
protected:
|
||||
void open_editor(GLFWwindow* window) override;
|
||||
void close_editor() override;
|
||||
private:
|
||||
VstIntPtr dispatch(VstInt32 opcode, VstInt32 index = 0, VstIntPtr value = 0, void* ptr = nullptr, float opt = 0) const;
|
||||
AEffect* effect_;
|
||||
|
@ -429,7 +429,7 @@ public:
|
||||
constexpr static const unsigned int INVALID_ID = (unsigned int)~0;
|
||||
private:
|
||||
unsigned int id_;
|
||||
static unsigned int CURRENT_ID;
|
||||
CORE_API static unsigned int CURRENT_ID;
|
||||
|
||||
static int get_new_id()
|
||||
{
|
||||
|
8
core/widget/compound_widget.cpp
Normal file
8
core/widget/compound_widget.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "compound_widget.h"
|
||||
|
||||
void compound_widget::set_content(const std::shared_ptr<widget>& content) {
|
||||
child_ = content;
|
||||
}
|
||||
|
||||
void compound_widget::on_paint(ImGuiIO& io) {
|
||||
}
|
10
core/widget/compound_widget.h
Normal file
10
core/widget/compound_widget.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "widget.h"
|
||||
|
||||
class compound_widget : public widget {
|
||||
public:
|
||||
void set_content(const std::shared_ptr<widget>& content);
|
||||
void on_paint(ImGuiIO& io) override;
|
||||
private:
|
||||
std::shared_ptr<widget> child_;
|
||||
};
|
1
core/widget/leaf_widget.cpp
Normal file
1
core/widget/leaf_widget.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "leaf_widget.h"
|
7
core/widget/leaf_widget.h
Normal file
7
core/widget/leaf_widget.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "widget.h"
|
||||
|
||||
class leaf_widget : public widget {
|
||||
public:
|
||||
|
||||
};
|
1
core/widget/panel_widget.cpp
Normal file
1
core/widget/panel_widget.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "panel_widget.h"
|
7
core/widget/panel_widget.h
Normal file
7
core/widget/panel_widget.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "widget.h"
|
||||
|
||||
class panel_widget : public widget {
|
||||
public:
|
||||
|
||||
};
|
11
core/widget/widget.cpp
Normal file
11
core/widget/widget.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "widget.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
ImGuiID widget::generate_widget_id() {
|
||||
// random number generator
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<ImGuiID> dis(0, std::numeric_limits<ImGuiID>::max());
|
||||
return dis(gen);
|
||||
}
|
16
core/widget/widget.h
Normal file
16
core/widget/widget.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
class geometry;
|
||||
|
||||
class CORE_API widget : public std::enable_shared_from_this<widget> {
|
||||
public:
|
||||
virtual ~widget() = default;
|
||||
|
||||
virtual void tick() {}
|
||||
virtual void on_paint(ImGuiIO& io) = 0;
|
||||
virtual void on_arrange_children(const geometry& allotted_geometry) {}
|
||||
[[nodiscard]] virtual ImVec2 compute_desired_size() const { return {0, 0}; }
|
||||
static ImGuiID generate_widget_id();
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user