feat: godot-engine-source-4.3-stable
This commit is contained in:
parent
c59a7dcade
commit
7125d019b5
11149 changed files with 5070401 additions and 0 deletions
5
engine/modules/openxr/editor/SCsub
Normal file
5
engine/modules/openxr/editor/SCsub
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
|
||||
env.add_source_files(env.modules_sources, "*.cpp")
|
||||
165
engine/modules/openxr/editor/openxr_action_editor.cpp
Normal file
165
engine/modules/openxr/editor/openxr_action_editor.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_action_editor.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_action_editor.h"
|
||||
|
||||
#include "editor/editor_string_names.h"
|
||||
|
||||
void OpenXRActionEditor::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_do_set_name", "name"), &OpenXRActionEditor::_do_set_name);
|
||||
ClassDB::bind_method(D_METHOD("_do_set_localized_name", "name"), &OpenXRActionEditor::_do_set_localized_name);
|
||||
ClassDB::bind_method(D_METHOD("_do_set_action_type", "type"), &OpenXRActionEditor::_do_set_action_type);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("remove", PropertyInfo(Variant::OBJECT, "action_editor")));
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_theme_changed() {
|
||||
rem_action->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
_theme_changed();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_on_action_name_changed(const String p_new_text) {
|
||||
if (action->get_name() != p_new_text) {
|
||||
undo_redo->create_action(TTR("Rename Action"));
|
||||
undo_redo->add_do_method(this, "_do_set_name", p_new_text);
|
||||
undo_redo->add_undo_method(this, "_do_set_name", action->get_name());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
// If our localized name matches our action name, set this too
|
||||
if (action->get_name() == action->get_localized_name()) {
|
||||
undo_redo->create_action(TTR("Rename Actions Localized name"));
|
||||
undo_redo->add_do_method(this, "_do_set_localized_name", p_new_text);
|
||||
undo_redo->add_undo_method(this, "_do_set_localized_name", action->get_localized_name());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
action->set_localized_name(p_new_text);
|
||||
action_localized_name->set_text(p_new_text);
|
||||
}
|
||||
action->set_name(p_new_text);
|
||||
action->set_edited(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_do_set_name(const String p_new_text) {
|
||||
action->set_name(p_new_text);
|
||||
action->set_edited(true);
|
||||
action_name->set_text(p_new_text);
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_on_action_localized_name_changed(const String p_new_text) {
|
||||
if (action->get_localized_name() != p_new_text) {
|
||||
undo_redo->create_action(TTR("Rename Actions Localized name"));
|
||||
undo_redo->add_do_method(this, "_do_set_localized_name", p_new_text);
|
||||
undo_redo->add_undo_method(this, "_do_set_localized_name", action->get_localized_name());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
action->set_localized_name(p_new_text);
|
||||
action->set_edited(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_do_set_localized_name(const String p_new_text) {
|
||||
action->set_localized_name(p_new_text);
|
||||
action->set_edited(true);
|
||||
action_localized_name->set_text(p_new_text);
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_on_item_selected(int p_idx) {
|
||||
ERR_FAIL_INDEX(p_idx, OpenXRAction::OPENXR_ACTION_MAX);
|
||||
|
||||
OpenXRAction::ActionType action_type = OpenXRAction::ActionType(p_idx);
|
||||
|
||||
if (action->get_action_type() != action_type) {
|
||||
undo_redo->create_action(TTR("Change Action Type"));
|
||||
undo_redo->add_do_method(this, "_do_set_action_type", action_type);
|
||||
undo_redo->add_undo_method(this, "_do_set_action_type", action->get_action_type());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
action->set_action_type(action_type);
|
||||
action->set_edited(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_do_set_action_type(OpenXRAction::ActionType p_action_type) {
|
||||
action->set_action_type(p_action_type);
|
||||
action->set_edited(true);
|
||||
action_type_button->select(int(action->get_action_type()));
|
||||
}
|
||||
|
||||
void OpenXRActionEditor::_on_remove_action() {
|
||||
emit_signal("remove", this);
|
||||
}
|
||||
|
||||
OpenXRActionEditor::OpenXRActionEditor(Ref<OpenXRAction> p_action) {
|
||||
undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
action = p_action;
|
||||
|
||||
set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
action_name = memnew(LineEdit);
|
||||
action_name->set_text(action->get_name());
|
||||
action_name->set_custom_minimum_size(Size2(150.0, 0.0));
|
||||
action_name->connect(SceneStringName(text_changed), callable_mp(this, &OpenXRActionEditor::_on_action_name_changed));
|
||||
add_child(action_name);
|
||||
|
||||
action_localized_name = memnew(LineEdit);
|
||||
action_localized_name->set_text(action->get_localized_name());
|
||||
action_localized_name->set_custom_minimum_size(Size2(150.0, 0.0));
|
||||
action_localized_name->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
action_localized_name->connect(SceneStringName(text_changed), callable_mp(this, &OpenXRActionEditor::_on_action_localized_name_changed));
|
||||
add_child(action_localized_name);
|
||||
|
||||
action_type_button = memnew(OptionButton);
|
||||
action_type_button->add_item("Bool", OpenXRAction::OPENXR_ACTION_BOOL);
|
||||
action_type_button->add_item("Float", OpenXRAction::OPENXR_ACTION_FLOAT);
|
||||
action_type_button->add_item("Vector2", OpenXRAction::OPENXR_ACTION_VECTOR2);
|
||||
action_type_button->add_item("Pose", OpenXRAction::OPENXR_ACTION_POSE);
|
||||
action_type_button->add_item("Haptic", OpenXRAction::OPENXR_ACTION_HAPTIC);
|
||||
action_type_button->select(int(action->get_action_type()));
|
||||
action_type_button->set_custom_minimum_size(Size2(100.0, 0.0));
|
||||
action_type_button->connect(SceneStringName(item_selected), callable_mp(this, &OpenXRActionEditor::_on_item_selected));
|
||||
add_child(action_type_button);
|
||||
|
||||
// maybe add dropdown to edit our toplevel paths, or do we deduce them from our suggested bindings?
|
||||
|
||||
rem_action = memnew(Button);
|
||||
rem_action->set_tooltip_text(TTR("Remove action"));
|
||||
rem_action->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionEditor::_on_remove_action));
|
||||
rem_action->set_flat(true);
|
||||
add_child(rem_action);
|
||||
}
|
||||
75
engine/modules/openxr/editor/openxr_action_editor.h
Normal file
75
engine/modules/openxr/editor/openxr_action_editor.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_action_editor.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_ACTION_EDITOR_H
|
||||
#define OPENXR_ACTION_EDITOR_H
|
||||
|
||||
#include "../action_map/openxr_action.h"
|
||||
|
||||
#include "editor/editor_undo_redo_manager.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/option_button.h"
|
||||
#include "scene/gui/text_edit.h"
|
||||
|
||||
class OpenXRActionEditor : public HBoxContainer {
|
||||
GDCLASS(OpenXRActionEditor, HBoxContainer);
|
||||
|
||||
private:
|
||||
EditorUndoRedoManager *undo_redo;
|
||||
Ref<OpenXRAction> action;
|
||||
|
||||
LineEdit *action_name = nullptr;
|
||||
LineEdit *action_localized_name = nullptr;
|
||||
OptionButton *action_type_button = nullptr;
|
||||
Button *rem_action = nullptr;
|
||||
|
||||
void _theme_changed();
|
||||
void _on_action_name_changed(const String p_new_text);
|
||||
void _on_action_localized_name_changed(const String p_new_text);
|
||||
void _on_item_selected(int p_idx);
|
||||
void _on_remove_action();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
// used for undo/redo
|
||||
void _do_set_name(const String p_new_text);
|
||||
void _do_set_localized_name(const String p_new_text);
|
||||
void _do_set_action_type(OpenXRAction::ActionType p_action_type);
|
||||
|
||||
public:
|
||||
Ref<OpenXRAction> get_action() { return action; };
|
||||
OpenXRActionEditor(Ref<OpenXRAction> p_action);
|
||||
};
|
||||
|
||||
#endif // OPENXR_ACTION_EDITOR_H
|
||||
459
engine/modules/openxr/editor/openxr_action_map_editor.cpp
Normal file
459
engine/modules/openxr/editor/openxr_action_map_editor.cpp
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_action_map_editor.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_action_map_editor.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/gui/editor_bottom_panel.h"
|
||||
#include "editor/gui/editor_file_dialog.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
|
||||
// TODO implement redo/undo system
|
||||
|
||||
void OpenXRActionMapEditor::_bind_methods() {
|
||||
ClassDB::bind_method("_add_action_set_editor", &OpenXRActionMapEditor::_add_action_set_editor);
|
||||
ClassDB::bind_method("_add_interaction_profile_editor", &OpenXRActionMapEditor::_add_interaction_profile_editor);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_add_action_set", "name"), &OpenXRActionMapEditor::_add_action_set);
|
||||
ClassDB::bind_method(D_METHOD("_remove_action_set", "name"), &OpenXRActionMapEditor::_remove_action_set);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_do_add_action_set_editor", "action_set_editor"), &OpenXRActionMapEditor::_do_add_action_set_editor);
|
||||
ClassDB::bind_method(D_METHOD("_do_remove_action_set_editor", "action_set_editor"), &OpenXRActionMapEditor::_do_remove_action_set_editor);
|
||||
ClassDB::bind_method(D_METHOD("_do_add_interaction_profile_editor", "interaction_profile_editor"), &OpenXRActionMapEditor::_do_add_interaction_profile_editor);
|
||||
ClassDB::bind_method(D_METHOD("_do_remove_interaction_profile_editor", "interaction_profile_editor"), &OpenXRActionMapEditor::_do_remove_interaction_profile_editor);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
for (int i = 0; i < tabs->get_child_count(); i++) {
|
||||
Control *tab = Object::cast_to<Control>(tabs->get_child(i));
|
||||
if (tab) {
|
||||
tab->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
_create_action_sets();
|
||||
_create_interaction_profiles();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRActionSetEditor *OpenXRActionMapEditor::_add_action_set_editor(Ref<OpenXRActionSet> p_action_set) {
|
||||
ERR_FAIL_COND_V(p_action_set.is_null(), nullptr);
|
||||
|
||||
OpenXRActionSetEditor *action_set_editor = memnew(OpenXRActionSetEditor(action_map, p_action_set));
|
||||
action_set_editor->connect("remove", callable_mp(this, &OpenXRActionMapEditor::_on_remove_action_set));
|
||||
action_set_editor->connect("action_removed", callable_mp(this, &OpenXRActionMapEditor::_on_action_removed));
|
||||
|
||||
actionsets_vb->add_child(action_set_editor);
|
||||
|
||||
return action_set_editor;
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_create_action_sets() {
|
||||
if (action_map.is_valid()) {
|
||||
Array action_sets = action_map->get_action_sets();
|
||||
for (int i = 0; i < action_sets.size(); i++) {
|
||||
Ref<OpenXRActionSet> action_set = action_sets[i];
|
||||
_add_action_set_editor(action_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRInteractionProfileEditorBase *OpenXRActionMapEditor::_add_interaction_profile_editor(Ref<OpenXRInteractionProfile> p_interaction_profile) {
|
||||
ERR_FAIL_COND_V(p_interaction_profile.is_null(), nullptr);
|
||||
|
||||
String profile_path = p_interaction_profile->get_interaction_profile_path();
|
||||
|
||||
// need to instance the correct editor for our profile
|
||||
OpenXRInteractionProfileEditorBase *new_profile_editor = nullptr;
|
||||
if (profile_path == "placeholder_text") {
|
||||
// instance specific editor for this type
|
||||
} else {
|
||||
// instance generic editor
|
||||
new_profile_editor = memnew(OpenXRInteractionProfileEditor(action_map, p_interaction_profile));
|
||||
}
|
||||
|
||||
// now add it in..
|
||||
ERR_FAIL_NULL_V(new_profile_editor, nullptr);
|
||||
tabs->add_child(new_profile_editor);
|
||||
new_profile_editor->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
|
||||
tabs->set_tab_button_icon(tabs->get_tab_count() - 1, get_theme_icon(SNAME("close"), SNAME("TabBar")));
|
||||
|
||||
return new_profile_editor;
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_create_interaction_profiles() {
|
||||
if (action_map.is_valid()) {
|
||||
Array new_interaction_profiles = action_map->get_interaction_profiles();
|
||||
for (int i = 0; i < new_interaction_profiles.size(); i++) {
|
||||
Ref<OpenXRInteractionProfile> interaction_profile = new_interaction_profiles[i];
|
||||
_add_interaction_profile_editor(interaction_profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRActionSetEditor *OpenXRActionMapEditor::_add_action_set(String p_name) {
|
||||
ERR_FAIL_COND_V(action_map.is_null(), nullptr);
|
||||
Ref<OpenXRActionSet> new_action_set;
|
||||
|
||||
// add our new action set
|
||||
new_action_set.instantiate();
|
||||
new_action_set->set_name(p_name);
|
||||
new_action_set->set_localized_name(p_name);
|
||||
action_map->add_action_set(new_action_set);
|
||||
action_map->set_edited(true);
|
||||
|
||||
// update our editor right away
|
||||
OpenXRActionSetEditor *action_set_editor = _add_action_set_editor(new_action_set);
|
||||
|
||||
undo_redo->create_action(TTR("Add action set"));
|
||||
undo_redo->add_do_method(this, "_do_add_action_set_editor", action_set_editor);
|
||||
undo_redo->add_undo_method(this, "_do_remove_action_set_editor", action_set_editor);
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
return action_set_editor;
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_remove_action_set(String p_name) {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
Ref<OpenXRActionSet> action_set = action_map->find_action_set(p_name);
|
||||
ERR_FAIL_COND(action_set.is_null());
|
||||
|
||||
for (int i = 0; i < actionsets_vb->get_child_count(); i++) {
|
||||
OpenXRActionSetEditor *action_set_editor = Object::cast_to<OpenXRActionSetEditor>(actionsets_vb->get_child(i));
|
||||
if (action_set_editor && action_set_editor->get_action_set() == action_set) {
|
||||
_on_remove_action_set(action_set_editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_add_action_set() {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
String new_name = "New";
|
||||
int count = 0;
|
||||
|
||||
while (action_map->find_action_set(new_name).is_valid()) {
|
||||
new_name = "New_" + itos(count++);
|
||||
}
|
||||
|
||||
OpenXRActionSetEditor *new_action_set_editor = _add_action_set(new_name);
|
||||
|
||||
// Make sure our action set is the current tab
|
||||
tabs->set_current_tab(0);
|
||||
|
||||
callable_mp(this, &OpenXRActionMapEditor::_set_focus_on_action_set).call_deferred(new_action_set_editor);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_set_focus_on_action_set(OpenXRActionSetEditor *p_action_set_editor) {
|
||||
// Scroll down to our new entry
|
||||
actionsets_scroll->ensure_control_visible(p_action_set_editor);
|
||||
|
||||
// Set focus on this entry
|
||||
p_action_set_editor->set_focus_on_entry();
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_remove_action_set(Object *p_action_set_editor) {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
|
||||
OpenXRActionSetEditor *action_set_editor = Object::cast_to<OpenXRActionSetEditor>(p_action_set_editor);
|
||||
ERR_FAIL_NULL(action_set_editor);
|
||||
ERR_FAIL_COND(action_set_editor->get_parent() != actionsets_vb);
|
||||
Ref<OpenXRActionSet> action_set = action_set_editor->get_action_set();
|
||||
ERR_FAIL_COND(action_set.is_null());
|
||||
|
||||
action_set_editor->remove_all_actions();
|
||||
|
||||
undo_redo->create_action(TTR("Remove action set"));
|
||||
undo_redo->add_do_method(this, "_do_remove_action_set_editor", action_set_editor);
|
||||
undo_redo->add_undo_method(this, "_do_add_action_set_editor", action_set_editor);
|
||||
undo_redo->commit_action(true);
|
||||
|
||||
action_map->set_edited(true);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_action_removed(Ref<OpenXRAction> p_action) {
|
||||
for (int i = 0; i < tabs->get_tab_count(); i++) {
|
||||
// First tab won't be an interaction profile editor, but being thorough..
|
||||
OpenXRInteractionProfileEditorBase *interaction_profile_editor = Object::cast_to<OpenXRInteractionProfileEditorBase>(tabs->get_tab_control(i));
|
||||
if (interaction_profile_editor) {
|
||||
interaction_profile_editor->remove_all_bindings_for_action(p_action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_add_interaction_profile() {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
|
||||
PackedStringArray already_selected;
|
||||
|
||||
for (int i = 0; i < action_map->get_interaction_profile_count(); i++) {
|
||||
already_selected.push_back(action_map->get_interaction_profile(i)->get_interaction_profile_path());
|
||||
}
|
||||
|
||||
select_interaction_profile_dialog->open(already_selected);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_interaction_profile_selected(const String p_path) {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
|
||||
Ref<OpenXRInteractionProfile> new_profile;
|
||||
new_profile.instantiate();
|
||||
new_profile->set_interaction_profile_path(p_path);
|
||||
action_map->add_interaction_profile(new_profile);
|
||||
action_map->set_edited(true);
|
||||
|
||||
OpenXRInteractionProfileEditorBase *interaction_profile_editor = _add_interaction_profile_editor(new_profile);
|
||||
|
||||
undo_redo->create_action(TTR("Add interaction profile"));
|
||||
undo_redo->add_do_method(this, "_do_add_interaction_profile_editor", interaction_profile_editor);
|
||||
undo_redo->add_undo_method(this, "_do_remove_interaction_profile_editor", interaction_profile_editor);
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
tabs->set_current_tab(tabs->get_tab_count() - 1);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_load_action_map(const String p_path, bool p_create_new_if_missing) {
|
||||
Error err = OK;
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
if (da->file_exists(p_path)) {
|
||||
action_map = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->show_warning(vformat(TTR("Error loading %s: %s."), edited_path, error_names[err]));
|
||||
|
||||
edited_path = "";
|
||||
header_label->set_text("");
|
||||
return;
|
||||
}
|
||||
} else if (p_create_new_if_missing) {
|
||||
action_map.instantiate();
|
||||
action_map->create_default_action_sets();
|
||||
action_map->set_path(p_path);
|
||||
|
||||
// Save it immediately
|
||||
err = ResourceSaver::save(action_map, p_path);
|
||||
if (err != OK) {
|
||||
// Show warning but continue.
|
||||
EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving file %s: %s"), edited_path, error_names[err]));
|
||||
}
|
||||
}
|
||||
|
||||
edited_path = p_path;
|
||||
header_label->set_text(TTR("OpenXR Action map:") + " " + edited_path.get_file());
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_save_action_map() {
|
||||
Error err = ResourceSaver::save(action_map, edited_path);
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving file %s: %s"), edited_path, error_names[err]));
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO should clear undo/redo history
|
||||
|
||||
// out with the old
|
||||
_clear_action_map();
|
||||
|
||||
_create_action_sets();
|
||||
_create_interaction_profiles();
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_reset_to_default_layout() {
|
||||
// TODO should clear undo/redo history
|
||||
|
||||
// out with the old
|
||||
_clear_action_map();
|
||||
|
||||
// create a new one
|
||||
action_map.unref();
|
||||
action_map.instantiate();
|
||||
action_map->create_default_action_sets();
|
||||
action_map->set_edited(true);
|
||||
|
||||
_create_action_sets();
|
||||
_create_interaction_profiles();
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_tabs_tab_changed(int p_tab) {
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_on_tab_button_pressed(int p_tab) {
|
||||
OpenXRInteractionProfileEditorBase *interaction_profile_editor = Object::cast_to<OpenXRInteractionProfileEditorBase>(tabs->get_tab_control(p_tab));
|
||||
ERR_FAIL_NULL(interaction_profile_editor);
|
||||
|
||||
undo_redo->create_action(TTR("Remove interaction profile"));
|
||||
undo_redo->add_do_method(this, "_do_remove_interaction_profile_editor", interaction_profile_editor);
|
||||
undo_redo->add_undo_method(this, "_do_add_interaction_profile_editor", interaction_profile_editor);
|
||||
undo_redo->commit_action(true);
|
||||
|
||||
action_map->set_edited(true);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_do_add_action_set_editor(OpenXRActionSetEditor *p_action_set_editor) {
|
||||
Ref<OpenXRActionSet> action_set = p_action_set_editor->get_action_set();
|
||||
ERR_FAIL_COND(action_set.is_null());
|
||||
|
||||
action_map->add_action_set(action_set);
|
||||
actionsets_vb->add_child(p_action_set_editor);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_do_remove_action_set_editor(OpenXRActionSetEditor *p_action_set_editor) {
|
||||
Ref<OpenXRActionSet> action_set = p_action_set_editor->get_action_set();
|
||||
ERR_FAIL_COND(action_set.is_null());
|
||||
|
||||
actionsets_vb->remove_child(p_action_set_editor);
|
||||
action_map->remove_action_set(action_set);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_do_add_interaction_profile_editor(OpenXRInteractionProfileEditorBase *p_interaction_profile_editor) {
|
||||
Ref<OpenXRInteractionProfile> interaction_profile = p_interaction_profile_editor->get_interaction_profile();
|
||||
ERR_FAIL_COND(interaction_profile.is_null());
|
||||
|
||||
action_map->add_interaction_profile(interaction_profile);
|
||||
tabs->add_child(p_interaction_profile_editor);
|
||||
tabs->set_tab_button_icon(tabs->get_tab_count() - 1, get_theme_icon(SNAME("close"), SNAME("TabBar")));
|
||||
|
||||
tabs->set_current_tab(tabs->get_tab_count() - 1);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_do_remove_interaction_profile_editor(OpenXRInteractionProfileEditorBase *p_interaction_profile_editor) {
|
||||
Ref<OpenXRInteractionProfile> interaction_profile = p_interaction_profile_editor->get_interaction_profile();
|
||||
ERR_FAIL_COND(interaction_profile.is_null());
|
||||
|
||||
tabs->remove_child(p_interaction_profile_editor);
|
||||
action_map->remove_interaction_profile(interaction_profile);
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::open_action_map(String p_path) {
|
||||
EditorNode::get_bottom_panel()->make_item_visible(this);
|
||||
|
||||
// out with the old...
|
||||
_clear_action_map();
|
||||
|
||||
// now load in our new action map
|
||||
_load_action_map(p_path);
|
||||
|
||||
_create_action_sets();
|
||||
_create_interaction_profiles();
|
||||
}
|
||||
|
||||
void OpenXRActionMapEditor::_clear_action_map() {
|
||||
while (actionsets_vb->get_child_count() > 0) {
|
||||
Node *child = actionsets_vb->get_child(0);
|
||||
actionsets_vb->remove_child(child);
|
||||
child->queue_free();
|
||||
}
|
||||
|
||||
for (int i = tabs->get_tab_count() - 1; i >= 0; --i) {
|
||||
// First tab won't be an interaction profile editor, but being thorough..
|
||||
OpenXRInteractionProfileEditorBase *interaction_profile_editor = Object::cast_to<OpenXRInteractionProfileEditorBase>(tabs->get_tab_control(i));
|
||||
if (interaction_profile_editor) {
|
||||
tabs->remove_child(interaction_profile_editor);
|
||||
interaction_profile_editor->queue_free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRActionMapEditor::OpenXRActionMapEditor() {
|
||||
undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
set_custom_minimum_size(Size2(0.0, 300.0));
|
||||
|
||||
top_hb = memnew(HBoxContainer);
|
||||
add_child(top_hb);
|
||||
|
||||
header_label = memnew(Label);
|
||||
header_label->set_text(String(TTR("Action Map")));
|
||||
header_label->set_clip_text(true);
|
||||
header_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
top_hb->add_child(header_label);
|
||||
|
||||
add_action_set = memnew(Button);
|
||||
add_action_set->set_text(TTR("Add Action Set"));
|
||||
add_action_set->set_tooltip_text(TTR("Add an action set."));
|
||||
add_action_set->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionMapEditor::_on_add_action_set));
|
||||
top_hb->add_child(add_action_set);
|
||||
|
||||
add_interaction_profile = memnew(Button);
|
||||
add_interaction_profile->set_text(TTR("Add profile"));
|
||||
add_interaction_profile->set_tooltip_text(TTR("Add an interaction profile."));
|
||||
add_interaction_profile->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionMapEditor::_on_add_interaction_profile));
|
||||
top_hb->add_child(add_interaction_profile);
|
||||
|
||||
VSeparator *vseparator = memnew(VSeparator);
|
||||
top_hb->add_child(vseparator);
|
||||
|
||||
save_as = memnew(Button);
|
||||
save_as->set_text(TTR("Save"));
|
||||
save_as->set_tooltip_text(TTR("Save this OpenXR action map."));
|
||||
save_as->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionMapEditor::_on_save_action_map));
|
||||
top_hb->add_child(save_as);
|
||||
|
||||
_default = memnew(Button);
|
||||
_default->set_text(TTR("Reset to Default"));
|
||||
_default->set_tooltip_text(TTR("Reset to default OpenXR action map."));
|
||||
_default->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionMapEditor::_on_reset_to_default_layout));
|
||||
top_hb->add_child(_default);
|
||||
|
||||
tabs = memnew(TabContainer);
|
||||
tabs->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
tabs->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
tabs->set_theme_type_variation("TabContainerOdd");
|
||||
tabs->connect("tab_changed", callable_mp(this, &OpenXRActionMapEditor::_on_tabs_tab_changed));
|
||||
tabs->connect("tab_button_pressed", callable_mp(this, &OpenXRActionMapEditor::_on_tab_button_pressed));
|
||||
add_child(tabs);
|
||||
|
||||
actionsets_scroll = memnew(ScrollContainer);
|
||||
actionsets_scroll->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
actionsets_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
actionsets_scroll->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
|
||||
tabs->add_child(actionsets_scroll);
|
||||
actionsets_scroll->set_name(TTR("Action Sets"));
|
||||
|
||||
actionsets_vb = memnew(VBoxContainer);
|
||||
actionsets_vb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
actionsets_scroll->add_child(actionsets_vb);
|
||||
|
||||
select_interaction_profile_dialog = memnew(OpenXRSelectInteractionProfileDialog);
|
||||
select_interaction_profile_dialog->connect("interaction_profile_selected", callable_mp(this, &OpenXRActionMapEditor::_on_interaction_profile_selected));
|
||||
add_child(select_interaction_profile_dialog);
|
||||
|
||||
// Our Action map editor is only shown if openxr is enabled in project settings
|
||||
// So load our action map and if it doesn't exist, create it right away.
|
||||
_load_action_map(GLOBAL_GET("xr/openxr/default_action_map"), true);
|
||||
}
|
||||
|
||||
OpenXRActionMapEditor::~OpenXRActionMapEditor() {
|
||||
}
|
||||
109
engine/modules/openxr/editor/openxr_action_map_editor.h
Normal file
109
engine/modules/openxr/editor/openxr_action_map_editor.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_action_map_editor.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_ACTION_MAP_EDITOR_H
|
||||
#define OPENXR_ACTION_MAP_EDITOR_H
|
||||
|
||||
#include "../action_map/openxr_action_map.h"
|
||||
#include "openxr_action_set_editor.h"
|
||||
#include "openxr_interaction_profile_editor.h"
|
||||
#include "openxr_select_interaction_profile_dialog.h"
|
||||
|
||||
#include "editor/editor_undo_redo_manager.h"
|
||||
#include "editor/plugins/editor_plugin.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/scroll_container.h"
|
||||
#include "scene/gui/tab_container.h"
|
||||
|
||||
class OpenXRActionMapEditor : public VBoxContainer {
|
||||
GDCLASS(OpenXRActionMapEditor, VBoxContainer);
|
||||
|
||||
private:
|
||||
EditorUndoRedoManager *undo_redo;
|
||||
String edited_path;
|
||||
Ref<OpenXRActionMap> action_map;
|
||||
|
||||
HBoxContainer *top_hb = nullptr;
|
||||
Label *header_label = nullptr;
|
||||
Button *add_action_set = nullptr;
|
||||
Button *add_interaction_profile = nullptr;
|
||||
Button *load = nullptr;
|
||||
Button *save_as = nullptr;
|
||||
Button *_default = nullptr;
|
||||
TabContainer *tabs = nullptr;
|
||||
ScrollContainer *actionsets_scroll = nullptr;
|
||||
VBoxContainer *actionsets_vb = nullptr;
|
||||
OpenXRSelectInteractionProfileDialog *select_interaction_profile_dialog = nullptr;
|
||||
|
||||
OpenXRActionSetEditor *_add_action_set_editor(Ref<OpenXRActionSet> p_action_set);
|
||||
void _create_action_sets();
|
||||
OpenXRInteractionProfileEditorBase *_add_interaction_profile_editor(Ref<OpenXRInteractionProfile> p_interaction_profile);
|
||||
void _create_interaction_profiles();
|
||||
|
||||
OpenXRActionSetEditor *_add_action_set(String p_name);
|
||||
void _remove_action_set(String p_name);
|
||||
|
||||
void _on_add_action_set();
|
||||
void _set_focus_on_action_set(OpenXRActionSetEditor *p_action_set_editor);
|
||||
void _on_remove_action_set(Object *p_action_set_editor);
|
||||
void _on_action_removed(Ref<OpenXRAction> p_action);
|
||||
|
||||
void _on_add_interaction_profile();
|
||||
void _on_interaction_profile_selected(const String p_path);
|
||||
|
||||
void _load_action_map(const String p_path, bool p_create_new_if_missing = false);
|
||||
void _on_save_action_map();
|
||||
void _on_reset_to_default_layout();
|
||||
|
||||
void _on_tabs_tab_changed(int p_tab);
|
||||
void _on_tab_button_pressed(int p_tab);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
void _clear_action_map();
|
||||
|
||||
// used for undo/redo
|
||||
void _do_add_action_set_editor(OpenXRActionSetEditor *p_action_set_editor);
|
||||
void _do_remove_action_set_editor(OpenXRActionSetEditor *p_action_set_editor);
|
||||
void _do_add_interaction_profile_editor(OpenXRInteractionProfileEditorBase *p_interaction_profile_editor);
|
||||
void _do_remove_interaction_profile_editor(OpenXRInteractionProfileEditorBase *p_interaction_profile_editor);
|
||||
|
||||
public:
|
||||
void open_action_map(String p_path);
|
||||
|
||||
OpenXRActionMapEditor();
|
||||
~OpenXRActionMapEditor();
|
||||
};
|
||||
|
||||
#endif // OPENXR_ACTION_MAP_EDITOR_H
|
||||
285
engine/modules/openxr/editor/openxr_action_set_editor.cpp
Normal file
285
engine/modules/openxr/editor/openxr_action_set_editor.cpp
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_action_set_editor.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_action_set_editor.h"
|
||||
|
||||
#include "editor/editor_string_names.h"
|
||||
#include "openxr_action_editor.h"
|
||||
|
||||
void OpenXRActionSetEditor::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_do_set_name", "name"), &OpenXRActionSetEditor::_do_set_name);
|
||||
ClassDB::bind_method(D_METHOD("_do_set_localized_name", "name"), &OpenXRActionSetEditor::_do_set_localized_name);
|
||||
ClassDB::bind_method(D_METHOD("_do_set_priority", "value"), &OpenXRActionSetEditor::_do_set_priority);
|
||||
ClassDB::bind_method(D_METHOD("_do_add_action_editor", "action_editor"), &OpenXRActionSetEditor::_do_add_action_editor);
|
||||
ClassDB::bind_method(D_METHOD("_do_remove_action_editor", "action_editor"), &OpenXRActionSetEditor::_do_remove_action_editor);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("remove", PropertyInfo(Variant::OBJECT, "action_set_editor")));
|
||||
ADD_SIGNAL(MethodInfo("action_removed", PropertyInfo(Variant::OBJECT, "action")));
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_set_fold_icon() {
|
||||
if (is_expanded) {
|
||||
fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons)));
|
||||
} else {
|
||||
fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons)));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_theme_changed() {
|
||||
_set_fold_icon();
|
||||
add_action->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
|
||||
rem_action_set->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
_theme_changed();
|
||||
panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("TabContainer")));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRActionEditor *OpenXRActionSetEditor::_add_action_editor(Ref<OpenXRAction> p_action) {
|
||||
OpenXRActionEditor *action_editor = memnew(OpenXRActionEditor(p_action));
|
||||
action_editor->connect("remove", callable_mp(this, &OpenXRActionSetEditor::_on_remove_action));
|
||||
actions_vb->add_child(action_editor);
|
||||
|
||||
return action_editor;
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_on_toggle_expand() {
|
||||
is_expanded = !is_expanded;
|
||||
actions_vb->set_visible(is_expanded);
|
||||
_set_fold_icon();
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_on_action_set_name_changed(const String p_new_text) {
|
||||
if (action_set->get_name() != p_new_text) {
|
||||
undo_redo->create_action(TTR("Rename Action Set"));
|
||||
undo_redo->add_do_method(this, "_do_set_name", p_new_text);
|
||||
undo_redo->add_undo_method(this, "_do_set_name", action_set->get_name());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
// If our localized name matches our action set name, set this too
|
||||
if (action_set->get_name() == action_set->get_localized_name()) {
|
||||
undo_redo->create_action(TTR("Rename Action Sets Localized name"));
|
||||
undo_redo->add_do_method(this, "_do_set_localized_name", p_new_text);
|
||||
undo_redo->add_undo_method(this, "_do_set_localized_name", action_set->get_localized_name());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
action_set->set_localized_name(p_new_text);
|
||||
action_set_localized_name->set_text(p_new_text);
|
||||
}
|
||||
action_set->set_name(p_new_text);
|
||||
action_set->set_edited(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_do_set_name(const String p_new_text) {
|
||||
action_set->set_name(p_new_text);
|
||||
action_set_name->set_text(p_new_text);
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_on_action_set_localized_name_changed(const String p_new_text) {
|
||||
if (action_set->get_localized_name() != p_new_text) {
|
||||
undo_redo->create_action(TTR("Rename Action Sets Localized name"));
|
||||
undo_redo->add_do_method(this, "_do_set_localized_name", p_new_text);
|
||||
undo_redo->add_undo_method(this, "_do_set_localized_name", action_set->get_localized_name());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
action_set->set_localized_name(p_new_text);
|
||||
action_set->set_edited(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_do_set_localized_name(const String p_new_text) {
|
||||
action_set->set_localized_name(p_new_text);
|
||||
action_set_localized_name->set_text(p_new_text);
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_on_action_set_priority_changed(const String p_new_text) {
|
||||
int64_t value = p_new_text.to_int();
|
||||
|
||||
if (action_set->get_priority() != value) {
|
||||
undo_redo->create_action(TTR("Change Action Sets priority"));
|
||||
undo_redo->add_do_method(this, "_do_set_priority", value);
|
||||
undo_redo->add_undo_method(this, "_do_set_priority", action_set->get_priority());
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
action_set->set_priority(value);
|
||||
action_set->set_edited(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_do_set_priority(int64_t p_value) {
|
||||
action_set->set_priority(p_value);
|
||||
action_set_priority->set_text(itos(p_value));
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_on_add_action() {
|
||||
Ref<OpenXRAction> new_action;
|
||||
|
||||
new_action.instantiate();
|
||||
new_action->set_name("New");
|
||||
new_action->set_localized_name("New");
|
||||
action_set->add_action(new_action);
|
||||
action_set->set_edited(true);
|
||||
|
||||
OpenXRActionEditor *action_editor = _add_action_editor(new_action);
|
||||
|
||||
undo_redo->create_action(TTR("Add action"));
|
||||
undo_redo->add_do_method(this, "_do_add_action_editor", action_editor);
|
||||
undo_redo->add_undo_method(this, "_do_remove_action_editor", action_editor);
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
// TODO handle focus
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_on_remove_action_set() {
|
||||
emit_signal("remove", this);
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_on_remove_action(Object *p_action_editor) {
|
||||
OpenXRActionEditor *action_editor = Object::cast_to<OpenXRActionEditor>(p_action_editor);
|
||||
ERR_FAIL_NULL(action_editor);
|
||||
ERR_FAIL_COND(action_editor->get_parent() != actions_vb);
|
||||
Ref<OpenXRAction> action = action_editor->get_action();
|
||||
ERR_FAIL_COND(action.is_null());
|
||||
|
||||
emit_signal("action_removed", action);
|
||||
|
||||
undo_redo->create_action(TTR("Delete action"));
|
||||
undo_redo->add_do_method(this, "_do_remove_action_editor", action_editor);
|
||||
undo_redo->add_undo_method(this, "_do_add_action_editor", action_editor);
|
||||
undo_redo->commit_action(true);
|
||||
|
||||
action_set->set_edited(true);
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_do_add_action_editor(OpenXRActionEditor *p_action_editor) {
|
||||
Ref<OpenXRAction> action = p_action_editor->get_action();
|
||||
ERR_FAIL_COND(action.is_null());
|
||||
|
||||
action_set->add_action(action);
|
||||
actions_vb->add_child(p_action_editor);
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::_do_remove_action_editor(OpenXRActionEditor *p_action_editor) {
|
||||
Ref<OpenXRAction> action = p_action_editor->get_action();
|
||||
ERR_FAIL_COND(action.is_null());
|
||||
|
||||
actions_vb->remove_child(p_action_editor);
|
||||
action_set->remove_action(action);
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::remove_all_actions() {
|
||||
for (int i = actions_vb->get_child_count(); i > 0; --i) {
|
||||
_on_remove_action(actions_vb->get_child(i));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRActionSetEditor::set_focus_on_entry() {
|
||||
ERR_FAIL_NULL(action_set_name);
|
||||
action_set_name->grab_focus();
|
||||
}
|
||||
|
||||
OpenXRActionSetEditor::OpenXRActionSetEditor(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRActionSet> p_action_set) {
|
||||
undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
action_map = p_action_map;
|
||||
action_set = p_action_set;
|
||||
|
||||
set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
panel = memnew(PanelContainer);
|
||||
panel->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
add_child(panel);
|
||||
|
||||
HBoxContainer *panel_hb = memnew(HBoxContainer);
|
||||
panel_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
panel->add_child(panel_hb);
|
||||
|
||||
fold_btn = memnew(Button);
|
||||
fold_btn->set_v_size_flags(Control::SIZE_SHRINK_BEGIN);
|
||||
fold_btn->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionSetEditor::_on_toggle_expand));
|
||||
fold_btn->set_flat(true);
|
||||
panel_hb->add_child(fold_btn);
|
||||
|
||||
main_vb = memnew(VBoxContainer);
|
||||
main_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
panel_hb->add_child(main_vb);
|
||||
|
||||
action_set_hb = memnew(HBoxContainer);
|
||||
action_set_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
main_vb->add_child(action_set_hb);
|
||||
|
||||
action_set_name = memnew(LineEdit);
|
||||
action_set_name->set_text(action_set->get_name());
|
||||
action_set_name->set_custom_minimum_size(Size2(150.0, 0.0));
|
||||
action_set_name->connect(SceneStringName(text_changed), callable_mp(this, &OpenXRActionSetEditor::_on_action_set_name_changed));
|
||||
action_set_hb->add_child(action_set_name);
|
||||
|
||||
action_set_localized_name = memnew(LineEdit);
|
||||
action_set_localized_name->set_text(action_set->get_localized_name());
|
||||
action_set_localized_name->set_custom_minimum_size(Size2(150.0, 0.0));
|
||||
action_set_localized_name->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
action_set_localized_name->connect(SceneStringName(text_changed), callable_mp(this, &OpenXRActionSetEditor::_on_action_set_localized_name_changed));
|
||||
action_set_hb->add_child(action_set_localized_name);
|
||||
|
||||
action_set_priority = memnew(TextEdit);
|
||||
action_set_priority->set_text(itos(action_set->get_priority()));
|
||||
action_set_priority->set_custom_minimum_size(Size2(50.0, 0.0));
|
||||
action_set_priority->connect(SceneStringName(text_changed), callable_mp(this, &OpenXRActionSetEditor::_on_action_set_priority_changed));
|
||||
action_set_hb->add_child(action_set_priority);
|
||||
|
||||
add_action = memnew(Button);
|
||||
add_action->set_tooltip_text(TTR("Add action."));
|
||||
add_action->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionSetEditor::_on_add_action));
|
||||
add_action->set_flat(true);
|
||||
action_set_hb->add_child(add_action);
|
||||
|
||||
rem_action_set = memnew(Button);
|
||||
rem_action_set->set_tooltip_text(TTR("Remove action set."));
|
||||
rem_action_set->connect(SceneStringName(pressed), callable_mp(this, &OpenXRActionSetEditor::_on_remove_action_set));
|
||||
rem_action_set->set_flat(true);
|
||||
action_set_hb->add_child(rem_action_set);
|
||||
|
||||
actions_vb = memnew(VBoxContainer);
|
||||
actions_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
main_vb->add_child(actions_vb);
|
||||
|
||||
// Add our existing actions
|
||||
Array actions = action_set->get_actions();
|
||||
for (int i = 0; i < actions.size(); i++) {
|
||||
Ref<OpenXRAction> action = actions[i];
|
||||
_add_action_editor(action);
|
||||
}
|
||||
}
|
||||
98
engine/modules/openxr/editor/openxr_action_set_editor.h
Normal file
98
engine/modules/openxr/editor/openxr_action_set_editor.h
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_action_set_editor.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_ACTION_SET_EDITOR_H
|
||||
#define OPENXR_ACTION_SET_EDITOR_H
|
||||
|
||||
#include "../action_map/openxr_action_map.h"
|
||||
#include "../action_map/openxr_action_set.h"
|
||||
#include "openxr_action_editor.h"
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
#include "scene/gui/text_edit.h"
|
||||
|
||||
class OpenXRActionSetEditor : public HBoxContainer {
|
||||
GDCLASS(OpenXRActionSetEditor, HBoxContainer);
|
||||
|
||||
private:
|
||||
EditorUndoRedoManager *undo_redo;
|
||||
Ref<OpenXRActionMap> action_map;
|
||||
Ref<OpenXRActionSet> action_set;
|
||||
|
||||
bool is_expanded = true;
|
||||
|
||||
PanelContainer *panel = nullptr;
|
||||
Button *fold_btn = nullptr;
|
||||
VBoxContainer *main_vb = nullptr;
|
||||
HBoxContainer *action_set_hb = nullptr;
|
||||
LineEdit *action_set_name = nullptr;
|
||||
LineEdit *action_set_localized_name = nullptr;
|
||||
TextEdit *action_set_priority = nullptr;
|
||||
Button *add_action = nullptr;
|
||||
Button *rem_action_set = nullptr;
|
||||
VBoxContainer *actions_vb = nullptr;
|
||||
|
||||
void _set_fold_icon();
|
||||
void _theme_changed();
|
||||
OpenXRActionEditor *_add_action_editor(Ref<OpenXRAction> p_action);
|
||||
|
||||
void _on_toggle_expand();
|
||||
void _on_action_set_name_changed(const String p_new_text);
|
||||
void _on_action_set_localized_name_changed(const String p_new_text);
|
||||
void _on_action_set_priority_changed(const String p_new_text);
|
||||
void _on_add_action();
|
||||
void _on_remove_action_set();
|
||||
|
||||
void _on_remove_action(Object *p_action_editor);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
// used for undo/redo
|
||||
void _do_set_name(const String p_new_text);
|
||||
void _do_set_localized_name(const String p_new_text);
|
||||
void _do_set_priority(int64_t value);
|
||||
void _do_add_action_editor(OpenXRActionEditor *p_action_editor);
|
||||
void _do_remove_action_editor(OpenXRActionEditor *p_action_editor);
|
||||
|
||||
public:
|
||||
Ref<OpenXRActionSet> get_action_set() { return action_set; };
|
||||
void set_focus_on_entry();
|
||||
|
||||
void remove_all_actions();
|
||||
|
||||
OpenXRActionSetEditor(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRActionSet> p_action_set);
|
||||
};
|
||||
|
||||
#endif // OPENXR_ACTION_SET_EDITOR_H
|
||||
66
engine/modules/openxr/editor/openxr_editor_plugin.cpp
Normal file
66
engine/modules/openxr/editor/openxr_editor_plugin.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_editor_plugin.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_editor_plugin.h"
|
||||
|
||||
#include "../action_map/openxr_action_map.h"
|
||||
|
||||
#include "editor/editor_command_palette.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/gui/editor_bottom_panel.h"
|
||||
|
||||
void OpenXREditorPlugin::edit(Object *p_node) {
|
||||
if (Object::cast_to<OpenXRActionMap>(p_node)) {
|
||||
String path = Object::cast_to<OpenXRActionMap>(p_node)->get_path();
|
||||
if (path.is_resource_file()) {
|
||||
action_map_editor->open_action_map(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenXREditorPlugin::handles(Object *p_node) const {
|
||||
return (Object::cast_to<OpenXRActionMap>(p_node) != nullptr);
|
||||
}
|
||||
|
||||
void OpenXREditorPlugin::make_visible(bool p_visible) {
|
||||
}
|
||||
|
||||
OpenXREditorPlugin::OpenXREditorPlugin() {
|
||||
action_map_editor = memnew(OpenXRActionMapEditor);
|
||||
EditorNode::get_bottom_panel()->add_item(TTR("OpenXR Action Map"), action_map_editor, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_openxr_action_map_bottom_panel", TTR("Toggle OpenXR Action Map Bottom Panel")));
|
||||
|
||||
#ifndef ANDROID_ENABLED
|
||||
select_runtime = memnew(OpenXRSelectRuntime);
|
||||
add_control_to_container(CONTAINER_TOOLBAR, select_runtime);
|
||||
#endif
|
||||
}
|
||||
|
||||
OpenXREditorPlugin::~OpenXREditorPlugin() {
|
||||
}
|
||||
58
engine/modules/openxr/editor/openxr_editor_plugin.h
Normal file
58
engine/modules/openxr/editor/openxr_editor_plugin.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_editor_plugin.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_EDITOR_PLUGIN_H
|
||||
#define OPENXR_EDITOR_PLUGIN_H
|
||||
|
||||
#include "openxr_action_map_editor.h"
|
||||
#include "openxr_select_runtime.h"
|
||||
|
||||
#include "editor/plugins/editor_plugin.h"
|
||||
|
||||
class OpenXREditorPlugin : public EditorPlugin {
|
||||
GDCLASS(OpenXREditorPlugin, EditorPlugin);
|
||||
|
||||
OpenXRActionMapEditor *action_map_editor = nullptr;
|
||||
#ifndef ANDROID_ENABLED
|
||||
OpenXRSelectRuntime *select_runtime = nullptr;
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual String get_name() const override { return "OpenXRPlugin"; }
|
||||
bool has_main_screen() const override { return false; }
|
||||
virtual void edit(Object *p_node) override;
|
||||
virtual bool handles(Object *p_node) const override;
|
||||
virtual void make_visible(bool p_visible) override;
|
||||
|
||||
OpenXREditorPlugin();
|
||||
~OpenXREditorPlugin();
|
||||
};
|
||||
|
||||
#endif // OPENXR_EDITOR_PLUGIN_H
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_interaction_profile_editor.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_interaction_profile_editor.h"
|
||||
|
||||
#include "editor/editor_string_names.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
#include "scene/gui/separator.h"
|
||||
#include "scene/gui/text_edit.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Interaction profile editor base
|
||||
|
||||
void OpenXRInteractionProfileEditorBase::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_add_binding", "action", "path"), &OpenXRInteractionProfileEditorBase::_add_binding);
|
||||
ClassDB::bind_method(D_METHOD("_remove_binding", "action", "path"), &OpenXRInteractionProfileEditorBase::_remove_binding);
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditorBase::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
_update_interaction_profile();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
_theme_changed();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditorBase::_do_update_interaction_profile() {
|
||||
if (!is_dirty) {
|
||||
is_dirty = true;
|
||||
callable_mp(this, &OpenXRInteractionProfileEditorBase::_update_interaction_profile).call_deferred();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditorBase::_add_binding(const String p_action, const String p_path) {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
ERR_FAIL_COND(interaction_profile.is_null());
|
||||
|
||||
Ref<OpenXRAction> action = action_map->get_action(p_action);
|
||||
ERR_FAIL_COND(action.is_null());
|
||||
|
||||
Ref<OpenXRIPBinding> binding = interaction_profile->get_binding_for_action(action);
|
||||
if (binding.is_null()) {
|
||||
// create a new binding
|
||||
binding.instantiate();
|
||||
binding->set_action(action);
|
||||
interaction_profile->add_binding(binding);
|
||||
interaction_profile->set_edited(true);
|
||||
}
|
||||
|
||||
binding->add_path(p_path);
|
||||
binding->set_edited(true);
|
||||
|
||||
// Update our toplevel paths
|
||||
action->set_toplevel_paths(action_map->get_top_level_paths(action));
|
||||
|
||||
_do_update_interaction_profile();
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditorBase::_remove_binding(const String p_action, const String p_path) {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
ERR_FAIL_COND(interaction_profile.is_null());
|
||||
|
||||
Ref<OpenXRAction> action = action_map->get_action(p_action);
|
||||
ERR_FAIL_COND(action.is_null());
|
||||
|
||||
Ref<OpenXRIPBinding> binding = interaction_profile->get_binding_for_action(action);
|
||||
if (binding.is_valid()) {
|
||||
binding->remove_path(p_path);
|
||||
binding->set_edited(true);
|
||||
|
||||
if (binding->get_path_count() == 0) {
|
||||
interaction_profile->remove_binding(binding);
|
||||
interaction_profile->set_edited(true);
|
||||
}
|
||||
|
||||
// Update our toplevel paths
|
||||
action->set_toplevel_paths(action_map->get_top_level_paths(action));
|
||||
|
||||
_do_update_interaction_profile();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditorBase::remove_all_bindings_for_action(Ref<OpenXRAction> p_action) {
|
||||
Ref<OpenXRIPBinding> binding = interaction_profile->get_binding_for_action(p_action);
|
||||
if (binding.is_valid()) {
|
||||
String action_name = p_action->get_name_with_set();
|
||||
|
||||
// for our undo/redo we process all paths
|
||||
undo_redo->create_action(TTR("Remove action from interaction profile"));
|
||||
PackedStringArray paths = binding->get_paths();
|
||||
for (const String &path : paths) {
|
||||
undo_redo->add_do_method(this, "_remove_binding", action_name, path);
|
||||
undo_redo->add_undo_method(this, "_add_binding", action_name, path);
|
||||
}
|
||||
undo_redo->commit_action(false);
|
||||
|
||||
// but we take a shortcut here :)
|
||||
interaction_profile->remove_binding(binding);
|
||||
interaction_profile->set_edited(true);
|
||||
|
||||
// Update our toplevel paths
|
||||
p_action->set_toplevel_paths(action_map->get_top_level_paths(p_action));
|
||||
|
||||
_do_update_interaction_profile();
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRInteractionProfileEditorBase::OpenXRInteractionProfileEditorBase(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRInteractionProfile> p_interaction_profile) {
|
||||
undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
|
||||
action_map = p_action_map;
|
||||
interaction_profile = p_interaction_profile;
|
||||
String profile_path = interaction_profile->get_interaction_profile_path();
|
||||
String profile_name = profile_path;
|
||||
|
||||
profile_def = OpenXRInteractionProfileMetadata::get_singleton()->get_profile(profile_path);
|
||||
if (profile_def != nullptr) {
|
||||
profile_name = profile_def->display_name;
|
||||
}
|
||||
|
||||
set_name(profile_name);
|
||||
set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
// Make sure it is updated when it enters the tree...
|
||||
is_dirty = true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default interaction profile editor
|
||||
|
||||
void OpenXRInteractionProfileEditor::select_action_for(const String p_io_path) {
|
||||
selecting_for_io_path = p_io_path;
|
||||
select_action_dialog->open();
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditor::action_selected(const String p_action) {
|
||||
undo_redo->create_action(TTR("Add binding"));
|
||||
undo_redo->add_do_method(this, "_add_binding", p_action, selecting_for_io_path);
|
||||
undo_redo->add_undo_method(this, "_remove_binding", p_action, selecting_for_io_path);
|
||||
undo_redo->commit_action(true);
|
||||
|
||||
selecting_for_io_path = "";
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditor::_on_remove_pressed(const String p_action, const String p_for_io_path) {
|
||||
undo_redo->create_action(TTR("Remove binding"));
|
||||
undo_redo->add_do_method(this, "_remove_binding", p_action, p_for_io_path);
|
||||
undo_redo->add_undo_method(this, "_add_binding", p_action, p_for_io_path);
|
||||
undo_redo->commit_action(true);
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, const OpenXRInteractionProfileMetadata::IOPath *p_io_path) {
|
||||
HBoxContainer *path_hb = memnew(HBoxContainer);
|
||||
path_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
p_container->add_child(path_hb);
|
||||
|
||||
Label *path_label = memnew(Label);
|
||||
path_label->set_text(p_io_path->display_name);
|
||||
path_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
path_hb->add_child(path_label);
|
||||
|
||||
Label *type_label = memnew(Label);
|
||||
switch (p_io_path->action_type) {
|
||||
case OpenXRAction::OPENXR_ACTION_BOOL: {
|
||||
type_label->set_text(TTR("Boolean"));
|
||||
} break;
|
||||
case OpenXRAction::OPENXR_ACTION_FLOAT: {
|
||||
type_label->set_text(TTR("Float"));
|
||||
} break;
|
||||
case OpenXRAction::OPENXR_ACTION_VECTOR2: {
|
||||
type_label->set_text(TTR("Vector2"));
|
||||
} break;
|
||||
case OpenXRAction::OPENXR_ACTION_POSE: {
|
||||
type_label->set_text(TTR("Pose"));
|
||||
} break;
|
||||
case OpenXRAction::OPENXR_ACTION_HAPTIC: {
|
||||
type_label->set_text(TTR("Haptic"));
|
||||
} break;
|
||||
default: {
|
||||
type_label->set_text(TTR("Unknown"));
|
||||
} break;
|
||||
}
|
||||
type_label->set_custom_minimum_size(Size2(50.0, 0.0));
|
||||
path_hb->add_child(type_label);
|
||||
|
||||
Button *path_add = memnew(Button);
|
||||
path_add->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
|
||||
path_add->set_flat(true);
|
||||
path_add->connect(SceneStringName(pressed), callable_mp(this, &OpenXRInteractionProfileEditor::select_action_for).bind(String(p_io_path->openxr_path)));
|
||||
path_hb->add_child(path_add);
|
||||
|
||||
if (interaction_profile.is_valid()) {
|
||||
String io_path = String(p_io_path->openxr_path);
|
||||
Array bindings = interaction_profile->get_bindings();
|
||||
for (int i = 0; i < bindings.size(); i++) {
|
||||
Ref<OpenXRIPBinding> binding = bindings[i];
|
||||
if (binding->has_path(io_path)) {
|
||||
Ref<OpenXRAction> action = binding->get_action();
|
||||
|
||||
HBoxContainer *action_hb = memnew(HBoxContainer);
|
||||
action_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
p_container->add_child(action_hb);
|
||||
|
||||
Control *indent_node = memnew(Control);
|
||||
indent_node->set_custom_minimum_size(Size2(10.0, 0.0));
|
||||
action_hb->add_child(indent_node);
|
||||
|
||||
Label *action_label = memnew(Label);
|
||||
action_label->set_text(action->get_name_with_set() + ": " + action->get_localized_name());
|
||||
action_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
action_hb->add_child(action_label);
|
||||
|
||||
Button *action_rem = memnew(Button);
|
||||
action_rem->set_flat(true);
|
||||
action_rem->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
|
||||
action_rem->connect(SceneStringName(pressed), callable_mp((OpenXRInteractionProfileEditor *)this, &OpenXRInteractionProfileEditor::_on_remove_pressed).bind(action->get_name_with_set(), String(p_io_path->openxr_path)));
|
||||
action_hb->add_child(action_rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditor::_update_interaction_profile() {
|
||||
ERR_FAIL_NULL(profile_def);
|
||||
|
||||
if (!is_dirty) {
|
||||
// no need to update
|
||||
return;
|
||||
}
|
||||
|
||||
// out with the old...
|
||||
while (main_hb->get_child_count() > 0) {
|
||||
memdelete(main_hb->get_child(0));
|
||||
}
|
||||
|
||||
// in with the new...
|
||||
|
||||
// Determine toplevel paths
|
||||
Vector<String> top_level_paths;
|
||||
for (int i = 0; i < profile_def->io_paths.size(); i++) {
|
||||
const OpenXRInteractionProfileMetadata::IOPath *io_path = &profile_def->io_paths[i];
|
||||
|
||||
if (!top_level_paths.has(io_path->top_level_path)) {
|
||||
top_level_paths.push_back(io_path->top_level_path);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < top_level_paths.size(); i++) {
|
||||
PanelContainer *panel = memnew(PanelContainer);
|
||||
panel->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
main_hb->add_child(panel);
|
||||
panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("TabContainer")));
|
||||
|
||||
VBoxContainer *container = memnew(VBoxContainer);
|
||||
panel->add_child(container);
|
||||
|
||||
Label *label = memnew(Label);
|
||||
label->set_text(OpenXRInteractionProfileMetadata::get_singleton()->get_top_level_name(top_level_paths[i]));
|
||||
container->add_child(label);
|
||||
|
||||
for (int j = 0; j < profile_def->io_paths.size(); j++) {
|
||||
const OpenXRInteractionProfileMetadata::IOPath *io_path = &profile_def->io_paths[j];
|
||||
if (io_path->top_level_path == top_level_paths[i]) {
|
||||
_add_io_path(container, io_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and we've updated it...
|
||||
is_dirty = false;
|
||||
}
|
||||
|
||||
void OpenXRInteractionProfileEditor::_theme_changed() {
|
||||
for (int i = 0; i < main_hb->get_child_count(); i++) {
|
||||
Control *panel = Object::cast_to<Control>(main_hb->get_child(i));
|
||||
if (panel) {
|
||||
panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("TabContainer")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRInteractionProfileEditor::OpenXRInteractionProfileEditor(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRInteractionProfile> p_interaction_profile) :
|
||||
OpenXRInteractionProfileEditorBase(p_action_map, p_interaction_profile) {
|
||||
main_hb = memnew(HBoxContainer);
|
||||
add_child(main_hb);
|
||||
|
||||
select_action_dialog = memnew(OpenXRSelectActionDialog(p_action_map));
|
||||
select_action_dialog->connect("action_selected", callable_mp(this, &OpenXRInteractionProfileEditor::action_selected));
|
||||
add_child(select_action_dialog);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_interaction_profile_editor.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_INTERACTION_PROFILE_EDITOR_H
|
||||
#define OPENXR_INTERACTION_PROFILE_EDITOR_H
|
||||
|
||||
#include "../action_map/openxr_action_map.h"
|
||||
#include "../action_map/openxr_interaction_profile.h"
|
||||
#include "../action_map/openxr_interaction_profile_metadata.h"
|
||||
#include "openxr_select_action_dialog.h"
|
||||
|
||||
#include "editor/editor_undo_redo_manager.h"
|
||||
#include "scene/gui/scroll_container.h"
|
||||
|
||||
class OpenXRInteractionProfileEditorBase : public ScrollContainer {
|
||||
GDCLASS(OpenXRInteractionProfileEditorBase, ScrollContainer);
|
||||
|
||||
protected:
|
||||
EditorUndoRedoManager *undo_redo;
|
||||
Ref<OpenXRInteractionProfile> interaction_profile;
|
||||
Ref<OpenXRActionMap> action_map;
|
||||
|
||||
bool is_dirty = false;
|
||||
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
const OpenXRInteractionProfileMetadata::InteractionProfile *profile_def = nullptr;
|
||||
|
||||
public:
|
||||
Ref<OpenXRInteractionProfile> get_interaction_profile() { return interaction_profile; }
|
||||
|
||||
virtual void _update_interaction_profile() {}
|
||||
virtual void _theme_changed() {}
|
||||
|
||||
void _do_update_interaction_profile();
|
||||
void _add_binding(const String p_action, const String p_path);
|
||||
void _remove_binding(const String p_action, const String p_path);
|
||||
|
||||
void remove_all_bindings_for_action(Ref<OpenXRAction> p_action);
|
||||
|
||||
OpenXRInteractionProfileEditorBase(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRInteractionProfile> p_interaction_profile);
|
||||
};
|
||||
|
||||
class OpenXRInteractionProfileEditor : public OpenXRInteractionProfileEditorBase {
|
||||
GDCLASS(OpenXRInteractionProfileEditor, OpenXRInteractionProfileEditorBase);
|
||||
|
||||
private:
|
||||
String selecting_for_io_path;
|
||||
HBoxContainer *main_hb = nullptr;
|
||||
OpenXRSelectActionDialog *select_action_dialog = nullptr;
|
||||
|
||||
void _add_io_path(VBoxContainer *p_container, const OpenXRInteractionProfileMetadata::IOPath *p_io_path);
|
||||
|
||||
public:
|
||||
void select_action_for(const String p_io_path);
|
||||
void action_selected(const String p_action);
|
||||
void _on_remove_pressed(const String p_action, const String p_for_io_path);
|
||||
|
||||
virtual void _update_interaction_profile() override;
|
||||
virtual void _theme_changed() override;
|
||||
OpenXRInteractionProfileEditor(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRInteractionProfile> p_interaction_profile);
|
||||
};
|
||||
|
||||
#endif // OPENXR_INTERACTION_PROFILE_EDITOR_H
|
||||
132
engine/modules/openxr/editor/openxr_select_action_dialog.cpp
Normal file
132
engine/modules/openxr/editor/openxr_select_action_dialog.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_select_action_dialog.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_select_action_dialog.h"
|
||||
|
||||
void OpenXRSelectActionDialog::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("action_selected", PropertyInfo(Variant::STRING, "action")));
|
||||
}
|
||||
|
||||
void OpenXRSelectActionDialog::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
scroll->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRSelectActionDialog::_on_select_action(const String p_action) {
|
||||
if (selected_action != "") {
|
||||
NodePath button_path = action_buttons[selected_action];
|
||||
Button *button = Object::cast_to<Button>(get_node(button_path));
|
||||
if (button != nullptr) {
|
||||
button->set_flat(true);
|
||||
}
|
||||
}
|
||||
|
||||
selected_action = p_action;
|
||||
|
||||
if (selected_action != "") {
|
||||
NodePath button_path = action_buttons[selected_action];
|
||||
Button *button = Object::cast_to<Button>(get_node(button_path));
|
||||
if (button != nullptr) {
|
||||
button->set_flat(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRSelectActionDialog::open() {
|
||||
ERR_FAIL_COND(action_map.is_null());
|
||||
|
||||
// out with the old...
|
||||
while (main_vb->get_child_count() > 0) {
|
||||
memdelete(main_vb->get_child(0));
|
||||
}
|
||||
|
||||
selected_action = "";
|
||||
action_buttons.clear();
|
||||
|
||||
Array action_sets = action_map->get_action_sets();
|
||||
for (int i = 0; i < action_sets.size(); i++) {
|
||||
Ref<OpenXRActionSet> action_set = action_sets[i];
|
||||
|
||||
Label *action_set_label = memnew(Label);
|
||||
action_set_label->set_text(action_set->get_localized_name());
|
||||
main_vb->add_child(action_set_label);
|
||||
|
||||
Array actions = action_set->get_actions();
|
||||
for (int j = 0; j < actions.size(); j++) {
|
||||
Ref<OpenXRAction> action = actions[j];
|
||||
|
||||
HBoxContainer *action_hb = memnew(HBoxContainer);
|
||||
main_vb->add_child(action_hb);
|
||||
|
||||
Control *indent_node = memnew(Control);
|
||||
indent_node->set_custom_minimum_size(Size2(10.0, 0.0));
|
||||
action_hb->add_child(indent_node);
|
||||
|
||||
Button *action_button = memnew(Button);
|
||||
String action_name = action->get_name_with_set();
|
||||
action_button->set_flat(true);
|
||||
action_button->set_text(action->get_name() + ": " + action->get_localized_name());
|
||||
action_button->connect(SceneStringName(pressed), callable_mp(this, &OpenXRSelectActionDialog::_on_select_action).bind(action_name));
|
||||
action_hb->add_child(action_button);
|
||||
|
||||
action_buttons[action_name] = action_button->get_path();
|
||||
}
|
||||
}
|
||||
|
||||
popup_centered();
|
||||
}
|
||||
|
||||
void OpenXRSelectActionDialog::ok_pressed() {
|
||||
if (selected_action == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
emit_signal("action_selected", selected_action);
|
||||
|
||||
hide();
|
||||
}
|
||||
|
||||
OpenXRSelectActionDialog::OpenXRSelectActionDialog(Ref<OpenXRActionMap> p_action_map) {
|
||||
action_map = p_action_map;
|
||||
|
||||
set_title(TTR("Select an action"));
|
||||
|
||||
scroll = memnew(ScrollContainer);
|
||||
scroll->set_custom_minimum_size(Size2(600.0, 400.0));
|
||||
add_child(scroll);
|
||||
|
||||
main_vb = memnew(VBoxContainer);
|
||||
main_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
scroll->add_child(main_vb);
|
||||
}
|
||||
68
engine/modules/openxr/editor/openxr_select_action_dialog.h
Normal file
68
engine/modules/openxr/editor/openxr_select_action_dialog.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_select_action_dialog.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_SELECT_ACTION_DIALOG_H
|
||||
#define OPENXR_SELECT_ACTION_DIALOG_H
|
||||
|
||||
#include "../action_map/openxr_action_map.h"
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/dialogs.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/scroll_container.h"
|
||||
#include "scene/gui/separator.h"
|
||||
#include "scene/gui/text_edit.h"
|
||||
|
||||
class OpenXRSelectActionDialog : public ConfirmationDialog {
|
||||
GDCLASS(OpenXRSelectActionDialog, ConfirmationDialog);
|
||||
|
||||
private:
|
||||
Ref<OpenXRActionMap> action_map;
|
||||
String selected_action;
|
||||
Dictionary action_buttons;
|
||||
|
||||
VBoxContainer *main_vb = nullptr;
|
||||
ScrollContainer *scroll = nullptr;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
void _on_select_action(const String p_action);
|
||||
void open();
|
||||
virtual void ok_pressed() override;
|
||||
|
||||
OpenXRSelectActionDialog(Ref<OpenXRActionMap> p_action_map);
|
||||
};
|
||||
|
||||
#endif // OPENXR_SELECT_ACTION_DIALOG_H
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_select_interaction_profile_dialog.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_select_interaction_profile_dialog.h"
|
||||
|
||||
void OpenXRSelectInteractionProfileDialog::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("interaction_profile_selected", PropertyInfo(Variant::STRING, "interaction_profile")));
|
||||
}
|
||||
|
||||
void OpenXRSelectInteractionProfileDialog::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
scroll->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRSelectInteractionProfileDialog::_on_select_interaction_profile(const String p_interaction_profile) {
|
||||
if (selected_interaction_profile != "") {
|
||||
NodePath button_path = ip_buttons[selected_interaction_profile];
|
||||
Button *button = Object::cast_to<Button>(get_node(button_path));
|
||||
if (button != nullptr) {
|
||||
button->set_flat(true);
|
||||
}
|
||||
}
|
||||
|
||||
selected_interaction_profile = p_interaction_profile;
|
||||
|
||||
if (selected_interaction_profile != "") {
|
||||
NodePath button_path = ip_buttons[selected_interaction_profile];
|
||||
Button *button = Object::cast_to<Button>(get_node(button_path));
|
||||
if (button != nullptr) {
|
||||
button->set_flat(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRSelectInteractionProfileDialog::open(PackedStringArray p_do_not_include) {
|
||||
int available_count = 0;
|
||||
|
||||
// out with the old...
|
||||
while (main_vb->get_child_count() > 0) {
|
||||
memdelete(main_vb->get_child(0));
|
||||
}
|
||||
|
||||
selected_interaction_profile = "";
|
||||
ip_buttons.clear();
|
||||
|
||||
// in with the new
|
||||
PackedStringArray interaction_profiles = OpenXRInteractionProfileMetadata::get_singleton()->get_interaction_profile_paths();
|
||||
for (int i = 0; i < interaction_profiles.size(); i++) {
|
||||
const String &path = interaction_profiles[i];
|
||||
if (!p_do_not_include.has(path)) {
|
||||
Button *ip_button = memnew(Button);
|
||||
ip_button->set_flat(true);
|
||||
ip_button->set_text(OpenXRInteractionProfileMetadata::get_singleton()->get_profile(path)->display_name);
|
||||
ip_button->connect(SceneStringName(pressed), callable_mp(this, &OpenXRSelectInteractionProfileDialog::_on_select_interaction_profile).bind(path));
|
||||
main_vb->add_child(ip_button);
|
||||
|
||||
ip_buttons[path] = ip_button->get_path();
|
||||
available_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (available_count == 0) {
|
||||
// give warning that we have all profiles selected
|
||||
|
||||
} else {
|
||||
// TODO maybe if we only have one, auto select it?
|
||||
|
||||
popup_centered();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRSelectInteractionProfileDialog::ok_pressed() {
|
||||
if (selected_interaction_profile == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
emit_signal("interaction_profile_selected", selected_interaction_profile);
|
||||
|
||||
hide();
|
||||
}
|
||||
|
||||
OpenXRSelectInteractionProfileDialog::OpenXRSelectInteractionProfileDialog() {
|
||||
set_title(TTR("Select an interaction profile"));
|
||||
|
||||
scroll = memnew(ScrollContainer);
|
||||
scroll->set_custom_minimum_size(Size2(600.0, 400.0));
|
||||
add_child(scroll);
|
||||
|
||||
main_vb = memnew(VBoxContainer);
|
||||
// main_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
scroll->add_child(main_vb);
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_select_interaction_profile_dialog.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_SELECT_INTERACTION_PROFILE_DIALOG_H
|
||||
#define OPENXR_SELECT_INTERACTION_PROFILE_DIALOG_H
|
||||
|
||||
#include "../action_map/openxr_interaction_profile_metadata.h"
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/dialogs.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/scroll_container.h"
|
||||
#include "scene/gui/separator.h"
|
||||
#include "scene/gui/text_edit.h"
|
||||
|
||||
class OpenXRSelectInteractionProfileDialog : public ConfirmationDialog {
|
||||
GDCLASS(OpenXRSelectInteractionProfileDialog, ConfirmationDialog);
|
||||
|
||||
private:
|
||||
String selected_interaction_profile;
|
||||
Dictionary ip_buttons;
|
||||
|
||||
VBoxContainer *main_vb = nullptr;
|
||||
ScrollContainer *scroll = nullptr;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
void _on_select_interaction_profile(const String p_interaction_profile);
|
||||
void open(PackedStringArray p_do_not_include);
|
||||
virtual void ok_pressed() override;
|
||||
|
||||
OpenXRSelectInteractionProfileDialog();
|
||||
};
|
||||
|
||||
#endif // OPENXR_SELECT_INTERACTION_PROFILE_DIALOG_H
|
||||
132
engine/modules/openxr/editor/openxr_select_runtime.cpp
Normal file
132
engine/modules/openxr/editor/openxr_select_runtime.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_select_runtime.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_select_runtime.h"
|
||||
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/os/os.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
|
||||
void OpenXRSelectRuntime::_bind_methods() {
|
||||
}
|
||||
|
||||
void OpenXRSelectRuntime::_update_items() {
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
OS *os = OS::get_singleton();
|
||||
Dictionary runtimes = EDITOR_GET("xr/openxr/runtime_paths");
|
||||
|
||||
int current_runtime = 0;
|
||||
int index = 0;
|
||||
String current_path = os->get_environment("XR_RUNTIME_JSON");
|
||||
|
||||
// Parse the user's home folder.
|
||||
String home_folder = os->get_environment("HOME");
|
||||
if (home_folder.is_empty()) {
|
||||
home_folder = os->get_environment("HOMEDRIVE") + os->get_environment("HOMEPATH");
|
||||
}
|
||||
|
||||
clear();
|
||||
add_item("Default", -1);
|
||||
set_item_metadata(index, "");
|
||||
index++;
|
||||
|
||||
Array keys = runtimes.keys();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
String key = keys[i];
|
||||
String path = runtimes[key];
|
||||
String adj_path = path.replace("~", home_folder);
|
||||
|
||||
if (da->file_exists(adj_path)) {
|
||||
add_item(key, index);
|
||||
set_item_metadata(index, adj_path);
|
||||
|
||||
if (current_path == adj_path) {
|
||||
current_runtime = index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
select(current_runtime);
|
||||
}
|
||||
|
||||
void OpenXRSelectRuntime::_item_selected(int p_which) {
|
||||
OS *os = OS::get_singleton();
|
||||
|
||||
if (p_which == 0) {
|
||||
// Return to default runtime
|
||||
os->set_environment("XR_RUNTIME_JSON", "");
|
||||
} else {
|
||||
// Select the runtime we want
|
||||
String runtime_path = get_item_metadata(p_which);
|
||||
os->set_environment("XR_RUNTIME_JSON", runtime_path);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRSelectRuntime::_notification(int p_notification) {
|
||||
switch (p_notification) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
// Update dropdown
|
||||
_update_items();
|
||||
|
||||
// Connect signal
|
||||
connect(SceneStringName(item_selected), callable_mp(this, &OpenXRSelectRuntime::_item_selected));
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
// Disconnect signal
|
||||
disconnect(SceneStringName(item_selected), callable_mp(this, &OpenXRSelectRuntime::_item_selected));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRSelectRuntime::OpenXRSelectRuntime() {
|
||||
Dictionary default_runtimes;
|
||||
|
||||
// Add known common runtimes by default.
|
||||
#ifdef WINDOWS_ENABLED
|
||||
default_runtimes["Meta"] = "C:\\Program Files\\Oculus\\Support\\oculus-runtime\\oculus_openxr_64.json";
|
||||
default_runtimes["SteamVR"] = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\SteamVR\\steamxr_win64.json";
|
||||
default_runtimes["Varjo"] = "C:\\Program Files\\Varjo\\varjo-openxr\\VarjoOpenXR.json";
|
||||
default_runtimes["WMR"] = "C:\\WINDOWS\\system32\\MixedRealityRuntime.json";
|
||||
#endif
|
||||
#ifdef LINUXBSD_ENABLED
|
||||
default_runtimes["Monado"] = "/usr/share/openxr/1/openxr_monado.json";
|
||||
default_runtimes["SteamVR"] = "~/.steam/steam/steamapps/common/SteamVR/steamxr_linux64.json";
|
||||
#endif
|
||||
|
||||
EDITOR_DEF_RST("xr/openxr/runtime_paths", default_runtimes);
|
||||
|
||||
set_flat(true);
|
||||
set_theme_type_variation("TopBarOptionButton");
|
||||
set_fit_to_longest_item(false);
|
||||
set_focus_mode(Control::FOCUS_NONE);
|
||||
set_tooltip_text(TTR("Choose an XR runtime."));
|
||||
}
|
||||
51
engine/modules/openxr/editor/openxr_select_runtime.h
Normal file
51
engine/modules/openxr/editor/openxr_select_runtime.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_select_runtime.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_SELECT_RUNTIME_H
|
||||
#define OPENXR_SELECT_RUNTIME_H
|
||||
|
||||
#include "scene/gui/option_button.h"
|
||||
|
||||
class OpenXRSelectRuntime : public OptionButton {
|
||||
GDCLASS(OpenXRSelectRuntime, OptionButton);
|
||||
|
||||
public:
|
||||
OpenXRSelectRuntime();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_notification);
|
||||
|
||||
private:
|
||||
void _update_items();
|
||||
void _item_selected(int p_which);
|
||||
};
|
||||
|
||||
#endif // OPENXR_SELECT_RUNTIME_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue