mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 07:53:26 +00:00
Compare commits
16 commits
20430236e7
...
60710df3b6
Author | SHA1 | Date | |
---|---|---|---|
![]() |
60710df3b6 | ||
![]() |
769505fef3 | ||
![]() |
94818a5313 | ||
![]() |
026efbb0f5 | ||
![]() |
f3ebee1f79 | ||
![]() |
9e96c7d9b8 | ||
![]() |
2edad6860a | ||
![]() |
13404515fb | ||
![]() |
af584b1ba8 | ||
![]() |
d739700178 | ||
![]() |
73afe696d2 | ||
![]() |
1f7e7de82b | ||
![]() |
a5ce9c3706 | ||
![]() |
e6783dbdd1 | ||
![]() |
24f23c5cdb | ||
![]() |
172c80df67 |
48 changed files with 368 additions and 282 deletions
|
@ -277,7 +277,7 @@ String InputEventWithModifiers::as_text() const {
|
|||
}
|
||||
}
|
||||
|
||||
String InputEventWithModifiers::to_string() {
|
||||
String InputEventWithModifiers::_to_string() {
|
||||
return as_text();
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ String InputEventKey::as_text() const {
|
|||
return mods_text.is_empty() ? kc : mods_text + "+" + kc;
|
||||
}
|
||||
|
||||
String InputEventKey::to_string() {
|
||||
String InputEventKey::_to_string() {
|
||||
String p = is_pressed() ? "true" : "false";
|
||||
String e = is_echo() ? "true" : "false";
|
||||
|
||||
|
@ -848,7 +848,7 @@ String InputEventMouseButton::as_text() const {
|
|||
return full_string;
|
||||
}
|
||||
|
||||
String InputEventMouseButton::to_string() {
|
||||
String InputEventMouseButton::_to_string() {
|
||||
String p = is_pressed() ? "true" : "false";
|
||||
String canceled_state = is_canceled() ? "true" : "false";
|
||||
String d = double_click ? "true" : "false";
|
||||
|
@ -988,7 +988,7 @@ String InputEventMouseMotion::as_text() const {
|
|||
return vformat(RTR("Mouse motion at position (%s) with velocity (%s)"), String(get_position()), String(get_velocity()));
|
||||
}
|
||||
|
||||
String InputEventMouseMotion::to_string() {
|
||||
String InputEventMouseMotion::_to_string() {
|
||||
BitField<MouseButtonMask> mouse_button_mask = get_button_mask();
|
||||
String button_mask_string = itos((int64_t)mouse_button_mask);
|
||||
|
||||
|
@ -1184,7 +1184,7 @@ String InputEventJoypadMotion::as_text() const {
|
|||
return vformat(RTR("Joypad Motion on Axis %d (%s) with Value %.2f"), axis, desc, axis_value);
|
||||
}
|
||||
|
||||
String InputEventJoypadMotion::to_string() {
|
||||
String InputEventJoypadMotion::_to_string() {
|
||||
return vformat("InputEventJoypadMotion: axis=%d, axis_value=%.2f", axis, axis_value);
|
||||
}
|
||||
|
||||
|
@ -1303,7 +1303,7 @@ String InputEventJoypadButton::as_text() const {
|
|||
return text;
|
||||
}
|
||||
|
||||
String InputEventJoypadButton::to_string() {
|
||||
String InputEventJoypadButton::_to_string() {
|
||||
String p = is_pressed() ? "true" : "false";
|
||||
return vformat("InputEventJoypadButton: button_index=%d, pressed=%s, pressure=%.2f", button_index, p, pressure);
|
||||
}
|
||||
|
@ -1386,7 +1386,7 @@ String InputEventScreenTouch::as_text() const {
|
|||
return vformat(RTR("Screen %s at (%s) with %s touch points"), status, String(get_position()), itos(index));
|
||||
}
|
||||
|
||||
String InputEventScreenTouch::to_string() {
|
||||
String InputEventScreenTouch::_to_string() {
|
||||
String p = pressed ? "true" : "false";
|
||||
String canceled_state = canceled ? "true" : "false";
|
||||
String double_tap_string = double_tap ? "true" : "false";
|
||||
|
@ -1514,7 +1514,7 @@ String InputEventScreenDrag::as_text() const {
|
|||
return vformat(RTR("Screen dragged with %s touch points at position (%s) with velocity of (%s)"), itos(index), String(get_position()), String(get_velocity()));
|
||||
}
|
||||
|
||||
String InputEventScreenDrag::to_string() {
|
||||
String InputEventScreenDrag::_to_string() {
|
||||
return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), velocity=(%s), pressure=%.2f, tilt=(%s), pen_inverted=(%s)", index, String(get_position()), String(get_relative()), String(get_velocity()), get_pressure(), String(get_tilt()), get_pen_inverted());
|
||||
}
|
||||
|
||||
|
@ -1656,7 +1656,7 @@ String InputEventAction::as_text() const {
|
|||
return String();
|
||||
}
|
||||
|
||||
String InputEventAction::to_string() {
|
||||
String InputEventAction::_to_string() {
|
||||
String p = is_pressed() ? "true" : "false";
|
||||
return vformat("InputEventAction: action=\"%s\", pressed=%s", action, p);
|
||||
}
|
||||
|
@ -1727,7 +1727,7 @@ String InputEventMagnifyGesture::as_text() const {
|
|||
return vformat(RTR("Magnify Gesture at (%s) with factor %s"), String(get_position()), rtos(get_factor()));
|
||||
}
|
||||
|
||||
String InputEventMagnifyGesture::to_string() {
|
||||
String InputEventMagnifyGesture::_to_string() {
|
||||
return vformat("InputEventMagnifyGesture: factor=%.2f, position=(%s)", factor, String(get_position()));
|
||||
}
|
||||
|
||||
|
@ -1769,7 +1769,7 @@ String InputEventPanGesture::as_text() const {
|
|||
return vformat(RTR("Pan Gesture at (%s) with delta (%s)"), String(get_position()), String(get_delta()));
|
||||
}
|
||||
|
||||
String InputEventPanGesture::to_string() {
|
||||
String InputEventPanGesture::_to_string() {
|
||||
return vformat("InputEventPanGesture: delta=(%s), position=(%s)", String(get_delta()), String(get_position()));
|
||||
}
|
||||
|
||||
|
@ -1850,7 +1850,7 @@ String InputEventMIDI::as_text() const {
|
|||
return vformat(RTR("MIDI Input on Channel=%s Message=%s"), itos(channel), itos((int64_t)message));
|
||||
}
|
||||
|
||||
String InputEventMIDI::to_string() {
|
||||
String InputEventMIDI::_to_string() {
|
||||
String ret;
|
||||
switch (message) {
|
||||
case MIDIMessage::NOTE_ON:
|
||||
|
@ -1926,7 +1926,7 @@ String InputEventShortcut::as_text() const {
|
|||
return vformat(RTR("Input Event with Shortcut=%s"), shortcut->get_as_text());
|
||||
}
|
||||
|
||||
String InputEventShortcut::to_string() {
|
||||
String InputEventShortcut::_to_string() {
|
||||
ERR_FAIL_COND_V(shortcut.is_null(), "None");
|
||||
|
||||
return vformat("InputEventShortcut: shortcut=%s", shortcut->get_as_text());
|
||||
|
|
|
@ -146,7 +146,7 @@ public:
|
|||
BitField<KeyModifierMask> get_modifiers_mask() const;
|
||||
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventWithModifiers() {}
|
||||
};
|
||||
|
@ -200,7 +200,7 @@ public:
|
|||
virtual String as_text_key_label() const;
|
||||
virtual String as_text_location() const;
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
static Ref<InputEventKey> create_reference(Key p_keycode_with_modifier_masks, bool p_physical = false);
|
||||
|
||||
|
@ -263,7 +263,7 @@ public:
|
|||
|
||||
virtual bool is_action_type() const override { return true; }
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventType get_type() const final override { return InputEventType::MOUSE_BUTTON; }
|
||||
|
||||
|
@ -308,7 +308,7 @@ public:
|
|||
|
||||
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
virtual bool accumulate(const Ref<InputEvent> &p_event) override;
|
||||
|
||||
|
@ -337,7 +337,7 @@ public:
|
|||
|
||||
virtual bool is_action_type() const override { return true; }
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
// The default device ID is `InputMap::ALL_DEVICES`.
|
||||
static Ref<InputEventJoypadMotion> create_reference(JoyAxis p_axis, float p_value, int p_device = -1);
|
||||
|
@ -370,7 +370,7 @@ public:
|
|||
virtual bool is_action_type() const override { return true; }
|
||||
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
// The default device ID is `InputMap::ALL_DEVICES`.
|
||||
static Ref<InputEventJoypadButton> create_reference(JoyButton p_btn_index, int p_device = -1);
|
||||
|
@ -404,7 +404,7 @@ public:
|
|||
|
||||
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventType get_type() const final override { return InputEventType::SCREEN_TOUCH; }
|
||||
|
||||
|
@ -456,7 +456,7 @@ public:
|
|||
|
||||
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
virtual bool accumulate(const Ref<InputEvent> &p_event) override;
|
||||
|
||||
|
@ -495,7 +495,7 @@ public:
|
|||
virtual bool is_action_type() const override { return true; }
|
||||
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventType get_type() const final override { return InputEventType::ACTION; }
|
||||
|
||||
|
@ -528,7 +528,7 @@ public:
|
|||
|
||||
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventType get_type() const final override { return InputEventType::MAGNIFY_GESTURE; }
|
||||
|
||||
|
@ -548,7 +548,7 @@ public:
|
|||
|
||||
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventType get_type() const final override { return InputEventType::PAN_GESTURE; }
|
||||
|
||||
|
@ -596,7 +596,7 @@ public:
|
|||
int get_controller_value() const;
|
||||
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventType get_type() const final override { return InputEventType::MIDI; }
|
||||
|
||||
|
@ -616,7 +616,7 @@ public:
|
|||
Ref<Shortcut> get_shortcut();
|
||||
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
InputEventType get_type() const final override { return InputEventType::SHORTCUT; }
|
||||
|
||||
|
|
|
@ -660,6 +660,10 @@ void Resource::reset_local_to_scene() {
|
|||
// Restores the state as if setup_local_to_scene() hadn't been called.
|
||||
}
|
||||
|
||||
String Resource::_to_string() {
|
||||
return (name.is_empty() ? "" : String(name) + " ") + "(" + path_cache + "):" + Object::_to_string();
|
||||
}
|
||||
|
||||
Node *(*Resource::_get_local_scene_func)() = nullptr;
|
||||
void (*Resource::_update_configuration_warning)() = nullptr;
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ protected:
|
|||
GDVIRTUAL0(_reset_state);
|
||||
|
||||
virtual Ref<Resource> _duplicate(const DuplicateParams &p_params) const;
|
||||
virtual String _to_string() override;
|
||||
|
||||
public:
|
||||
static Node *(*_get_local_scene_func)(); // Used by the editor.
|
||||
|
|
|
@ -1044,7 +1044,7 @@ String Object::to_string() {
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
return "<" + get_class() + "#" + itos(get_instance_id()) + ">";
|
||||
return _to_string();
|
||||
}
|
||||
|
||||
void Object::set_script(const Variant &p_script) {
|
||||
|
@ -1688,6 +1688,19 @@ bool Object::_uses_signal_mutex() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
String Object::_get_locale() const {
|
||||
TranslationServer *ts = TranslationServer::get_singleton();
|
||||
const StringName domain_name = get_translation_domain();
|
||||
if (ts->has_domain(domain_name)) {
|
||||
const Ref<TranslationDomain> domain = ts->get_or_add_domain(domain_name);
|
||||
const String &overridden = domain->get_locale_override();
|
||||
if (!overridden.is_empty()) {
|
||||
return overridden;
|
||||
}
|
||||
}
|
||||
return ts->get_locale();
|
||||
}
|
||||
|
||||
void Object::_set_bind(const StringName &p_set, const Variant &p_value) {
|
||||
set(p_set, p_value);
|
||||
}
|
||||
|
@ -1826,6 +1839,10 @@ void Object::notify_property_list_changed() {
|
|||
emit_signal(CoreStringName(property_list_changed));
|
||||
}
|
||||
|
||||
String Object::_to_string() {
|
||||
return "<" + get_class() + "#" + itos(get_instance_id()) + ">";
|
||||
}
|
||||
|
||||
void Object::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_class"), &Object::get_class);
|
||||
ClassDB::bind_method(D_METHOD("is_class", "class"), &Object::is_class);
|
||||
|
|
|
@ -738,6 +738,7 @@ protected:
|
|||
void _notification_backward(int p_notification);
|
||||
virtual void _notification_forwardv(int p_notification) {}
|
||||
virtual void _notification_backwardv(int p_notification) {}
|
||||
virtual String _to_string();
|
||||
|
||||
static void _bind_methods();
|
||||
static void _bind_compatibility_methods() {}
|
||||
|
@ -801,6 +802,9 @@ protected:
|
|||
|
||||
virtual bool _uses_signal_mutex() const;
|
||||
|
||||
// Internal helper to get the current locale, taking into account the translation domain.
|
||||
String _get_locale() const;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
struct VirtualMethodTracker {
|
||||
void **method;
|
||||
|
@ -916,7 +920,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual String to_string();
|
||||
String to_string();
|
||||
|
||||
// Used mainly by script, get and set all INCLUDING string.
|
||||
virtual Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const;
|
||||
|
|
|
@ -84,5 +84,5 @@ public:
|
|||
Variant get_member_variable_value(int p_frame_index, int p_variable_index) const;
|
||||
|
||||
String format(int p_indent_all = 0, int p_indent_frames = 4) const;
|
||||
virtual String to_string() override { return format(); }
|
||||
virtual String _to_string() override { return format(); }
|
||||
};
|
||||
|
|
|
@ -407,6 +407,9 @@
|
|||
<member name="editors/3d/navigation/zoom_style" type="int" setter="" getter="">
|
||||
The mouse cursor movement direction to use when zooming by moving the mouse. This does not affect zooming with the mouse wheel.
|
||||
</member>
|
||||
<member name="editors/3d/navigation_feel/angle_snap_threshold" type="float" setter="" getter="">
|
||||
The angle threshold for snapping camera rotation to 45-degree angles while orbiting with [kbd]Alt[/kbd] held.
|
||||
</member>
|
||||
<member name="editors/3d/navigation_feel/orbit_inertia" type="float" setter="" getter="">
|
||||
The inertia to use when orbiting in the 3D editor. Higher values make the camera start and stop slower, which looks smoother but adds latency.
|
||||
</member>
|
||||
|
|
|
@ -1163,6 +1163,7 @@
|
|||
<constant name="DRIVER_RESOURCE_COMMAND_QUEUE" value="3" enum="DriverResource">
|
||||
The main graphics-compute command queue ([code]rid[/code] parameter is ignored).
|
||||
- Vulkan: [code]VkQueue[/code].
|
||||
- D3D12: [code]ID3D12CommandQueue[/code].
|
||||
- Metal: [code]MTLCommandQueue[/code].
|
||||
</constant>
|
||||
<constant name="DRIVER_RESOURCE_QUEUE_FAMILY" value="4" enum="DriverResource">
|
||||
|
@ -1171,6 +1172,7 @@
|
|||
</constant>
|
||||
<constant name="DRIVER_RESOURCE_TEXTURE" value="5" enum="DriverResource">
|
||||
- Vulkan: [code]VkImage[/code].
|
||||
- D3D12: [code]ID3D12Resource[/code].
|
||||
</constant>
|
||||
<constant name="DRIVER_RESOURCE_TEXTURE_VIEW" value="6" enum="DriverResource">
|
||||
The view of an owned or shared texture.
|
||||
|
|
|
@ -5751,14 +5751,18 @@ uint64_t RenderingDeviceDriverD3D12::get_resource_native_handle(DriverResource p
|
|||
return 0;
|
||||
}
|
||||
case DRIVER_RESOURCE_COMMAND_QUEUE: {
|
||||
return (uint64_t)p_driver_id.id;
|
||||
const CommandQueueInfo *cmd_queue_info = (const CommandQueueInfo *)p_driver_id.id;
|
||||
return (uint64_t)cmd_queue_info->d3d_queue.Get();
|
||||
}
|
||||
case DRIVER_RESOURCE_QUEUE_FAMILY: {
|
||||
return 0;
|
||||
}
|
||||
case DRIVER_RESOURCE_TEXTURE: {
|
||||
const TextureInfo *tex_info = (const TextureInfo *)p_driver_id.id;
|
||||
return (uint64_t)tex_info->main_texture;
|
||||
if (tex_info->main_texture) {
|
||||
tex_info = tex_info->main_texture;
|
||||
}
|
||||
return (uint64_t)tex_info->resource;
|
||||
} break;
|
||||
case DRIVER_RESOURCE_TEXTURE_VIEW: {
|
||||
const TextureInfo *tex_info = (const TextureInfo *)p_driver_id.id;
|
||||
|
|
|
@ -455,6 +455,10 @@ void EditorNode::_update_from_settings() {
|
|||
String current_fallback_locale = GLOBAL_GET("internationalization/locale/fallback");
|
||||
if (current_fallback_locale != TranslationServer::get_singleton()->get_fallback_locale()) {
|
||||
TranslationServer::get_singleton()->set_fallback_locale(current_fallback_locale);
|
||||
Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_main_domain();
|
||||
if (!domain->is_enabled()) {
|
||||
domain->set_locale_override(current_fallback_locale);
|
||||
}
|
||||
scene_root->propagate_notification(Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED);
|
||||
}
|
||||
|
||||
|
@ -4203,8 +4207,15 @@ void EditorNode::set_preview_locale(const String &p_locale) {
|
|||
// Texts set in the editor could be identifiers that should never be translated.
|
||||
// So we need to disable translation entirely.
|
||||
Ref<TranslationDomain> main_domain = TranslationServer::get_singleton()->get_main_domain();
|
||||
main_domain->set_enabled(!p_locale.is_empty());
|
||||
main_domain->set_locale_override(p_locale);
|
||||
if (p_locale.is_empty()) {
|
||||
// Disable preview. Use the fallback locale.
|
||||
main_domain->set_enabled(false);
|
||||
main_domain->set_locale_override(TranslationServer::get_singleton()->get_fallback_locale());
|
||||
} else {
|
||||
// Preview a specific locale.
|
||||
main_domain->set_enabled(true);
|
||||
main_domain->set_locale_override(p_locale);
|
||||
}
|
||||
|
||||
_translation_resources_changed();
|
||||
}
|
||||
|
@ -7638,7 +7649,10 @@ EditorNode::EditorNode() {
|
|||
ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &EditorNode::_update_from_settings));
|
||||
GDExtensionManager::get_singleton()->connect("extensions_reloaded", callable_mp(this, &EditorNode::_gdextensions_reloaded));
|
||||
|
||||
TranslationServer::get_singleton()->get_main_domain()->set_enabled(false);
|
||||
Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_main_domain();
|
||||
domain->set_enabled(false);
|
||||
domain->set_locale_override(TranslationServer::get_singleton()->get_fallback_locale());
|
||||
|
||||
// Load settings.
|
||||
if (!EditorSettings::get_singleton()) {
|
||||
EditorSettings::create();
|
||||
|
|
|
@ -1213,7 +1213,7 @@ void Node3DEditorViewport::_update_name() {
|
|||
} break;
|
||||
}
|
||||
|
||||
if (auto_orthogonal) {
|
||||
if (orthogonal && auto_orthogonal) {
|
||||
// TRANSLATORS: This will be appended to the view name when Auto Orthogonal is enabled.
|
||||
name += " " + TTR("[auto]");
|
||||
}
|
||||
|
@ -2541,27 +2541,32 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
|||
if (ED_IS_SHORTCUT("spatial_editor/orbit_view_down", p_event)) {
|
||||
// Clamp rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented.
|
||||
cursor.x_rot = CLAMP(cursor.x_rot - Math::PI / 12.0, -1.57, 1.57);
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
view_type = VIEW_TYPE_USER;
|
||||
_update_name();
|
||||
}
|
||||
if (ED_IS_SHORTCUT("spatial_editor/orbit_view_up", p_event)) {
|
||||
// Clamp rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented.
|
||||
cursor.x_rot = CLAMP(cursor.x_rot + Math::PI / 12.0, -1.57, 1.57);
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
view_type = VIEW_TYPE_USER;
|
||||
_update_name();
|
||||
}
|
||||
if (ED_IS_SHORTCUT("spatial_editor/orbit_view_right", p_event)) {
|
||||
cursor.y_rot -= Math::PI / 12.0;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
view_type = VIEW_TYPE_USER;
|
||||
_update_name();
|
||||
}
|
||||
if (ED_IS_SHORTCUT("spatial_editor/orbit_view_left", p_event)) {
|
||||
cursor.y_rot += Math::PI / 12.0;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
view_type = VIEW_TYPE_USER;
|
||||
_update_name();
|
||||
}
|
||||
if (ED_IS_SHORTCUT("spatial_editor/orbit_view_180", p_event)) {
|
||||
cursor.y_rot += Math::PI;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
view_type = VIEW_TYPE_USER;
|
||||
_update_name();
|
||||
}
|
||||
|
@ -2766,30 +2771,69 @@ void Node3DEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, cons
|
|||
return;
|
||||
}
|
||||
|
||||
if (orthogonal && auto_orthogonal) {
|
||||
_menu_option(VIEW_PERSPECTIVE);
|
||||
}
|
||||
|
||||
const real_t degrees_per_pixel = EDITOR_GET("editors/3d/navigation_feel/orbit_sensitivity");
|
||||
const real_t radians_per_pixel = Math::deg_to_rad(degrees_per_pixel);
|
||||
const bool invert_y_axis = EDITOR_GET("editors/3d/navigation/invert_y_axis");
|
||||
const bool invert_x_axis = EDITOR_GET("editors/3d/navigation/invert_x_axis");
|
||||
|
||||
if (invert_y_axis) {
|
||||
cursor.x_rot -= p_relative.y * radians_per_pixel;
|
||||
} else {
|
||||
cursor.x_rot += p_relative.y * radians_per_pixel;
|
||||
}
|
||||
// Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented.
|
||||
cursor.x_rot = CLAMP(cursor.x_rot, -1.57, 1.57);
|
||||
cursor.unsnapped_x_rot += p_relative.y * radians_per_pixel * (invert_y_axis ? -1 : 1);
|
||||
cursor.unsnapped_x_rot = CLAMP(cursor.unsnapped_x_rot, -1.57, 1.57);
|
||||
cursor.unsnapped_y_rot += p_relative.x * radians_per_pixel * (invert_x_axis ? -1 : 1);
|
||||
|
||||
if (invert_x_axis) {
|
||||
cursor.y_rot -= p_relative.x * radians_per_pixel;
|
||||
} else {
|
||||
cursor.y_rot += p_relative.x * radians_per_pixel;
|
||||
cursor.x_rot = cursor.unsnapped_x_rot;
|
||||
cursor.y_rot = cursor.unsnapped_y_rot;
|
||||
|
||||
if (_is_nav_modifier_pressed("spatial_editor/viewport_orbit_snap_modifier_1") &&
|
||||
_is_nav_modifier_pressed("spatial_editor/viewport_orbit_snap_modifier_2")) {
|
||||
const real_t snap_angle = Math::deg_to_rad(45.0);
|
||||
const real_t snap_threshold = Math::deg_to_rad((real_t)EDITOR_GET("editors/3d/navigation_feel/angle_snap_threshold"));
|
||||
|
||||
real_t x_rot_snapped = Math::snapped(cursor.unsnapped_x_rot, snap_angle);
|
||||
real_t y_rot_snapped = Math::snapped(cursor.unsnapped_y_rot, snap_angle);
|
||||
|
||||
real_t x_dist = Math::abs(cursor.unsnapped_x_rot - x_rot_snapped);
|
||||
real_t y_dist = Math::abs(cursor.unsnapped_y_rot - y_rot_snapped);
|
||||
|
||||
if (x_dist < snap_threshold && y_dist < snap_threshold) {
|
||||
cursor.x_rot = x_rot_snapped;
|
||||
cursor.y_rot = y_rot_snapped;
|
||||
|
||||
real_t y_rot_wrapped = Math::wrapf(y_rot_snapped, (real_t)-Math::PI, (real_t)Math::PI);
|
||||
|
||||
if (Math::abs(x_rot_snapped) < snap_threshold) {
|
||||
if (Math::abs(y_rot_wrapped) < snap_threshold) {
|
||||
view_type = VIEW_TYPE_FRONT;
|
||||
} else if (Math::abs(Math::abs(y_rot_wrapped) - Math::PI) < snap_threshold) {
|
||||
view_type = VIEW_TYPE_REAR;
|
||||
} else if (Math::abs(y_rot_wrapped - Math::PI / 2.0) < snap_threshold) {
|
||||
view_type = VIEW_TYPE_LEFT;
|
||||
} else if (Math::abs(y_rot_wrapped + Math::PI / 2.0) < snap_threshold) {
|
||||
view_type = VIEW_TYPE_RIGHT;
|
||||
} else {
|
||||
// Only switch to ortho for 90-degree views.
|
||||
return;
|
||||
}
|
||||
_set_auto_orthogonal();
|
||||
_update_name();
|
||||
} else if (Math::abs(Math::abs(x_rot_snapped) - Math::PI / 2.0) < snap_threshold) {
|
||||
if (Math::abs(y_rot_wrapped) < snap_threshold ||
|
||||
Math::abs(Math::abs(y_rot_wrapped) - Math::PI) < snap_threshold ||
|
||||
Math::abs(y_rot_wrapped - Math::PI / 2.0) < snap_threshold ||
|
||||
Math::abs(y_rot_wrapped + Math::PI / 2.0) < snap_threshold) {
|
||||
view_type = x_rot_snapped > 0 ? VIEW_TYPE_TOP : VIEW_TYPE_BOTTOM;
|
||||
_set_auto_orthogonal();
|
||||
_update_name();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
view_type = VIEW_TYPE_USER;
|
||||
_update_name();
|
||||
if (orthogonal && auto_orthogonal) {
|
||||
_menu_option(VIEW_PERSPECTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
|
||||
|
@ -2817,8 +2861,10 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const
|
|||
}
|
||||
// Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented.
|
||||
cursor.x_rot = CLAMP(cursor.x_rot, -1.57, 1.57);
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
|
||||
cursor.y_rot += p_relative.x * radians_per_pixel;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
|
||||
// Look is like the opposite of Orbit: the focus point rotates around the camera
|
||||
Transform3D camera_transform = to_camera_transform(cursor);
|
||||
|
@ -3803,6 +3849,8 @@ void Node3DEditorViewport::_apply_camera_transform_to_cursor() {
|
|||
|
||||
cursor.x_rot = -camera_transform.basis.get_euler().x;
|
||||
cursor.y_rot = -camera_transform.basis.get_euler().y;
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
}
|
||||
|
||||
void Node3DEditorViewport::_menu_option(int p_option) {
|
||||
|
@ -3811,6 +3859,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
|
|||
case VIEW_TOP: {
|
||||
cursor.y_rot = 0;
|
||||
cursor.x_rot = Math::PI / 2.0;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
set_message(TTR("Top View."), 2);
|
||||
view_type = VIEW_TYPE_TOP;
|
||||
_set_auto_orthogonal();
|
||||
|
@ -3820,6 +3870,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
|
|||
case VIEW_BOTTOM: {
|
||||
cursor.y_rot = 0;
|
||||
cursor.x_rot = -Math::PI / 2.0;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
set_message(TTR("Bottom View."), 2);
|
||||
view_type = VIEW_TYPE_BOTTOM;
|
||||
_set_auto_orthogonal();
|
||||
|
@ -3829,6 +3881,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
|
|||
case VIEW_LEFT: {
|
||||
cursor.x_rot = 0;
|
||||
cursor.y_rot = Math::PI / 2.0;
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
set_message(TTR("Left View."), 2);
|
||||
view_type = VIEW_TYPE_LEFT;
|
||||
_set_auto_orthogonal();
|
||||
|
@ -3838,6 +3892,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
|
|||
case VIEW_RIGHT: {
|
||||
cursor.x_rot = 0;
|
||||
cursor.y_rot = -Math::PI / 2.0;
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
set_message(TTR("Right View."), 2);
|
||||
view_type = VIEW_TYPE_RIGHT;
|
||||
_set_auto_orthogonal();
|
||||
|
@ -3847,6 +3903,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
|
|||
case VIEW_FRONT: {
|
||||
cursor.x_rot = 0;
|
||||
cursor.y_rot = 0;
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
set_message(TTR("Front View."), 2);
|
||||
view_type = VIEW_TYPE_FRONT;
|
||||
_set_auto_orthogonal();
|
||||
|
@ -3856,6 +3914,8 @@ void Node3DEditorViewport::_menu_option(int p_option) {
|
|||
case VIEW_REAR: {
|
||||
cursor.x_rot = 0;
|
||||
cursor.y_rot = Math::PI;
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
set_message(TTR("Rear View."), 2);
|
||||
view_type = VIEW_TYPE_REAR;
|
||||
_set_auto_orthogonal();
|
||||
|
@ -4485,9 +4545,11 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
|
|||
}
|
||||
if (p_state.has("x_rotation")) {
|
||||
cursor.x_rot = p_state["x_rotation"];
|
||||
cursor.unsnapped_x_rot = cursor.x_rot;
|
||||
}
|
||||
if (p_state.has("y_rotation")) {
|
||||
cursor.y_rot = p_state["y_rotation"];
|
||||
cursor.unsnapped_y_rot = cursor.y_rot;
|
||||
}
|
||||
if (p_state.has("distance")) {
|
||||
cursor.distance = p_state["distance"];
|
||||
|
@ -6056,6 +6118,8 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
|
|||
// Registering with Key::NONE intentionally creates an empty Array.
|
||||
register_shortcut_action("spatial_editor/viewport_orbit_modifier_1", TTRC("Viewport Orbit Modifier 1"), Key::NONE);
|
||||
register_shortcut_action("spatial_editor/viewport_orbit_modifier_2", TTRC("Viewport Orbit Modifier 2"), Key::NONE);
|
||||
register_shortcut_action("spatial_editor/viewport_orbit_snap_modifier_1", TTRC("Viewport Orbit Snap Modifier 1"), Key::ALT);
|
||||
register_shortcut_action("spatial_editor/viewport_orbit_snap_modifier_2", TTRC("Viewport Orbit Snap Modifier 2"), Key::NONE);
|
||||
register_shortcut_action("spatial_editor/viewport_pan_modifier_1", TTRC("Viewport Pan Modifier 1"), Key::SHIFT);
|
||||
register_shortcut_action("spatial_editor/viewport_pan_modifier_2", TTRC("Viewport Pan Modifier 2"), Key::NONE);
|
||||
register_shortcut_action("spatial_editor/viewport_zoom_modifier_1", TTRC("Viewport Zoom Modifier 1"), Key::SHIFT);
|
||||
|
|
|
@ -409,6 +409,7 @@ private:
|
|||
struct Cursor {
|
||||
Vector3 pos;
|
||||
real_t x_rot, y_rot, distance, fov_scale;
|
||||
real_t unsnapped_x_rot, unsnapped_y_rot;
|
||||
Vector3 eye_pos; // Used in freelook mode
|
||||
bool region_select;
|
||||
Point2 region_begin, region_end;
|
||||
|
@ -417,6 +418,8 @@ private:
|
|||
// These rotations place the camera in +X +Y +Z, aka south east, facing north west.
|
||||
x_rot = 0.5;
|
||||
y_rot = -0.5;
|
||||
unsnapped_x_rot = x_rot;
|
||||
unsnapped_y_rot = y_rot;
|
||||
distance = 4;
|
||||
fov_scale = 1.0;
|
||||
region_select = false;
|
||||
|
|
|
@ -936,6 +936,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
|||
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/orbit_inertia", 0.0, "0,1,0.001")
|
||||
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/translation_inertia", 0.05, "0,1,0.001")
|
||||
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/zoom_inertia", 0.05, "0,1,0.001")
|
||||
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/angle_snap_threshold", 10.0, "1,20,0.1,degrees")
|
||||
_initial_set("editors/3d/navigation/show_viewport_rotation_gizmo", true);
|
||||
_initial_set("editors/3d/navigation/show_viewport_navigation_gizmo", DisplayServer::get_singleton()->is_touchscreen_available());
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ Vector<uint8_t> compile_glslang_shader(RenderingDeviceCommons::ShaderStage p_sta
|
|||
glslang::EShTargetLanguageVersion TargetVersion = (glslang::EShTargetLanguageVersion)p_spirv_version;
|
||||
|
||||
glslang::TShader shader(stages[p_stage]);
|
||||
CharString cs = p_source_code.ascii();
|
||||
CharString cs = p_source_code.utf8();
|
||||
const char *cs_strings = cs.get_data();
|
||||
std::string preamble = "";
|
||||
|
||||
|
|
|
@ -37,6 +37,18 @@ partial class ExportedProperties
|
|||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @LamdaPropertyString = "LamdaPropertyString";
|
||||
/// <summary>
|
||||
/// Cached name for the 'PrimaryCtorParameter' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @PrimaryCtorParameter = "PrimaryCtorParameter";
|
||||
/// <summary>
|
||||
/// Cached name for the 'ConstantMath' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @ConstantMath = "ConstantMath";
|
||||
/// <summary>
|
||||
/// Cached name for the 'StaticStringAddition' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @StaticStringAddition = "StaticStringAddition";
|
||||
/// <summary>
|
||||
/// Cached name for the 'PropertyBoolean' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @PropertyBoolean = "PropertyBoolean";
|
||||
|
@ -317,6 +329,18 @@ partial class ExportedProperties
|
|||
this.@LamdaPropertyString = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@PrimaryCtorParameter) {
|
||||
this.@PrimaryCtorParameter = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@ConstantMath) {
|
||||
this.@ConstantMath = global::Godot.NativeInterop.VariantUtils.ConvertTo<float>(value);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@StaticStringAddition) {
|
||||
this.@StaticStringAddition = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@PropertyBoolean) {
|
||||
this.@PropertyBoolean = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value);
|
||||
return true;
|
||||
|
@ -599,6 +623,18 @@ partial class ExportedProperties
|
|||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@LamdaPropertyString);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@PrimaryCtorParameter) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@PrimaryCtorParameter);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@ConstantMath) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<float>(this.@ConstantMath);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@StaticStringAddition) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@StaticStringAddition);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@PropertyBoolean) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<bool>(this.@PropertyBoolean);
|
||||
return true;
|
||||
|
@ -870,6 +906,9 @@ partial class ExportedProperties
|
|||
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@FullPropertyString_Complex, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@_lamdaPropertyString, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@LamdaPropertyString, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@PrimaryCtorParameter, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)3, name: PropertyName.@ConstantMath, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@StaticStringAddition, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.@PropertyBoolean, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@PropertyChar, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@PropertySByte, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
|
|
|
@ -11,7 +11,7 @@ partial class ExportedProperties
|
|||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant> GetGodotPropertyDefaultValues()
|
||||
{
|
||||
var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(64);
|
||||
var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(67);
|
||||
string __NotGenerateComplexLamdaProperty_default_value = default;
|
||||
values.Add(PropertyName.@NotGenerateComplexLamdaProperty, global::Godot.Variant.From<string>(__NotGenerateComplexLamdaProperty_default_value));
|
||||
string __NotGenerateLamdaNoFieldProperty_default_value = default;
|
||||
|
@ -26,6 +26,12 @@ partial class ExportedProperties
|
|||
values.Add(PropertyName.@FullPropertyString_Complex, global::Godot.Variant.From<string>(__FullPropertyString_Complex_default_value));
|
||||
string __LamdaPropertyString_default_value = "LamdaPropertyString";
|
||||
values.Add(PropertyName.@LamdaPropertyString, global::Godot.Variant.From<string>(__LamdaPropertyString_default_value));
|
||||
string __PrimaryCtorParameter_default_value = default;
|
||||
values.Add(PropertyName.@PrimaryCtorParameter, global::Godot.Variant.From<string>(__PrimaryCtorParameter_default_value));
|
||||
float __ConstantMath_default_value = 2 * global::Godot.Mathf.Pi;
|
||||
values.Add(PropertyName.@ConstantMath, global::Godot.Variant.From<float>(__ConstantMath_default_value));
|
||||
string __StaticStringAddition_default_value = string.Empty + string.Empty;
|
||||
values.Add(PropertyName.@StaticStringAddition, global::Godot.Variant.From<string>(__StaticStringAddition_default_value));
|
||||
bool __PropertyBoolean_default_value = true;
|
||||
values.Add(PropertyName.@PropertyBoolean, global::Godot.Variant.From<bool>(__PropertyBoolean_default_value));
|
||||
char __PropertyChar_default_value = 'f';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public partial class ExportedProperties : GodotObject
|
||||
public partial class ExportedProperties(string primaryCtorParameter) : GodotObject
|
||||
{
|
||||
// Do not generate default value
|
||||
private String _notGeneratePropertyString = new string("not generate");
|
||||
|
@ -91,6 +91,18 @@ public partial class ExportedProperties : GodotObject
|
|||
set => _lamdaPropertyString = value;
|
||||
}
|
||||
|
||||
// Primary Constructor Parameter
|
||||
[Export]
|
||||
public String PrimaryCtorParameter { get; set; } = primaryCtorParameter;
|
||||
|
||||
// Constant Math Expression
|
||||
[Export]
|
||||
public Single ConstantMath { get; set; } = 2 * Mathf.Pi;
|
||||
|
||||
// Static Strings Addition
|
||||
[Export]
|
||||
public string StaticStringAddition { get; set; } = string.Empty + string.Empty;
|
||||
|
||||
// Auto Property
|
||||
[Export] private Boolean PropertyBoolean { get; set; } = true;
|
||||
[Export] private Char PropertyChar { get; set; } = 'f';
|
||||
|
|
|
@ -336,7 +336,11 @@ namespace Godot.SourceGenerators
|
|||
if (initializer != null)
|
||||
{
|
||||
var sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
|
||||
value = initializer.Value.FullQualifiedSyntax(sm);
|
||||
var initializerValue = initializer.Value;
|
||||
if (!IsStaticallyResolvable(initializerValue, sm))
|
||||
value = "default";
|
||||
else
|
||||
value = initializer.Value.FullQualifiedSyntax(sm);
|
||||
}
|
||||
|
||||
exportedMembers.Add(new ExportedPropertyMetadata(
|
||||
|
@ -424,109 +428,28 @@ namespace Godot.SourceGenerators
|
|||
|
||||
private static bool IsStaticallyResolvable(ExpressionSyntax expression, SemanticModel semanticModel)
|
||||
{
|
||||
// Handle literals (e.g., `10`, `"string"`, `true`, etc.)
|
||||
if (expression is LiteralExpressionSyntax)
|
||||
// Find non-static node in expression
|
||||
foreach (SyntaxNode descendant in expression.DescendantNodesAndSelf())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle negative literals (e.g., `-10`)
|
||||
if (expression is PrefixUnaryExpressionSyntax { Operand: LiteralExpressionSyntax } &&
|
||||
expression.Kind() == SyntaxKind.UnaryMinusExpression)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle identifiers (e.g., variable names)
|
||||
if (expression is IdentifierNameSyntax identifier)
|
||||
{
|
||||
var symbolInfo = semanticModel.GetSymbolInfo(identifier).Symbol;
|
||||
|
||||
// Ensure it's a static member
|
||||
return symbolInfo is { IsStatic: true };
|
||||
}
|
||||
|
||||
// Handle member access (e.g., `MyClass.StaticValue`)
|
||||
if (expression is MemberAccessExpressionSyntax memberAccess)
|
||||
{
|
||||
var symbolInfo = semanticModel.GetSymbolInfo(memberAccess).Symbol;
|
||||
|
||||
// Ensure it's referring to a static member
|
||||
return symbolInfo is { IsStatic: true };
|
||||
}
|
||||
|
||||
// Handle object creation expressions (e.g., `new Vector2(1.0f, 2.0f)`)
|
||||
if (expression is ObjectCreationExpressionSyntax objectCreation)
|
||||
{
|
||||
// Recursively ensure all its arguments are self-contained
|
||||
if (objectCreation.ArgumentList == null)
|
||||
// Constant nodes are static
|
||||
if (semanticModel.GetConstantValue(descendant).HasValue)
|
||||
{
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
foreach (var argument in objectCreation.ArgumentList.Arguments)
|
||||
|
||||
// Check non-static symbol
|
||||
SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(descendant);
|
||||
if (symbolInfo.Symbol is ISymbol symbol)
|
||||
{
|
||||
if (!IsStaticallyResolvable(argument.Expression, semanticModel))
|
||||
if (symbol.Kind is SymbolKind.Local or SymbolKind.Parameter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expression is ImplicitObjectCreationExpressionSyntax)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expression is InvocationExpressionSyntax invocationExpression)
|
||||
{
|
||||
// Resolve the method being invoked
|
||||
var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression).Symbol;
|
||||
|
||||
if (symbolInfo is IMethodSymbol methodSymbol)
|
||||
{
|
||||
// Ensure the method is static
|
||||
if (methodSymbol.IsStatic)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expression is InterpolatedStringExpressionSyntax interpolatedString)
|
||||
{
|
||||
foreach (var content in interpolatedString.Contents)
|
||||
{
|
||||
if (content is not InterpolationSyntax interpolation)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Analyze the expression inside `${...}`
|
||||
var interpolatedExpression = interpolation.Expression;
|
||||
|
||||
if (!IsStaticallyResolvable(interpolatedExpression, semanticModel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expression is InitializerExpressionSyntax initializerExpressionSyntax)
|
||||
{
|
||||
foreach (var content in initializerExpressionSyntax.Expressions)
|
||||
{
|
||||
if (!IsStaticallyResolvable(content, semanticModel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle other expressions conservatively (e.g., method calls, instance references, etc.)
|
||||
return false;
|
||||
// No non-static nodes found
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool MemberHasNodeType(ITypeSymbol memberType, MarshalType marshalType)
|
||||
|
|
|
@ -205,7 +205,7 @@ public:
|
|||
bool has_java_method(const StringName &p_method) const;
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
#endif
|
||||
|
||||
JavaClass();
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
bool has_java_method(const StringName &p_method) const;
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
virtual String to_string() override;
|
||||
virtual String _to_string() override;
|
||||
|
||||
jobject get_instance() { return instance; }
|
||||
|
||||
|
|
|
@ -826,7 +826,7 @@ Ref<JavaClass> JavaClass::get_java_parent_class() const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
String JavaClass::to_string() {
|
||||
String JavaClass::_to_string() {
|
||||
return "<JavaClass:" + java_class_name + ">";
|
||||
}
|
||||
|
||||
|
@ -874,11 +874,11 @@ Ref<JavaClass> JavaObject::get_java_class() const {
|
|||
return base_class;
|
||||
}
|
||||
|
||||
String JavaObject::to_string() {
|
||||
String JavaObject::_to_string() {
|
||||
if (base_class.is_valid() && instance) {
|
||||
return "<JavaObject:" + base_class->java_class_name + " \"" + (String)call("toString") + "\">";
|
||||
}
|
||||
return RefCounted::to_string();
|
||||
return RefCounted::_to_string();
|
||||
}
|
||||
|
||||
bool JavaObject::has_java_method(const StringName &p_method) const {
|
||||
|
|
|
@ -247,6 +247,9 @@ def configure(env: "SConsEnvironment"):
|
|||
|
||||
if not env["builtin_enet"]:
|
||||
env.ParseConfig("pkg-config libenet --cflags --libs")
|
||||
print_warning(
|
||||
"System-provided ENet has its functionality limited to IPv4 only and no DTLS support, unless patched for Godot."
|
||||
)
|
||||
|
||||
if not env["builtin_zstd"]:
|
||||
env.ParseConfig("pkg-config libzstd --cflags --libs")
|
||||
|
|
|
@ -215,11 +215,8 @@ void Label3D::_notification(int p_what) {
|
|||
window->disconnect("size_changed", callable_mp(this, &Label3D::_font_changed));
|
||||
} break;
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
String new_text = atr(text);
|
||||
if (new_text == xl_text) {
|
||||
return; // Nothing new.
|
||||
}
|
||||
xl_text = new_text;
|
||||
// Language update might change the appearance of some characters.
|
||||
xl_text = atr(text);
|
||||
dirty_text = true;
|
||||
_queue_update();
|
||||
} break;
|
||||
|
@ -483,8 +480,9 @@ void Label3D::_shape() {
|
|||
TS->shaped_text_clear(text_rid);
|
||||
TS->shaped_text_set_direction(text_rid, text_direction);
|
||||
|
||||
String txt = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
|
||||
TS->shaped_text_add_string(text_rid, txt, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
String txt = uppercase ? TS->string_to_upper(xl_text, lang) : xl_text;
|
||||
TS->shaped_text_add_string(text_rid, txt, font->get_rids(), font_size, font->get_opentype_features(), lang);
|
||||
|
||||
TypedArray<Vector3i> stt;
|
||||
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
|
||||
|
|
|
@ -459,8 +459,8 @@ Variant Tween::interpolate_variant(const Variant &p_initial_val, const Variant &
|
|||
return ret;
|
||||
}
|
||||
|
||||
String Tween::to_string() {
|
||||
String ret = Object::to_string();
|
||||
String Tween::_to_string() {
|
||||
String ret = Object::_to_string();
|
||||
Node *node = get_bound_node();
|
||||
if (node) {
|
||||
ret += vformat(" (bound to %s)", node->get_name());
|
||||
|
|
|
@ -140,10 +140,9 @@ private:
|
|||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual String _to_string() override;
|
||||
|
||||
public:
|
||||
virtual String to_string() override;
|
||||
|
||||
Ref<PropertyTweener> tween_property(const Object *p_target, const NodePath &p_property, Variant p_to, double p_duration);
|
||||
Ref<IntervalTweener> tween_interval(double p_time);
|
||||
Ref<CallbackTweener> tween_callback(const Callable &p_callback);
|
||||
|
|
|
@ -566,7 +566,8 @@ void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) const {
|
|||
} else {
|
||||
p_paragraph->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
p_paragraph->add_string(p_text, font, font_size, language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
p_paragraph->add_string(p_text, font, font_size, lang);
|
||||
p_paragraph->set_text_overrun_behavior(overrun_behavior);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,13 +188,14 @@ void CodeEdit::_notification(int p_what) {
|
|||
code_completion_line_ofs = CLAMP((code_completion_force_item_center < 0 ? code_completion_current_selected : code_completion_force_item_center) - lines / 2, 0, code_completion_options_count - lines);
|
||||
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, code_completion_rect.position.y + (code_completion_current_selected - code_completion_line_ofs) * row_height), Size2(code_completion_rect.size.width, row_height)), theme_cache.code_completion_selected_color);
|
||||
|
||||
const String &lang = _get_locale();
|
||||
for (int i = 0; i < lines; i++) {
|
||||
int l = code_completion_line_ofs + i;
|
||||
ERR_CONTINUE(l < 0 || l >= code_completion_options_count);
|
||||
|
||||
Ref<TextLine> tl;
|
||||
tl.instantiate();
|
||||
tl->add_string(code_completion_options[l].display, theme_cache.font, theme_cache.font_size);
|
||||
tl->add_string(code_completion_options[l].display, theme_cache.font, theme_cache.font_size, lang);
|
||||
|
||||
int yofs = (row_height - tl->get_size().y) / 2;
|
||||
Point2 title_pos(code_completion_rect.position.x, code_completion_rect.position.y + i * row_height + yofs);
|
||||
|
@ -1521,14 +1522,15 @@ void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2
|
|||
if (E) {
|
||||
text_rid = E->value;
|
||||
} else {
|
||||
const String &lang = _get_locale();
|
||||
String fc = String::num_int64(p_line + 1).lpad(line_number_digits, line_number_padding);
|
||||
if (is_localizing_numeral_system()) {
|
||||
fc = TS->format_number(fc);
|
||||
fc = TS->format_number(fc, lang);
|
||||
}
|
||||
|
||||
text_rid = TS->create_shaped_text();
|
||||
if (theme_cache.font.is_valid()) {
|
||||
TS->shaped_text_add_string(text_rid, fc, theme_cache.font->get_rids(), theme_cache.font_size, theme_cache.font->get_opentype_features());
|
||||
TS->shaped_text_add_string(text_rid, fc, theme_cache.font->get_rids(), theme_cache.font_size, theme_cache.font->get_opentype_features(), lang);
|
||||
}
|
||||
line_number_text_cache.insert(p_line, text_rid);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "core/input/input_map.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/string/string_builder.h"
|
||||
#include "core/string/translation_server.h"
|
||||
#include "scene/gui/scroll_container.h"
|
||||
#include "scene/main/canvas_layer.h"
|
||||
#include "scene/main/window.h"
|
||||
|
@ -3548,12 +3547,9 @@ bool Control::is_layout_rtl() const {
|
|||
} else if (proj_root_layout_direction == 2) {
|
||||
data.is_rtl = true;
|
||||
} else if (proj_root_layout_direction == 3) {
|
||||
String locale = OS::get_singleton()->get_locale();
|
||||
data.is_rtl = TS->is_locale_right_to_left(locale);
|
||||
data.is_rtl = TS->is_locale_right_to_left(OS::get_singleton()->get_locale());
|
||||
} else {
|
||||
const Ref<Translation> &t = TranslationServer::get_singleton()->get_translation_object(TranslationServer::get_singleton()->get_locale());
|
||||
String locale = t.is_valid() ? t->get_locale() : TranslationServer::get_singleton()->get_fallback_locale();
|
||||
data.is_rtl = TS->is_locale_right_to_left(locale);
|
||||
data.is_rtl = TS->is_locale_right_to_left(_get_locale());
|
||||
}
|
||||
return data.is_rtl;
|
||||
}
|
||||
|
@ -3564,8 +3560,9 @@ bool Control::is_layout_rtl() const {
|
|||
return data.is_rtl;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
const StringName domain_name = get_translation_domain();
|
||||
Node *parent_node = get_parent();
|
||||
while (parent_node) {
|
||||
while (parent_node && domain_name == parent_node->get_translation_domain()) {
|
||||
Control *parent_control = Object::cast_to<Control>(parent_node);
|
||||
if (parent_control) {
|
||||
data.is_rtl = parent_control->is_layout_rtl();
|
||||
|
@ -3588,22 +3585,19 @@ bool Control::is_layout_rtl() const {
|
|||
String locale = OS::get_singleton()->get_locale();
|
||||
data.is_rtl = TS->is_locale_right_to_left(locale);
|
||||
} else {
|
||||
String locale = TranslationServer::get_singleton()->get_tool_locale();
|
||||
data.is_rtl = TS->is_locale_right_to_left(locale);
|
||||
data.is_rtl = TS->is_locale_right_to_left(_get_locale());
|
||||
}
|
||||
} else if (data.layout_dir == LAYOUT_DIRECTION_APPLICATION_LOCALE) {
|
||||
if (GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
|
||||
data.is_rtl = true;
|
||||
} else {
|
||||
String locale = TranslationServer::get_singleton()->get_tool_locale();
|
||||
data.is_rtl = TS->is_locale_right_to_left(locale);
|
||||
data.is_rtl = TS->is_locale_right_to_left(_get_locale());
|
||||
}
|
||||
} else if (data.layout_dir == LAYOUT_DIRECTION_SYSTEM_LOCALE) {
|
||||
if (GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
|
||||
const_cast<Control *>(this)->data.is_rtl = true;
|
||||
data.is_rtl = true;
|
||||
} else {
|
||||
String locale = OS::get_singleton()->get_locale();
|
||||
const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale);
|
||||
data.is_rtl = TS->is_locale_right_to_left(OS::get_singleton()->get_locale());
|
||||
}
|
||||
} else {
|
||||
data.is_rtl = (data.layout_dir == LAYOUT_DIRECTION_RTL);
|
||||
|
|
|
@ -488,7 +488,8 @@ void FoldableContainer::_shape() {
|
|||
}
|
||||
text_buf->set_horizontal_alignment(_get_actual_alignment());
|
||||
text_buf->set_text_overrun_behavior(overrun_behavior);
|
||||
text_buf->add_string(atr(title), font, font_size, language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
text_buf->add_string(atr(title), font, font_size, lang);
|
||||
}
|
||||
|
||||
HorizontalAlignment FoldableContainer::_get_actual_alignment() const {
|
||||
|
|
|
@ -43,7 +43,8 @@ void ItemList::_shape_text(int p_idx) {
|
|||
} else {
|
||||
item.text_buf->set_direction((TextServer::Direction)item.text_direction);
|
||||
}
|
||||
item.text_buf->add_string(item.xl_text, theme_cache.font, theme_cache.font_size, item.language);
|
||||
const String &lang = item.language.is_empty() ? _get_locale() : item.language;
|
||||
item.text_buf->add_string(item.xl_text, theme_cache.font, theme_cache.font_size, lang);
|
||||
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
|
||||
item.text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_TRIM_START_EDGE_SPACES | TextServer::BREAK_TRIM_END_EDGE_SPACES);
|
||||
} else {
|
||||
|
|
|
@ -136,6 +136,8 @@ int Label::get_line_height(int p_line) const {
|
|||
}
|
||||
|
||||
void Label::_shape() const {
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
|
||||
Ref<StyleBox> style = theme_cache.normal_style;
|
||||
int width = (get_size().width - style->get_minimum_size().width);
|
||||
|
||||
|
@ -149,7 +151,7 @@ void Label::_shape() const {
|
|||
}
|
||||
paragraphs.clear();
|
||||
|
||||
String txt = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
|
||||
String txt = (uppercase) ? TS->string_to_upper(xl_text, lang) : xl_text;
|
||||
if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) {
|
||||
txt = txt.substr(0, visible_chars);
|
||||
}
|
||||
|
@ -183,7 +185,7 @@ void Label::_shape() const {
|
|||
ERR_FAIL_COND(font.is_null());
|
||||
|
||||
if (para.dirty) {
|
||||
TS->shaped_text_add_string(para.text_rid, para.text, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
TS->shaped_text_add_string(para.text_rid, para.text, font->get_rids(), font_size, font->get_opentype_features(), lang);
|
||||
} else {
|
||||
int spans = TS->shaped_get_span_count(para.text_rid);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
|
@ -709,15 +711,14 @@ void Label::_notification(int p_what) {
|
|||
} break;
|
||||
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
String new_text = atr(text);
|
||||
if (new_text == xl_text) {
|
||||
return; // Nothing new.
|
||||
const String new_text = atr(text);
|
||||
if (new_text != xl_text) {
|
||||
xl_text = new_text;
|
||||
if (visible_ratio < 1) {
|
||||
visible_chars = get_total_character_count() * visible_ratio;
|
||||
}
|
||||
}
|
||||
xl_text = new_text;
|
||||
if (visible_ratio < 1) {
|
||||
visible_chars = get_total_character_count() * visible_ratio;
|
||||
}
|
||||
text_dirty = true;
|
||||
text_dirty = true; // Language update might change the appearance of some characters.
|
||||
|
||||
queue_accessibility_update();
|
||||
queue_redraw();
|
||||
|
|
|
@ -1202,11 +1202,8 @@ void LineEdit::_notification(int p_what) {
|
|||
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_REPLACE_SELECTED_TEXT, callable_mp(this, &LineEdit::_accessibility_action_replace_selected));
|
||||
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_SET_VALUE, callable_mp(this, &LineEdit::_accessibility_action_set_value));
|
||||
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_SHOW_CONTEXT_MENU, callable_mp(this, &LineEdit::_accessibility_action_menu));
|
||||
if (!language.is_empty()) {
|
||||
DisplayServer::get_singleton()->accessibility_update_set_language(ae, language);
|
||||
} else {
|
||||
DisplayServer::get_singleton()->accessibility_update_set_language(ae, TranslationServer::get_singleton()->get_tool_locale());
|
||||
}
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
DisplayServer::get_singleton()->accessibility_update_set_language(ae, lang);
|
||||
|
||||
bool rtl = is_layout_rtl();
|
||||
Ref<StyleBox> style = theme_cache.normal;
|
||||
|
@ -2979,7 +2976,8 @@ void LineEdit::_shape() {
|
|||
}
|
||||
TS->shaped_text_set_preserve_control(text_rid, draw_control_chars);
|
||||
|
||||
TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, font->get_opentype_features(), lang);
|
||||
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, t));
|
||||
|
||||
full_width = TS->shaped_text_get_size(text_rid).x;
|
||||
|
|
|
@ -43,7 +43,8 @@ void LinkButton::_shape() {
|
|||
text_buf->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
TS->shaped_text_set_bidi_override(text_buf->get_rid(), structured_text_parser(st_parser, st_args, xl_text));
|
||||
text_buf->add_string(xl_text, font, font_size, language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
text_buf->add_string(xl_text, font, font_size, lang);
|
||||
|
||||
queue_accessibility_update();
|
||||
}
|
||||
|
|
|
@ -517,7 +517,8 @@ void MenuBar::shape(Menu &p_menu) {
|
|||
} else {
|
||||
p_menu.text_buf->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
p_menu.text_buf->add_string(atr(p_menu.name), theme_cache.font, theme_cache.font_size, language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
p_menu.text_buf->add_string(atr(p_menu.name), theme_cache.font, theme_cache.font_size, lang);
|
||||
}
|
||||
|
||||
void MenuBar::_refresh_menu_names() {
|
||||
|
|
|
@ -1018,11 +1018,12 @@ void PopupMenu::_shape_item(int p_idx) const {
|
|||
} else {
|
||||
items.write[p_idx].text_buf->set_direction((TextServer::Direction)items[p_idx].text_direction);
|
||||
}
|
||||
items.write[p_idx].text_buf->add_string(items.write[p_idx].xl_text, font, font_size, items[p_idx].language);
|
||||
const String &lang = items[p_idx].language.is_empty() ? _get_locale() : items[p_idx].language;
|
||||
items.write[p_idx].text_buf->add_string(items.write[p_idx].xl_text, font, font_size, lang);
|
||||
|
||||
items.write[p_idx].accel_text_buf->clear();
|
||||
items.write[p_idx].accel_text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
|
||||
items.write[p_idx].accel_text_buf->add_string(_get_accel_text(items.write[p_idx]), font, font_size);
|
||||
items.write[p_idx].accel_text_buf->add_string(_get_accel_text(items.write[p_idx]), font, font_size, lang);
|
||||
items.write[p_idx].dirty = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,8 @@ void ProgressBar::_notification(int p_what) {
|
|||
String txt = itos(int(ratio * 100));
|
||||
|
||||
if (is_localizing_numeral_system()) {
|
||||
txt = TS->format_number(txt) + TS->percent_sign();
|
||||
const String &lang = _get_locale();
|
||||
txt = TS->format_number(txt, lang) + TS->percent_sign(lang);
|
||||
} else {
|
||||
txt += String("%");
|
||||
}
|
||||
|
|
|
@ -3461,21 +3461,20 @@ TextServer::StructuredTextParser RichTextLabel::_find_stt(Item *p_item) {
|
|||
}
|
||||
|
||||
String RichTextLabel::_find_language(Item *p_item) {
|
||||
Item *item = p_item;
|
||||
|
||||
while (item) {
|
||||
String lang = language;
|
||||
for (Item *item = p_item; item; item = item->parent) {
|
||||
if (item->type == ITEM_LANGUAGE) {
|
||||
ItemLanguage *p = static_cast<ItemLanguage *>(item);
|
||||
return p->language;
|
||||
} else if (item->type == ITEM_PARAGRAPH) {
|
||||
ItemParagraph *p = static_cast<ItemParagraph *>(item);
|
||||
return p->language;
|
||||
lang = p->language;
|
||||
break;
|
||||
}
|
||||
if (item->type == ITEM_PARAGRAPH) {
|
||||
ItemParagraph *p = static_cast<ItemParagraph *>(item);
|
||||
lang = p->language;
|
||||
break;
|
||||
}
|
||||
|
||||
item = item->parent;
|
||||
}
|
||||
|
||||
return language;
|
||||
return lang.is_empty() ? _get_locale() : lang;
|
||||
}
|
||||
|
||||
Color RichTextLabel::_find_color(Item *p_item, const Color &p_default_color) {
|
||||
|
|
|
@ -88,7 +88,7 @@ void SpinBox::_update_text(bool p_only_update_if_value_changed) {
|
|||
double step = get_step();
|
||||
String value = String::num(get_value(), Math::range_step_decimals(step));
|
||||
if (is_localizing_numeral_system()) {
|
||||
value = TS->format_number(value);
|
||||
value = TS->format_number(value, _get_locale());
|
||||
}
|
||||
|
||||
if (p_only_update_if_value_changed && value == last_text_value) {
|
||||
|
@ -137,8 +137,9 @@ void SpinBox::_text_submitted(const String &p_string) {
|
|||
Ref<Expression> expr;
|
||||
expr.instantiate();
|
||||
|
||||
const String &lang = _get_locale();
|
||||
text = text.replace_char(';', ',');
|
||||
text = TS->parse_number(text);
|
||||
text = TS->parse_number(text, lang);
|
||||
// Ignore the prefix and suffix in the expression.
|
||||
text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix);
|
||||
|
||||
|
@ -147,7 +148,7 @@ void SpinBox::_text_submitted(const String &p_string) {
|
|||
if (err != OK) {
|
||||
// If the expression failed try without converting commas to dots - they might have been for parameter separation.
|
||||
text = p_string;
|
||||
text = TS->parse_number(text);
|
||||
text = TS->parse_number(text, lang);
|
||||
text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix);
|
||||
|
||||
err = expr->parse(text);
|
||||
|
|
|
@ -363,7 +363,8 @@ void TabBar::_shape(int p_tab) {
|
|||
tabs.write[p_tab].text_buf->set_direction((TextServer::Direction)tabs[p_tab].text_direction);
|
||||
}
|
||||
|
||||
tabs.write[p_tab].text_buf->add_string(atr(tabs[p_tab].text), theme_cache.font, theme_cache.font_size, tabs[p_tab].language);
|
||||
const String &lang = tabs[p_tab].language.is_empty() ? _get_locale() : tabs[p_tab].language;
|
||||
tabs.write[p_tab].text_buf->add_string(atr(tabs[p_tab].text), theme_cache.font, theme_cache.font_size, lang);
|
||||
}
|
||||
|
||||
RID TabBar::get_tab_accessibility_element(int p_tab) const {
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "core/os/os.h"
|
||||
#include "core/string/alt_codes.h"
|
||||
#include "core/string/string_builder.h"
|
||||
#include "core/string/translation_server.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/main/window.h"
|
||||
#include "scene/theme/theme_db.h"
|
||||
|
@ -863,7 +862,7 @@ void TextEdit::_notification(int p_what) {
|
|||
case NOTIFICATION_TRANSLATION_CHANGED:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
if (is_inside_tree()) {
|
||||
_update_caches();
|
||||
_update_caches(p_what == NOTIFICATION_TRANSLATION_CHANGED);
|
||||
_update_wrap_at_column(true);
|
||||
}
|
||||
} break;
|
||||
|
@ -1435,7 +1434,7 @@ void TextEdit::_notification(int p_what) {
|
|||
|
||||
Ref<TextLine> tl;
|
||||
tl.instantiate();
|
||||
tl->add_string(txt, theme_cache.font, theme_cache.font_size);
|
||||
tl->add_string(txt, theme_cache.font, theme_cache.font_size, _get_locale());
|
||||
|
||||
int yofs = ofs_y + (row_height - tl->get_size().y) / 2;
|
||||
if (theme_cache.outline_size > 0 && theme_cache.outline_color.a > 0) {
|
||||
|
@ -3356,7 +3355,8 @@ void TextEdit::_update_placeholder() {
|
|||
placeholder_data_buf->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
placeholder_data_buf->set_preserve_control(draw_control_chars);
|
||||
placeholder_data_buf->add_string(placeholder_translated, theme_cache.font, theme_cache.font_size, language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
placeholder_data_buf->add_string(placeholder_translated, theme_cache.font, theme_cache.font_size, lang);
|
||||
|
||||
placeholder_bidi_override = structured_text_parser(st_parser, st_args, placeholder_translated);
|
||||
if (placeholder_bidi_override.is_empty()) {
|
||||
|
@ -3402,7 +3402,7 @@ void TextEdit::_update_theme_item_cache() {
|
|||
}
|
||||
}
|
||||
|
||||
void TextEdit::_update_caches() {
|
||||
void TextEdit::_update_caches(bool p_invalidate_all) {
|
||||
/* Text properties. */
|
||||
TextServer::Direction dir;
|
||||
if (text_direction == Control::TEXT_DIRECTION_INHERITED) {
|
||||
|
@ -3410,11 +3410,16 @@ void TextEdit::_update_caches() {
|
|||
} else {
|
||||
dir = (TextServer::Direction)text_direction;
|
||||
}
|
||||
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
text.set_direction_and_language(dir, lang);
|
||||
text.set_draw_control_chars(draw_control_chars);
|
||||
text.set_font(theme_cache.font);
|
||||
text.set_font_size(theme_cache.font_size);
|
||||
text.invalidate_font();
|
||||
if (p_invalidate_all) {
|
||||
text.invalidate_all();
|
||||
} else {
|
||||
text.invalidate_font();
|
||||
}
|
||||
_update_placeholder();
|
||||
|
||||
/* Syntax highlighting. */
|
||||
|
@ -3741,8 +3746,9 @@ void TextEdit::set_text_direction(Control::TextDirection p_text_direction) {
|
|||
} else {
|
||||
dir = (TextServer::Direction)text_direction;
|
||||
}
|
||||
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
text.invalidate_font();
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
text.set_direction_and_language(dir, lang);
|
||||
text.invalidate_all();
|
||||
_update_placeholder();
|
||||
|
||||
if (menu_dir) {
|
||||
|
@ -3769,7 +3775,8 @@ void TextEdit::set_language(const String &p_language) {
|
|||
} else {
|
||||
dir = (TextServer::Direction)text_direction;
|
||||
}
|
||||
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
text.set_direction_and_language(dir, lang);
|
||||
text.invalidate_all();
|
||||
_update_placeholder();
|
||||
queue_accessibility_update();
|
||||
|
|
|
@ -333,7 +333,7 @@ private:
|
|||
Array st_args;
|
||||
|
||||
void _clear();
|
||||
void _update_caches();
|
||||
void _update_caches(bool p_invalidate_all = false);
|
||||
|
||||
void _close_ime_window();
|
||||
void _update_ime_window_position();
|
||||
|
|
|
@ -2131,7 +2131,8 @@ void Tree::update_column(int p_col) {
|
|||
}
|
||||
|
||||
columns.write[p_col].xl_title = atr(columns[p_col].title);
|
||||
columns.write[p_col].text_buf->add_string(columns[p_col].xl_title, theme_cache.tb_font, theme_cache.tb_font_size, columns[p_col].language);
|
||||
const String &lang = columns[p_col].language.is_empty() ? _get_locale() : columns[p_col].language;
|
||||
columns.write[p_col].text_buf->add_string(columns[p_col].xl_title, theme_cache.tb_font, theme_cache.tb_font_size, lang);
|
||||
columns.write[p_col].cached_minimum_width_dirty = true;
|
||||
}
|
||||
|
||||
|
@ -2200,7 +2201,8 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) const {
|
|||
} else {
|
||||
font_size = theme_cache.font_size;
|
||||
}
|
||||
p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].language);
|
||||
const String &lang = p_item->cells[p_col].language.is_empty() ? _get_locale() : p_item->cells[p_col].language;
|
||||
p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, lang);
|
||||
|
||||
BitField<TextServer::LineBreakFlag> break_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_TRIM_START_EDGE_SPACES | TextServer::BREAK_TRIM_END_EDGE_SPACES;
|
||||
switch (p_item->cells.write[p_col].autowrap_mode) {
|
||||
|
|
|
@ -2779,27 +2779,6 @@ void Node::get_storable_properties(HashSet<StringName> &r_storable_properties) c
|
|||
}
|
||||
}
|
||||
|
||||
String Node::to_string() {
|
||||
// Keep this method in sync with `Object::to_string`.
|
||||
ERR_THREAD_GUARD_V(String());
|
||||
if (get_script_instance()) {
|
||||
bool valid;
|
||||
String ret = get_script_instance()->to_string(&valid);
|
||||
if (valid) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (_get_extension() && _get_extension()->to_string) {
|
||||
String ret;
|
||||
GDExtensionBool is_valid;
|
||||
_get_extension()->to_string(_get_extension_instance(), &is_valid, &ret);
|
||||
if (is_valid) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return (get_name() ? String(get_name()) + ":" : "") + Object::to_string();
|
||||
}
|
||||
|
||||
void Node::set_scene_instance_state(const Ref<SceneState> &p_state) {
|
||||
ERR_THREAD_GUARD
|
||||
data.instance_state = p_state;
|
||||
|
@ -3615,6 +3594,11 @@ void Node::_validate_property(PropertyInfo &p_property) const {
|
|||
}
|
||||
}
|
||||
|
||||
String Node::_to_string() {
|
||||
ERR_THREAD_GUARD_V(String());
|
||||
return (get_name() ? String(get_name()) + ":" : "") + Object::_to_string();
|
||||
}
|
||||
|
||||
void Node::input(const Ref<InputEvent> &p_event) {
|
||||
}
|
||||
|
||||
|
|
|
@ -407,6 +407,7 @@ protected:
|
|||
void _call_unhandled_key_input(const Ref<InputEvent> &p_event);
|
||||
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
virtual String _to_string() override;
|
||||
|
||||
Variant _get_node_rpc_config_bind() const {
|
||||
return get_node_rpc_config().duplicate(true);
|
||||
|
@ -631,8 +632,6 @@ public:
|
|||
#endif
|
||||
void get_storable_properties(HashSet<StringName> &r_storable_properties) const;
|
||||
|
||||
virtual String to_string() override;
|
||||
|
||||
/* NOTIFICATIONS */
|
||||
|
||||
void propagate_notification(int p_notification);
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/debugger/engine_debugger.h"
|
||||
#include "core/string/translation_server.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/theme/theme_db.h"
|
||||
#include "scene/theme/theme_owner.h"
|
||||
|
@ -2934,12 +2933,9 @@ bool Window::is_layout_rtl() const {
|
|||
} else if (proj_root_layout_direction == 2) {
|
||||
return true;
|
||||
} else if (proj_root_layout_direction == 3) {
|
||||
String locale = OS::get_singleton()->get_locale();
|
||||
return TS->is_locale_right_to_left(locale);
|
||||
return TS->is_locale_right_to_left(OS::get_singleton()->get_locale());
|
||||
} else {
|
||||
const Ref<Translation> &t = TranslationServer::get_singleton()->get_translation_object(TranslationServer::get_singleton()->get_locale());
|
||||
String locale = t.is_valid() ? t->get_locale() : TranslationServer::get_singleton()->get_fallback_locale();
|
||||
return TS->is_locale_right_to_left(locale);
|
||||
return TS->is_locale_right_to_left(_get_locale());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2948,8 +2944,9 @@ bool Window::is_layout_rtl() const {
|
|||
return true;
|
||||
}
|
||||
#endif
|
||||
const StringName domain_name = get_translation_domain();
|
||||
Node *parent_node = get_parent();
|
||||
while (parent_node) {
|
||||
while (parent_node && parent_node->get_translation_domain() == domain_name) {
|
||||
Control *parent_control = Object::cast_to<Control>(parent_node);
|
||||
if (parent_control) {
|
||||
return parent_control->is_layout_rtl();
|
||||
|
@ -2967,25 +2964,21 @@ bool Window::is_layout_rtl() const {
|
|||
} else if (root_layout_direction == 2) {
|
||||
return true;
|
||||
} else if (root_layout_direction == 3) {
|
||||
String locale = OS::get_singleton()->get_locale();
|
||||
return TS->is_locale_right_to_left(locale);
|
||||
return TS->is_locale_right_to_left(OS::get_singleton()->get_locale());
|
||||
} else {
|
||||
String locale = TranslationServer::get_singleton()->get_tool_locale();
|
||||
return TS->is_locale_right_to_left(locale);
|
||||
return TS->is_locale_right_to_left(_get_locale());
|
||||
}
|
||||
} else if (layout_dir == LAYOUT_DIRECTION_APPLICATION_LOCALE) {
|
||||
if (GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
|
||||
return true;
|
||||
} else {
|
||||
String locale = TranslationServer::get_singleton()->get_tool_locale();
|
||||
return TS->is_locale_right_to_left(locale);
|
||||
return TS->is_locale_right_to_left(_get_locale());
|
||||
}
|
||||
} else if (layout_dir == LAYOUT_DIRECTION_SYSTEM_LOCALE) {
|
||||
if (GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
|
||||
return true;
|
||||
} else {
|
||||
String locale = OS::get_singleton()->get_locale();
|
||||
return TS->is_locale_right_to_left(locale);
|
||||
return TS->is_locale_right_to_left(OS::get_singleton()->get_locale());
|
||||
}
|
||||
} else {
|
||||
return (layout_dir == LAYOUT_DIRECTION_RTL);
|
||||
|
|
|
@ -3227,8 +3227,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
|
|||
TS->shaped_text_clear(text_rid);
|
||||
TS->shaped_text_set_direction(text_rid, text_direction);
|
||||
|
||||
String txt = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
|
||||
TS->shaped_text_add_string(text_rid, txt, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
const String &lang = language.is_empty() ? _get_locale() : language;
|
||||
String txt = (uppercase) ? TS->string_to_upper(xl_text, lang) : xl_text;
|
||||
TS->shaped_text_add_string(text_rid, txt, font->get_rids(), font_size, font->get_opentype_features(), lang);
|
||||
|
||||
TypedArray<Vector3i> stt;
|
||||
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
|
||||
|
@ -3686,11 +3687,8 @@ void TextMesh::_bind_methods() {
|
|||
void TextMesh::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case MainLoop::NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
String new_text = tr(text);
|
||||
if (new_text == xl_text) {
|
||||
return; // Nothing new.
|
||||
}
|
||||
xl_text = new_text;
|
||||
// Language update might change the appearance of some characters.
|
||||
xl_text = tr(text);
|
||||
dirty_text = true;
|
||||
request_update();
|
||||
} break;
|
||||
|
|
|
@ -6584,11 +6584,14 @@ void RenderingDevice::_stall_for_previous_frames() {
|
|||
}
|
||||
}
|
||||
|
||||
void RenderingDevice::_flush_and_stall_for_all_frames() {
|
||||
void RenderingDevice::_flush_and_stall_for_all_frames(bool p_begin_frame) {
|
||||
_stall_for_previous_frames();
|
||||
_end_frame();
|
||||
_execute_frame(false);
|
||||
_begin_frame();
|
||||
|
||||
if (p_begin_frame) {
|
||||
_begin_frame();
|
||||
}
|
||||
}
|
||||
|
||||
Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServer::WindowID p_main_window) {
|
||||
|
@ -7086,7 +7089,7 @@ void RenderingDevice::finalize() {
|
|||
|
||||
if (!frames.is_empty()) {
|
||||
// Wait for all frames to have finished rendering.
|
||||
_flush_and_stall_for_all_frames();
|
||||
_flush_and_stall_for_all_frames(false);
|
||||
}
|
||||
|
||||
// Wait for transfer workers to finish.
|
||||
|
|
|
@ -1587,7 +1587,7 @@ public:
|
|||
void _execute_frame(bool p_present);
|
||||
void _stall_for_frame(uint32_t p_frame);
|
||||
void _stall_for_previous_frames();
|
||||
void _flush_and_stall_for_all_frames();
|
||||
void _flush_and_stall_for_all_frames(bool p_begin_frame = true);
|
||||
|
||||
template <typename T>
|
||||
void _free_rids(T &p_owner, const char *p_type);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue