You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-26 15:46:23 +00:00
MacOS: Embedded window support.
This commit is contained in:
@@ -35,25 +35,14 @@
|
||||
#include "scene/resources/style_box_flat.h"
|
||||
#include "scene/theme/theme_db.h"
|
||||
|
||||
void EmbeddedProcess::_notification(int p_what) {
|
||||
void EmbeddedProcessBase::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
window = get_window();
|
||||
} break;
|
||||
case NOTIFICATION_PROCESS: {
|
||||
if (updated_embedded_process_queued) {
|
||||
updated_embedded_process_queued = false;
|
||||
_update_embedded_process();
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_DRAW: {
|
||||
_draw();
|
||||
} break;
|
||||
case NOTIFICATION_RESIZED:
|
||||
case NOTIFICATION_VISIBILITY_CHANGED:
|
||||
case NOTIFICATION_WM_POSITION_CHANGED: {
|
||||
queue_update_embedded_process();
|
||||
} break;
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
focus_style_box = get_theme_stylebox(SNAME("FocusViewport"), EditorStringName(EditorStyles));
|
||||
Ref<StyleBoxFlat> focus_style_box_flat = focus_style_box;
|
||||
@@ -68,60 +57,43 @@ void EmbeddedProcess::_notification(int p_what) {
|
||||
margin_bottom_right = Point2i();
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_FOCUS_ENTER: {
|
||||
queue_update_embedded_process();
|
||||
} break;
|
||||
case NOTIFICATION_APPLICATION_FOCUS_IN: {
|
||||
application_has_focus = true;
|
||||
last_application_focus_time = OS::get_singleton()->get_ticks_msec();
|
||||
} break;
|
||||
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
|
||||
application_has_focus = false;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void EmbeddedProcess::set_window_size(const Size2i p_window_size) {
|
||||
void EmbeddedProcessBase::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("embedding_completed"));
|
||||
ADD_SIGNAL(MethodInfo("embedding_failed"));
|
||||
ADD_SIGNAL(MethodInfo("embedded_process_updated"));
|
||||
ADD_SIGNAL(MethodInfo("embedded_process_focused"));
|
||||
}
|
||||
|
||||
void EmbeddedProcessBase::_draw() {
|
||||
if (is_process_focused() && focus_style_box.is_valid()) {
|
||||
Size2 size = get_size();
|
||||
Rect2 r = Rect2(Point2(), size);
|
||||
focus_style_box->draw(get_canvas_item(), r);
|
||||
}
|
||||
}
|
||||
|
||||
void EmbeddedProcessBase::set_window_size(const Size2i &p_window_size) {
|
||||
if (window_size != p_window_size) {
|
||||
window_size = p_window_size;
|
||||
queue_update_embedded_process();
|
||||
}
|
||||
}
|
||||
|
||||
void EmbeddedProcess::set_keep_aspect(bool p_keep_aspect) {
|
||||
void EmbeddedProcessBase::set_keep_aspect(bool p_keep_aspect) {
|
||||
if (keep_aspect != p_keep_aspect) {
|
||||
keep_aspect = p_keep_aspect;
|
||||
queue_update_embedded_process();
|
||||
}
|
||||
}
|
||||
|
||||
Rect2i EmbeddedProcess::get_adjusted_embedded_window_rect(Rect2i p_rect) {
|
||||
Rect2i control_rect = Rect2i(p_rect.position + margin_top_left, (p_rect.size - get_margins_size()).maxi(1));
|
||||
if (window) {
|
||||
control_rect.position += window->get_position();
|
||||
}
|
||||
if (window_size != Size2i()) {
|
||||
Rect2i desired_rect = Rect2i();
|
||||
if (!keep_aspect && control_rect.size.x >= window_size.x && control_rect.size.y >= window_size.y) {
|
||||
// Fixed at the desired size.
|
||||
desired_rect.size = window_size;
|
||||
} else {
|
||||
float ratio = MIN((float)control_rect.size.x / window_size.x, (float)control_rect.size.y / window_size.y);
|
||||
desired_rect.size = Size2i(window_size.x * ratio, window_size.y * ratio).maxi(1);
|
||||
}
|
||||
desired_rect.position = Size2i(control_rect.position.x + ((control_rect.size.x - desired_rect.size.x) / 2), control_rect.position.y + ((control_rect.size.y - desired_rect.size.y) / 2));
|
||||
return desired_rect;
|
||||
} else {
|
||||
// Stretch, use all the control area.
|
||||
return control_rect;
|
||||
}
|
||||
}
|
||||
|
||||
Rect2i EmbeddedProcess::get_screen_embedded_window_rect() {
|
||||
Rect2i EmbeddedProcessBase::get_screen_embedded_window_rect() const {
|
||||
return get_adjusted_embedded_window_rect(get_global_rect());
|
||||
}
|
||||
|
||||
int EmbeddedProcess::get_margin_size(Side p_side) const {
|
||||
int EmbeddedProcessBase::get_margin_size(Side p_side) const {
|
||||
ERR_FAIL_INDEX_V((int)p_side, 4, 0);
|
||||
|
||||
switch (p_side) {
|
||||
@@ -138,18 +110,51 @@ int EmbeddedProcess::get_margin_size(Side p_side) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Size2 EmbeddedProcess::get_margins_size() {
|
||||
Size2 EmbeddedProcessBase::get_margins_size() const {
|
||||
return margin_top_left + margin_bottom_right;
|
||||
}
|
||||
|
||||
bool EmbeddedProcess::is_embedding_in_progress() {
|
||||
EmbeddedProcessBase::EmbeddedProcessBase() {
|
||||
set_focus_mode(FOCUS_ALL);
|
||||
}
|
||||
|
||||
EmbeddedProcessBase::~EmbeddedProcessBase() {
|
||||
}
|
||||
|
||||
Rect2i EmbeddedProcess::get_adjusted_embedded_window_rect(const Rect2i &p_rect) const {
|
||||
Rect2i control_rect = Rect2i(p_rect.position + margin_top_left, (p_rect.size - get_margins_size()).maxi(1));
|
||||
if (window) {
|
||||
control_rect.position += window->get_position();
|
||||
}
|
||||
if (window_size != Size2i()) {
|
||||
Rect2i desired_rect;
|
||||
if (!keep_aspect && control_rect.size.x >= window_size.x && control_rect.size.y >= window_size.y) {
|
||||
// Fixed at the desired size.
|
||||
desired_rect.size = window_size;
|
||||
} else {
|
||||
float ratio = MIN((float)control_rect.size.x / window_size.x, (float)control_rect.size.y / window_size.y);
|
||||
desired_rect.size = Size2i(window_size.x * ratio, window_size.y * ratio).maxi(1);
|
||||
}
|
||||
desired_rect.position = Size2i(control_rect.position.x + ((control_rect.size.x - desired_rect.size.x) / 2), control_rect.position.y + ((control_rect.size.y - desired_rect.size.y) / 2));
|
||||
return desired_rect;
|
||||
} else {
|
||||
// Stretch, use all the control area.
|
||||
return control_rect;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmbeddedProcess::is_embedding_in_progress() const {
|
||||
return !timer_embedding->is_stopped();
|
||||
}
|
||||
|
||||
bool EmbeddedProcess::is_embedding_completed() {
|
||||
bool EmbeddedProcess::is_embedding_completed() const {
|
||||
return embedding_completed;
|
||||
}
|
||||
|
||||
bool EmbeddedProcess::is_process_focused() const {
|
||||
return focused_process_id == current_process_id && has_focus();
|
||||
}
|
||||
|
||||
int EmbeddedProcess::get_embedded_pid() const {
|
||||
return current_process_id;
|
||||
}
|
||||
@@ -270,11 +275,29 @@ void EmbeddedProcess::_timer_embedding_timeout() {
|
||||
_try_embed_process();
|
||||
}
|
||||
|
||||
void EmbeddedProcess::_draw() {
|
||||
if (focused_process_id == current_process_id && has_focus() && focus_style_box.is_valid()) {
|
||||
Size2 size = get_size();
|
||||
Rect2 r = Rect2(Point2(), size);
|
||||
focus_style_box->draw(get_canvas_item(), r);
|
||||
void EmbeddedProcess::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_PROCESS: {
|
||||
if (updated_embedded_process_queued) {
|
||||
updated_embedded_process_queued = false;
|
||||
_update_embedded_process();
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_RESIZED:
|
||||
case NOTIFICATION_VISIBILITY_CHANGED:
|
||||
case NOTIFICATION_WM_POSITION_CHANGED: {
|
||||
queue_update_embedded_process();
|
||||
} break;
|
||||
case NOTIFICATION_APPLICATION_FOCUS_IN: {
|
||||
application_has_focus = true;
|
||||
last_application_focus_time = OS::get_singleton()->get_ticks_msec();
|
||||
} break;
|
||||
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
|
||||
application_has_focus = false;
|
||||
} break;
|
||||
case NOTIFICATION_FOCUS_ENTER: {
|
||||
queue_update_embedded_process();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,14 +409,8 @@ Window *EmbeddedProcess::_get_current_modal_window() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EmbeddedProcess::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("embedding_completed"));
|
||||
ADD_SIGNAL(MethodInfo("embedding_failed"));
|
||||
ADD_SIGNAL(MethodInfo("embedded_process_updated"));
|
||||
ADD_SIGNAL(MethodInfo("embedded_process_focused"));
|
||||
}
|
||||
|
||||
EmbeddedProcess::EmbeddedProcess() {
|
||||
EmbeddedProcess::EmbeddedProcess() :
|
||||
EmbeddedProcessBase() {
|
||||
timer_embedding = memnew(Timer);
|
||||
timer_embedding->set_wait_time(0.1);
|
||||
timer_embedding->set_one_shot(true);
|
||||
@@ -404,8 +421,6 @@ EmbeddedProcess::EmbeddedProcess() {
|
||||
timer_update_embedded_process->set_wait_time(0.1);
|
||||
add_child(timer_update_embedded_process);
|
||||
timer_update_embedded_process->connect("timeout", callable_mp(this, &EmbeddedProcess::_timer_update_embedded_process_timeout));
|
||||
|
||||
set_focus_mode(FOCUS_ALL);
|
||||
}
|
||||
|
||||
EmbeddedProcess::~EmbeddedProcess() {
|
||||
|
||||
@@ -32,8 +32,49 @@
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
|
||||
class EmbeddedProcess : public Control {
|
||||
GDCLASS(EmbeddedProcess, Control);
|
||||
class ScriptEditorDebugger;
|
||||
|
||||
class EmbeddedProcessBase : public Control {
|
||||
GDCLASS(EmbeddedProcessBase, Control);
|
||||
|
||||
void _draw();
|
||||
|
||||
protected:
|
||||
Ref<StyleBox> focus_style_box;
|
||||
Size2i window_size;
|
||||
bool keep_aspect = false;
|
||||
Point2i margin_top_left;
|
||||
Point2i margin_bottom_right;
|
||||
Window *window = nullptr;
|
||||
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
virtual void set_script_debugger(ScriptEditorDebugger *p_debugger) {}
|
||||
|
||||
virtual bool is_embedding_completed() const = 0;
|
||||
virtual bool is_embedding_in_progress() const = 0;
|
||||
virtual bool is_process_focused() const = 0;
|
||||
virtual void embed_process(OS::ProcessID p_pid) = 0;
|
||||
virtual int get_embedded_pid() const = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual void request_close() = 0;
|
||||
virtual void queue_update_embedded_process() = 0;
|
||||
|
||||
void set_window_size(const Size2i &p_window_size);
|
||||
void set_keep_aspect(bool p_keep_aspect);
|
||||
virtual Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const = 0;
|
||||
Rect2i get_screen_embedded_window_rect() const;
|
||||
int get_margin_size(Side p_side) const;
|
||||
Size2 get_margins_size() const;
|
||||
|
||||
EmbeddedProcessBase();
|
||||
virtual ~EmbeddedProcessBase();
|
||||
};
|
||||
|
||||
class EmbeddedProcess : public EmbeddedProcessBase {
|
||||
GDCLASS(EmbeddedProcess, EmbeddedProcessBase);
|
||||
|
||||
bool application_has_focus = true;
|
||||
uint64_t last_application_focus_time = 0;
|
||||
@@ -45,51 +86,37 @@ class EmbeddedProcess : public Control {
|
||||
bool updated_embedded_process_queued = false;
|
||||
bool last_updated_embedded_process_focused = false;
|
||||
|
||||
Window *window = nullptr;
|
||||
Timer *timer_embedding = nullptr;
|
||||
Timer *timer_update_embedded_process = nullptr;
|
||||
|
||||
const int embedding_timeout = 45000;
|
||||
|
||||
bool keep_aspect = false;
|
||||
Size2i window_size;
|
||||
Ref<StyleBox> focus_style_box;
|
||||
Point2i margin_top_left;
|
||||
Point2i margin_bottom_right;
|
||||
Rect2i last_global_rect;
|
||||
|
||||
void _try_embed_process();
|
||||
void _update_embedded_process();
|
||||
void _timer_embedding_timeout();
|
||||
void _timer_update_embedded_process_timeout();
|
||||
void _draw();
|
||||
void _check_mouse_over();
|
||||
void _check_focused_process_id();
|
||||
bool _is_embedded_process_updatable();
|
||||
Rect2i _get_global_embedded_window_rect();
|
||||
Window *_get_current_modal_window();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
void embed_process(OS::ProcessID p_pid);
|
||||
void reset();
|
||||
void request_close();
|
||||
bool is_embedding_in_progress() const override;
|
||||
bool is_embedding_completed() const override;
|
||||
bool is_process_focused() const override;
|
||||
void embed_process(OS::ProcessID p_pid) override;
|
||||
int get_embedded_pid() const override;
|
||||
void reset() override;
|
||||
void request_close() override;
|
||||
void queue_update_embedded_process() override;
|
||||
|
||||
void set_window_size(const Size2i p_window_size);
|
||||
void set_keep_aspect(bool p_keep_aspect);
|
||||
void queue_update_embedded_process();
|
||||
|
||||
Rect2i get_adjusted_embedded_window_rect(Rect2i p_rect);
|
||||
Rect2i get_screen_embedded_window_rect();
|
||||
int get_margin_size(Side p_side) const;
|
||||
Size2 get_margins_size();
|
||||
bool is_embedding_in_progress();
|
||||
bool is_embedding_completed();
|
||||
int get_embedded_pid() const;
|
||||
Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const override;
|
||||
|
||||
EmbeddedProcess();
|
||||
~EmbeddedProcess();
|
||||
~EmbeddedProcess() override;
|
||||
};
|
||||
|
||||
@@ -243,11 +243,17 @@ void GameView::_sessions_changed() {
|
||||
|
||||
_update_debugger_buttons();
|
||||
|
||||
#ifdef MACOS_ENABLED
|
||||
if (!embedded_script_debugger || !embedded_script_debugger->is_session_active() || embedded_script_debugger->get_remote_pid() != embedded_process->get_embedded_pid()) {
|
||||
_attach_script_debugger();
|
||||
}
|
||||
#else
|
||||
if (embedded_process->is_embedding_completed()) {
|
||||
if (!embedded_script_debugger || !embedded_script_debugger->is_session_active() || embedded_script_debugger->get_remote_pid() != embedded_process->get_embedded_pid()) {
|
||||
_attach_script_debugger();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GameView::_instance_starting_static(int p_idx, List<String> &r_arguments) {
|
||||
@@ -370,7 +376,9 @@ void GameView::_stop_pressed() {
|
||||
}
|
||||
|
||||
void GameView::_embedding_completed() {
|
||||
#ifndef MACOS_ENABLED
|
||||
_attach_script_debugger();
|
||||
#endif
|
||||
_update_ui();
|
||||
if (make_floating_on_play) {
|
||||
get_window()->set_flag(Window::FLAG_ALWAYS_ON_TOP, bool(GLOBAL_GET("display/window/size/always_on_top")));
|
||||
@@ -507,9 +515,11 @@ GameView::EmbedAvailability GameView::_get_embed_available() {
|
||||
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_WINDOW_EMBEDDING)) {
|
||||
return EMBED_NOT_AVAILABLE_FEATURE_NOT_SUPPORTED;
|
||||
}
|
||||
#ifndef MACOS_ENABLED
|
||||
if (get_tree()->get_root()->is_embedding_subwindows()) {
|
||||
return EMBED_NOT_AVAILABLE_SINGLE_WINDOW_MODE;
|
||||
}
|
||||
#endif
|
||||
String display_driver = GLOBAL_GET("display/display_server/driver");
|
||||
if (display_driver == "headless" || display_driver == "wayland") {
|
||||
return EMBED_NOT_AVAILABLE_PROJECT_DISPLAY_DRIVER;
|
||||
@@ -786,14 +796,19 @@ void GameView::_attach_script_debugger() {
|
||||
}
|
||||
|
||||
embedded_script_debugger = nullptr;
|
||||
for (int i = 0; EditorDebuggerNode::get_singleton()->get_debugger(i); i++) {
|
||||
ScriptEditorDebugger *script_debugger = EditorDebuggerNode::get_singleton()->get_debugger(i);
|
||||
int i = 0;
|
||||
while (ScriptEditorDebugger *script_debugger = EditorDebuggerNode::get_singleton()->get_debugger(i)) {
|
||||
if (script_debugger->is_session_active() && script_debugger->get_remote_pid() == embedded_process->get_embedded_pid()) {
|
||||
embedded_script_debugger = script_debugger;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
#ifdef MACOS_ENABLED
|
||||
embedded_process->set_script_debugger(embedded_script_debugger);
|
||||
#endif
|
||||
|
||||
if (embedded_script_debugger) {
|
||||
embedded_script_debugger->connect("remote_window_title_changed", callable_mp(this, &GameView::_remote_window_title_changed));
|
||||
embedded_script_debugger->connect("embed_shortcut_requested", callable_mp(this, &GameView::_handle_shortcut_requested));
|
||||
@@ -845,6 +860,12 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
|
||||
List<String>::Element *N = r_arguments.insert_before(user_args_element, "--wid");
|
||||
N = r_arguments.insert_after(N, itos(DisplayServer::get_singleton()->window_get_native_handle(DisplayServer::WINDOW_HANDLE, get_window()->get_window_id())));
|
||||
|
||||
#if MACOS_ENABLED
|
||||
r_arguments.push_back("--display-driver");
|
||||
r_arguments.push_back("embedded");
|
||||
r_arguments.push_back("--embedded");
|
||||
#endif
|
||||
|
||||
// Be sure to have the correct window size in the embedded_process control.
|
||||
_update_embed_window_size();
|
||||
Rect2i rect = embedded_process->get_screen_embedded_window_rect();
|
||||
@@ -931,11 +952,12 @@ void GameView::_feature_profile_changed() {
|
||||
node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_visible(is_3d_enabled);
|
||||
}
|
||||
|
||||
GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
|
||||
GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embedded_process, WindowWrapper *p_wrapper) {
|
||||
singleton = this;
|
||||
|
||||
debugger = p_debugger;
|
||||
window_wrapper = p_wrapper;
|
||||
embedded_process = p_embedded_process;
|
||||
|
||||
// Add some margin to the sides for better aesthetics.
|
||||
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
|
||||
@@ -1051,7 +1073,6 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
|
||||
camera_override_menu->set_h_size_flags(SIZE_SHRINK_END);
|
||||
camera_override_menu->set_tooltip_text(TTR("Camera Override Options"));
|
||||
camera_override_menu->set_accessibility_name(TTRC("Camera Override Options"));
|
||||
_camera_override_menu_id_pressed(EditorSettings::get_singleton()->get_project_metadata("game_view", "camera_override_mode", 0));
|
||||
|
||||
PopupMenu *menu = camera_override_menu->get_popup();
|
||||
menu->connect(SceneStringName(id_pressed), callable_mp(this, &GameView::_camera_override_menu_id_pressed));
|
||||
@@ -1061,6 +1082,7 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
|
||||
menu->add_radio_check_item(TTR("Manipulate In-Game"), CAMERA_MODE_INGAME);
|
||||
menu->set_item_checked(menu->get_item_index(CAMERA_MODE_INGAME), true);
|
||||
menu->add_radio_check_item(TTR("Manipulate From Editors"), CAMERA_MODE_EDITORS);
|
||||
_camera_override_menu_id_pressed(EditorSettings::get_singleton()->get_project_metadata("game_view", "camera_override_mode", 0));
|
||||
|
||||
embedding_separator = memnew(VSeparator);
|
||||
main_menu_hbox->add_child(embedding_separator);
|
||||
@@ -1118,7 +1140,6 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
|
||||
panel->set_theme_type_variation("GamePanel");
|
||||
panel->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
embedded_process = memnew(EmbeddedProcess);
|
||||
panel->add_child(embedded_process);
|
||||
embedded_process->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
|
||||
embedded_process->connect("embedding_failed", callable_mp(this, &GameView::_embedding_failed));
|
||||
@@ -1131,6 +1152,9 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
|
||||
state_container->add_theme_constant_override("margin_left", 8 * EDSCALE);
|
||||
state_container->add_theme_constant_override("margin_right", 8 * EDSCALE);
|
||||
state_container->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
|
||||
#ifdef MACOS_ENABLED
|
||||
state_container->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
|
||||
#endif
|
||||
panel->add_child(state_container);
|
||||
|
||||
state_label = memnew(Label());
|
||||
@@ -1156,7 +1180,7 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
|
||||
|
||||
///////
|
||||
|
||||
void GameViewPlugin::selected_notify() {
|
||||
void GameViewPluginBase::selected_notify() {
|
||||
if (_is_window_wrapper_enabled()) {
|
||||
#ifdef ANDROID_ENABLED
|
||||
notify_main_screen_changed(get_plugin_name());
|
||||
@@ -1168,7 +1192,7 @@ void GameViewPlugin::selected_notify() {
|
||||
}
|
||||
|
||||
#ifndef ANDROID_ENABLED
|
||||
void GameViewPlugin::make_visible(bool p_visible) {
|
||||
void GameViewPluginBase::make_visible(bool p_visible) {
|
||||
if (p_visible) {
|
||||
window_wrapper->show();
|
||||
} else {
|
||||
@@ -1176,35 +1200,54 @@ void GameViewPlugin::make_visible(bool p_visible) {
|
||||
}
|
||||
}
|
||||
|
||||
void GameViewPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
|
||||
void GameViewPluginBase::set_window_layout(Ref<ConfigFile> p_layout) {
|
||||
game_view->set_window_layout(p_layout);
|
||||
}
|
||||
|
||||
void GameViewPlugin::get_window_layout(Ref<ConfigFile> p_layout) {
|
||||
void GameViewPluginBase::get_window_layout(Ref<ConfigFile> p_layout) {
|
||||
game_view->get_window_layout(p_layout);
|
||||
}
|
||||
|
||||
void GameViewPluginBase::setup(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embedded_process) {
|
||||
debugger = p_debugger;
|
||||
|
||||
window_wrapper = memnew(WindowWrapper);
|
||||
window_wrapper->set_window_title(vformat(TTR("%s - Godot Engine"), TTR("Game Workspace")));
|
||||
window_wrapper->set_margins_enabled(true);
|
||||
|
||||
game_view = memnew(GameView(debugger, p_embedded_process, window_wrapper));
|
||||
game_view->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
window_wrapper->set_wrapped_control(game_view, nullptr);
|
||||
|
||||
EditorNode::get_singleton()->get_editor_main_screen()->get_control()->add_child(window_wrapper);
|
||||
window_wrapper->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
window_wrapper->hide();
|
||||
window_wrapper->connect("window_visibility_changed", callable_mp(this, &GameViewPlugin::_focus_another_editor).unbind(1));
|
||||
}
|
||||
|
||||
#endif // ANDROID_ENABLED
|
||||
|
||||
void GameViewPlugin::_notification(int p_what) {
|
||||
void GameViewPluginBase::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
add_debugger_plugin(debugger);
|
||||
connect("main_screen_changed", callable_mp(this, &GameViewPlugin::_save_last_editor));
|
||||
connect("main_screen_changed", callable_mp(this, &GameViewPluginBase::_save_last_editor));
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
remove_debugger_plugin(debugger);
|
||||
disconnect("main_screen_changed", callable_mp(this, &GameViewPlugin::_save_last_editor));
|
||||
disconnect("main_screen_changed", callable_mp(this, &GameViewPluginBase::_save_last_editor));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void GameViewPlugin::_save_last_editor(const String &p_editor) {
|
||||
void GameViewPluginBase::_save_last_editor(const String &p_editor) {
|
||||
if (p_editor != get_plugin_name()) {
|
||||
last_editor = p_editor;
|
||||
}
|
||||
}
|
||||
|
||||
void GameViewPlugin::_focus_another_editor() {
|
||||
void GameViewPluginBase::_focus_another_editor() {
|
||||
if (_is_window_wrapper_enabled()) {
|
||||
if (last_editor.is_empty()) {
|
||||
EditorNode::get_singleton()->get_editor_main_screen()->select(EditorMainScreen::EDITOR_2D);
|
||||
@@ -1214,7 +1257,7 @@ void GameViewPlugin::_focus_another_editor() {
|
||||
}
|
||||
}
|
||||
|
||||
bool GameViewPlugin::_is_window_wrapper_enabled() const {
|
||||
bool GameViewPluginBase::_is_window_wrapper_enabled() const {
|
||||
#ifdef ANDROID_ENABLED
|
||||
return true;
|
||||
#else
|
||||
@@ -1222,22 +1265,15 @@ bool GameViewPlugin::_is_window_wrapper_enabled() const {
|
||||
#endif // ANDROID_ENABLED
|
||||
}
|
||||
|
||||
GameViewPlugin::GameViewPlugin() {
|
||||
debugger.instantiate();
|
||||
|
||||
#ifndef ANDROID_ENABLED
|
||||
window_wrapper = memnew(WindowWrapper);
|
||||
window_wrapper->set_window_title(vformat(TTR("%s - Godot Engine"), TTR("Game Workspace")));
|
||||
window_wrapper->set_margins_enabled(true);
|
||||
|
||||
game_view = memnew(GameView(debugger, window_wrapper));
|
||||
game_view->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
window_wrapper->set_wrapped_control(game_view, nullptr);
|
||||
|
||||
EditorNode::get_singleton()->get_editor_main_screen()->get_control()->add_child(window_wrapper);
|
||||
window_wrapper->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
window_wrapper->hide();
|
||||
window_wrapper->connect("window_visibility_changed", callable_mp(this, &GameViewPlugin::_focus_another_editor).unbind(1));
|
||||
#endif // ANDROID_ENABLED
|
||||
GameViewPluginBase::GameViewPluginBase() {
|
||||
}
|
||||
|
||||
GameViewPlugin::GameViewPlugin() :
|
||||
GameViewPluginBase() {
|
||||
#ifndef ANDROID_ENABLED
|
||||
Ref<GameViewDebugger> game_view_debugger;
|
||||
game_view_debugger.instantiate();
|
||||
EmbeddedProcess *embedded_process = memnew(EmbeddedProcess);
|
||||
setup(game_view_debugger, embedded_process);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
|
||||
class EmbeddedProcess;
|
||||
class EmbeddedProcessBase;
|
||||
class VSeparator;
|
||||
class WindowWrapper;
|
||||
class ScriptEditorDebugger;
|
||||
@@ -154,7 +154,7 @@ class GameView : public VBoxContainer {
|
||||
MenuButton *embed_options_menu = nullptr;
|
||||
Label *game_size_label = nullptr;
|
||||
Panel *panel = nullptr;
|
||||
EmbeddedProcess *embedded_process = nullptr;
|
||||
EmbeddedProcessBase *embedded_process = nullptr;
|
||||
Label *state_label = nullptr;
|
||||
|
||||
void _sessions_changed();
|
||||
@@ -214,11 +214,11 @@ public:
|
||||
void set_window_layout(Ref<ConfigFile> p_layout);
|
||||
void get_window_layout(Ref<ConfigFile> p_layout);
|
||||
|
||||
GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper);
|
||||
GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embedded_process, WindowWrapper *p_wrapper);
|
||||
};
|
||||
|
||||
class GameViewPlugin : public EditorPlugin {
|
||||
GDCLASS(GameViewPlugin, EditorPlugin);
|
||||
class GameViewPluginBase : public EditorPlugin {
|
||||
GDCLASS(GameViewPluginBase, EditorPlugin);
|
||||
|
||||
#ifndef ANDROID_ENABLED
|
||||
GameView *game_view = nullptr;
|
||||
@@ -238,6 +238,9 @@ class GameViewPlugin : public EditorPlugin {
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
#ifndef ANDROID_ENABLED
|
||||
void setup(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embedded_process);
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual String get_plugin_name() const override { return TTRC("Game"); }
|
||||
@@ -254,6 +257,12 @@ public:
|
||||
virtual void set_window_layout(Ref<ConfigFile> p_layout) override;
|
||||
virtual void get_window_layout(Ref<ConfigFile> p_layout) override;
|
||||
#endif // ANDROID_ENABLED
|
||||
GameViewPluginBase();
|
||||
};
|
||||
|
||||
class GameViewPlugin : public GameViewPluginBase {
|
||||
GDCLASS(GameViewPlugin, GameViewPluginBase);
|
||||
|
||||
public:
|
||||
GameViewPlugin();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user