Compare commits

...

34 commits

Author SHA1 Message Date
Thaddeus Crews
fc7065d2b4
Merge pull request #111487 from AThousandShips/fix_2d_build_2
Fix 2D builds (again)
2025-10-13 12:30:16 -05:00
Thaddeus Crews
599fd7344a
Merge pull request #111356 from blueskythlikesclouds/d3d12-spec-constant-patch-fix
Fix specialization constant patching on D3D12.
2025-10-13 12:30:15 -05:00
Thaddeus Crews
31f9ed087e
Merge pull request #110650 from WhalesState/node-cache-less-dirty
Optimize children cache updates and refine special-case handling
2025-10-13 12:30:14 -05:00
Thaddeus Crews
c9b72fcfb6
Merge pull request #111481 from Ivorforce/texture-less-includes
Remove extraneous includes from `texture.h`.
2025-10-13 12:30:13 -05:00
Thaddeus Crews
bb4d0638c4
Merge pull request #109816 from SatLess/ArraysArePeopleToo
Add `Make_Unique_Recursive` option for `Resources` with `Arrays` and `Dictionaries`
2025-10-13 12:30:11 -05:00
Thaddeus Crews
e560ea47d4
Merge pull request #70646 from KoBeWi/relatable_offset
Add `pivot_offset_ratio` property to Control
2025-10-13 12:30:10 -05:00
Thaddeus Crews
094eb99a43
Merge pull request #111601 from AThousandShips/fix_build_objprof
Fix use of outdated macros in ObjectDBProfiler
2025-10-13 12:30:09 -05:00
Thaddeus Crews
10c333a8f1
Merge pull request #111313 from bruvzg/emb_res
Fix editor embedded windows partially resizing.
2025-10-13 12:30:08 -05:00
Thaddeus Crews
dc05e0f907
Merge pull request #111596 from kb173/fix-vr-visible-layers
Fix `CAMERA_VISIBLE_LAYERS` in multiview camera (VR) not aligning with the camera's cull mask
2025-10-13 12:30:06 -05:00
Thaddeus Crews
43438fec2a
Merge pull request #111529 from wagnerfs/fix-windows-native-filedialog-filters
Fix Windows native FileDialog filters not showing descriptions
2025-10-13 12:30:05 -05:00
Thaddeus Crews
1274facd44
Merge pull request #111434 from ChristophHaag/initialize_XrRenderModelPropertiesEXT_type
Ensure `XrRenderModelPropertiesEXT::type` is initialized
2025-10-13 12:30:04 -05:00
Thaddeus Crews
2b1fa0f10c
Merge pull request #111111 from bruvzg/outl_warn
[Label] Add MSDF pixel range/outline configuration warning.
2025-10-13 12:30:03 -05:00
Thaddeus Crews
dcb9a0d030
Merge pull request #110151 from FifthTundraG/tabbar_horizontal_scrolling
Add horizontal scrolling to `TabBar`
2025-10-13 12:30:02 -05:00
Thaddeus Crews
08c200e82f
Merge pull request #111527 from DenisCiammaricone/fix-inline-object-parse
Fix editor inline color display of color from `Color.from_rgba8`
2025-10-13 12:30:00 -05:00
Thaddeus Crews
5e7f7735a4
Merge pull request #86468 from KoBeWi/always_has_been
Move script name to top
2025-10-13 12:29:59 -05:00
Thaddeus Crews
02f48683b5
Merge pull request #111556 from kleonc/fix_show_members_overview_editor_setting_tooltip
Fix `text_editor/script_list/show_members_overview` editor setting docs/tooltip
2025-10-13 12:29:58 -05:00
Thaddeus Crews
0450686035
Merge pull request #111460 from KoBeWi/dialoging_shortcut_files
Rework FileDialog shortcuts
2025-10-13 12:29:57 -05:00
Denis Ciammaricone
7e2f6c3ebc Fix editor inline color display of color from Color.from_rgba8 2025-10-13 19:12:17 +02:00
FifthTundraG
14f7cbd74c Add horizontal scrolling to TabBar 2025-10-13 13:05:25 -04:00
Karl Office
7a49918c89 fix: set visible layers in multiview camera 2025-10-13 17:31:01 +02:00
A Thousand Ships
ac05ce5226
Fix use of outdated macros in ObjectDBProfiler
These were renamed but were missed in this PR and fails with disable
deprecated.
2025-10-13 17:25:45 +02:00
Sat
12ced6c83b Add support for making arrays and dictionaries with Resources unique 2025-10-12 23:11:09 -03:00
Wagner
f835707f7a Fix Windows native FileDialog filters not showing descriptions 2025-10-12 16:22:45 -03:00
kleonc
5ea0b9d60d Fix show_members_overview editor setting docs/tooltip 2025-10-12 15:03:03 +02:00
kobewi
206d4a0fb3 Move script name to top 2025-10-12 14:10:44 +02:00
kobewi
263a2bdec6 Rework FileDialog shortcuts 2025-10-11 14:37:40 +02:00
A Thousand Ships
a872b54a3b
Fix 2D builds (again) 2025-10-10 20:44:50 +02:00
Lukas Tenbrink
985e6178b4 Remove extraneous includes from texture.h. 2025-10-10 18:39:16 +02:00
Christoph Haag
e33e069508 initialize XrRenderModelPropertiesEXT 2025-10-09 18:45:13 +02:00
Skyth
36b7e77f03 Fix specialization constant patching on D3D12. 2025-10-08 09:37:35 +03:00
Pāvels Nadtočajevs
0d056cf294
Fix editor embedded windows partially resizing. 2025-10-06 09:12:20 +03:00
Pāvels Nadtočajevs
61003f18ab
[Label] Add MSDF pixel range/outline configuration warning. 2025-10-01 12:31:08 +03:00
kobewi
618afcffa6 Add pivot_offset_ratio property to Control 2025-09-30 15:27:52 +02:00
Mounir Tohami
3335708ce0 Refine children cache invalidation to skip more special cases. 2025-09-18 18:28:59 +03:00
65 changed files with 438 additions and 182 deletions

View file

@ -403,9 +403,12 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = {
{ "ui_graph_delete", TTRC("Delete Nodes") },
{ "ui_graph_follow_left", TTRC("Follow Input Port Connection") },
{ "ui_graph_follow_right", TTRC("Follow Output Port Connection") },
{ "ui_filedialog_delete", TTRC("Delete") },
{ "ui_filedialog_up_one_level", TTRC("Go Up One Level") },
{ "ui_filedialog_refresh", TTRC("Refresh") },
{ "ui_filedialog_show_hidden", TTRC("Show Hidden") },
{ "ui_filedialog_find", TTRC("Find") },
{ "ui_filedialog_focus_path", TTRC("Focus Path") },
{ "ui_swap_input_direction ", TTRC("Swap Input Direction") },
{ "ui_unicode_start", TTRC("Start Unicode Character Input") },
{ "ui_colorpicker_delete_preset", TTRC("ColorPicker: Delete Preset") },
@ -804,6 +807,10 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
default_builtin_cache.insert("ui_graph_follow_right.macos", inputs);
// ///// UI File Dialog Shortcuts /////
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE));
default_builtin_cache.insert("ui_filedialog_delete", inputs);
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE));
default_builtin_cache.insert("ui_filedialog_up_one_level", inputs);
@ -816,6 +823,22 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
inputs.push_back(InputEventKey::create_reference(Key::H));
default_builtin_cache.insert("ui_filedialog_show_hidden", inputs);
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::F | KeyModifierMask::CMD_OR_CTRL));
default_builtin_cache.insert("ui_filedialog_find", inputs);
inputs = List<Ref<InputEvent>>();
// Ctrl + L (matches most Windows/Linux file managers' "focus on path bar" shortcut,
// plus macOS Safari's "focus on address bar" shortcut).
inputs.push_back(InputEventKey::create_reference(Key::L | KeyModifierMask::CMD_OR_CTRL));
default_builtin_cache.insert("ui_filedialog_focus_path", inputs);
inputs = List<Ref<InputEvent>>();
// Cmd + Shift + G (matches Finder's "Go To" shortcut).
inputs.push_back(InputEventKey::create_reference(Key::G | KeyModifierMask::CMD_OR_CTRL));
inputs.push_back(InputEventKey::create_reference(Key::L | KeyModifierMask::CMD_OR_CTRL));
default_builtin_cache.insert("ui_filedialog_focus_path.macos", inputs);
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::QUOTELEFT | KeyModifierMask::CMD_OR_CTRL));
default_builtin_cache.insert("ui_swap_input_direction", inputs);

View file

@ -85,6 +85,17 @@ String Shortcut::get_as_text() const {
return "None";
}
Ref<Shortcut> Shortcut::make_from_action(const StringName &p_action) {
Ref<InputEventAction> event;
event.instantiate();
event->set_action(p_action);
Ref<Shortcut> shortcut;
shortcut.instantiate();
shortcut->set_events({ event });
return shortcut;
}
bool Shortcut::has_valid_event() const {
// Tests if there is ANY input event which is valid.
for (int i = 0; i < events.size(); i++) {

View file

@ -52,5 +52,7 @@ public:
String get_as_text() const;
static Ref<Shortcut> make_from_action(const StringName &p_action);
static bool is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2);
};

View file

@ -409,6 +409,12 @@
Returns combined minimum size from [member custom_minimum_size] and [method get_minimum_size].
</description>
</method>
<method name="get_combined_pivot_offset" qualifiers="const">
<return type="Vector2" />
<description>
Returns the combined value of [member pivot_offset] and [member pivot_offset_ratio], in pixels. The ratio is multiplied by the control's size.
</description>
</method>
<method name="get_cursor_shape" qualifiers="const">
<return type="int" enum="Control.CursorShape" />
<param index="0" name="position" type="Vector2" default="Vector2(0, 0)" />
@ -1090,7 +1096,12 @@
</member>
<member name="physics_interpolation_mode" type="int" setter="set_physics_interpolation_mode" getter="get_physics_interpolation_mode" overrides="Node" enum="Node.PhysicsInterpolationMode" default="2" />
<member name="pivot_offset" type="Vector2" setter="set_pivot_offset" getter="get_pivot_offset" default="Vector2(0, 0)">
By default, the node's pivot is its top-left corner. When you change its [member rotation] or [member scale], it will rotate or scale around this pivot. Set this property to [member size] / 2 to pivot around the Control's center.
By default, the node's pivot is its top-left corner. When you change its [member rotation] or [member scale], it will rotate or scale around this pivot.
The actual offset is the combined value of this property and [member pivot_offset_ratio].
</member>
<member name="pivot_offset_ratio" type="Vector2" setter="set_pivot_offset_ratio" getter="get_pivot_offset_ratio" default="Vector2(0, 0)">
Same as [member pivot_offset], but expressed as uniform vector, where [code]Vector2(0, 0)[/code] is the top-left corner of this control, and [code]Vector2(1, 1)[/code] is its bottom-right corner. Set this property to [code]Vector2(0.5, 0.5)[/code] to pivot around this control's center.
The actual offset is the combined value of this property and [member pivot_offset].
</member>
<member name="position" type="Vector2" setter="_set_position" getter="get_position" default="Vector2(0, 0)">
The node's position, relative to its containing node. It corresponds to the rectangle's top-left corner. The property is not affected by [member pivot_offset].

View file

@ -1462,7 +1462,7 @@
How many script names can be highlighted at most, if [member text_editor/script_list/script_temperature_enabled] is [code]true[/code]. Scripts older than this value use the default font color.
</member>
<member name="text_editor/script_list/show_members_overview" type="bool" setter="" getter="">
If [code]true[/code], displays an overview of the current script's member variables and functions at the left of the script editor. See also [member text_editor/script_list/sort_members_outline_alphabetically].
If [code]true[/code], displays an overview of the current script's member functions at the left of the script editor. See also [member text_editor/script_list/sort_members_outline_alphabetically].
</member>
<member name="text_editor/script_list/sort_members_outline_alphabetically" type="bool" setter="" getter="">
If [code]true[/code], sorts the members outline (located at the left of the script editor) using alphabetical order. If [code]false[/code], sorts the members outline depending on the order in which members are found in the script.

View file

@ -1287,6 +1287,21 @@
Default [InputEventAction] to go to the end position of a [Control] (e.g. last item in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_END] on typical desktop UI systems.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
<member name="input/ui_filedialog_delete" type="Dictionary" setter="" getter="">
Default [InputEventAction] to delete the selected file in a [FileDialog].
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
<member name="input/ui_filedialog_find" type="Dictionary" setter="" getter="">
Default [InputEventAction] to open file filter in a [FileDialog].
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
<member name="input/ui_filedialog_focus_path" type="Dictionary" setter="" getter="">
Default [InputEventAction] to focus path edit field in a [FileDialog].
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
<member name="input/ui_filedialog_focus_path.macos" type="Dictionary" setter="" getter="">
macOS specific override for the shortcut to focus path edit field in [FileDialog].
</member>
<member name="input/ui_filedialog_refresh" type="Dictionary" setter="" getter="">
Default [InputEventAction] to refresh the contents of the current directory of a [FileDialog].
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.

View file

@ -94,28 +94,26 @@ uint32_t RenderingDXIL::patch_specialization_constant(
const uint64_t (&p_stages_bit_offsets)[D3D12_BITCODE_OFFSETS_NUM_STAGES],
HashMap<RenderingDeviceCommons::ShaderStage, Vector<uint8_t>> &r_stages_bytecodes,
bool p_is_first_patch) {
uint32_t patch_val = 0;
int64_t patch_val = 0;
switch (p_type) {
case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT: {
uint32_t int_value = *((const int *)p_value);
ERR_FAIL_COND_V(int_value & (1 << 31), 0);
patch_val = int_value;
patch_val = *((const int32_t *)p_value);
} break;
case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL: {
bool bool_value = *((const bool *)p_value);
patch_val = (uint32_t)bool_value;
patch_val = (int32_t)bool_value;
} break;
case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT: {
uint32_t int_value = *((const int *)p_value);
ERR_FAIL_COND_V(int_value & (1 << 31), 0);
patch_val = (int_value >> 1);
patch_val = *((const int32_t *)p_value);
} break;
}
// For VBR encoding to encode the number of bits we expect (32), we need to set the MSB unconditionally.
// However, signed VBR moves the MSB to the LSB, so setting the MSB to 1 wouldn't help. Therefore,
// the bit we set to 1 is the one at index 30.
patch_val |= (1 << 30);
patch_val <<= 1; // What signed VBR does.
// Encode to signed VBR.
if (patch_val >= 0) {
patch_val <<= 1;
} else {
patch_val = ((-patch_val) << 1) | 1;
}
auto tamper_bits = [](uint8_t *p_start, uint64_t p_bit_offset, uint64_t p_tb_value) -> uint64_t {
uint64_t original = 0;
@ -169,13 +167,13 @@ uint32_t RenderingDXIL::patch_specialization_constant(
Vector<uint8_t> &bytecode = r_stages_bytecodes[(RenderingDeviceCommons::ShaderStage)stage];
#ifdef DEV_ENABLED
uint64_t orig_patch_val = tamper_bits(bytecode.ptrw(), offset, patch_val);
uint64_t orig_patch_val = tamper_bits(bytecode.ptrw(), offset, (uint64_t)patch_val);
// Checking against the value the NIR patch should have set.
DEV_ASSERT(!p_is_first_patch || ((orig_patch_val >> 1) & GODOT_NIR_SC_SENTINEL_MAGIC_MASK) == GODOT_NIR_SC_SENTINEL_MAGIC);
uint64_t readback_patch_val = tamper_bits(bytecode.ptrw(), offset, patch_val);
DEV_ASSERT(readback_patch_val == patch_val);
uint64_t readback_patch_val = tamper_bits(bytecode.ptrw(), offset, (uint64_t)patch_val);
DEV_ASSERT(readback_patch_val == (uint64_t)patch_val);
#else
tamper_bits(bytecode.ptrw(), offset, patch_val);
tamper_bits(bytecode.ptrw(), offset, (uint64_t)patch_val);
#endif
stages_patched_mask |= (1 << stage);

View file

@ -53,8 +53,26 @@ static bool _has_sub_resources(const Ref<Resource> &p_res) {
List<PropertyInfo> property_list;
p_res->get_property_list(&property_list);
for (const PropertyInfo &p : property_list) {
Variant value = p_res->get(p.name);
if (p.type == Variant::OBJECT && p.hint == PROPERTY_HINT_RESOURCE_TYPE && !(p.usage & PROPERTY_USAGE_NEVER_DUPLICATE) && p_res->get(p.name).get_validated_object()) {
return true;
} else if (p.type == Variant::ARRAY) {
Array arr = value;
for (Variant &var : arr) {
Ref<Resource> res = var;
if (res.is_valid()) {
return true;
}
}
} else if (p.type == Variant::DICTIONARY) {
Dictionary dict = value;
for (const KeyValue<Variant, Variant> &kv : dict) {
Ref<Resource> resk = kv.key;
Ref<Resource> resv = kv.value;
if (resk.is_valid() || resv.is_valid()) {
return true;
}
}
}
}
return false;
@ -1097,9 +1115,9 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref<Resource> p_
}
if (res_name.is_empty()) {
p_item->set_text(0, p_resource->get_class());
p_item->set_text(0, _get_resource_type(p_resource));
} else {
p_item->set_text(0, vformat("%s (%s)", p_resource->get_class(), res_name));
p_item->set_text(0, vformat("%s (%s)", _get_resource_type(p_resource), res_name));
}
p_item->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_resource.ptr()));
@ -1122,7 +1140,47 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref<Resource> p_
p_resource->get_property_list(&plist);
for (const PropertyInfo &E : plist) {
if (!(E.usage & PROPERTY_USAGE_STORAGE) || E.type != Variant::OBJECT || E.hint != PROPERTY_HINT_RESOURCE_TYPE) {
if (!(E.usage & PROPERTY_USAGE_STORAGE) || (E.type != Variant::OBJECT && E.type != Variant::ARRAY && E.type != Variant::DICTIONARY)) {
continue;
}
Variant value = p_resource->get(E.name);
TreeItem *child = nullptr;
if (E.type == Variant::ARRAY) {
Array arr = value;
for (int i = 0; i < arr.size(); i++) {
Ref<Resource> res = arr[i];
if (res.is_valid()) {
child = p_item->create_child();
_gather_resources_to_duplicate(res, child, E.name);
meta = child->get_metadata(0);
meta.push_back(E.name);
meta.push_back(i); // Remember index.
}
}
continue;
} else if (E.type == Variant::DICTIONARY) {
Dictionary dict = value;
for (const KeyValue<Variant, Variant> &kv : dict) {
Ref<Resource> key_res = kv.key;
Ref<Resource> value_res = kv.value;
if (key_res.is_valid()) {
child = p_item->create_child();
_gather_resources_to_duplicate(key_res, child, E.name);
meta = child->get_metadata(0);
meta.push_back(E.name);
meta.push_back(key_res);
}
if (value_res.is_valid()) {
child = p_item->create_child();
_gather_resources_to_duplicate(value_res, child, E.name);
meta = child->get_metadata(0);
meta.push_back(E.name);
meta.push_back(value_res);
meta.push_back(kv.key);
}
}
continue;
}
@ -1130,13 +1188,11 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref<Resource> p_
if (res.is_null()) {
continue;
}
TreeItem *child = p_item->create_child();
child = p_item->create_child();
_gather_resources_to_duplicate(res, child, E.name);
meta = child->get_metadata(0);
// Remember property name.
meta.append(E.name);
meta.push_back(E.name);
if ((E.usage & PROPERTY_USAGE_NEVER_DUPLICATE)) {
// The resource can't be duplicated, but make it appear on the list anyway.
@ -1161,10 +1217,47 @@ void EditorResourcePicker::_duplicate_selected_resources() {
if (meta.size() == 1) { // Root.
edited_resource = unique_resource;
_resource_changed();
} else {
Array parent_meta = item->get_parent()->get_metadata(0);
Ref<Resource> parent = parent_meta[0];
continue;
}
Array parent_meta = item->get_parent()->get_metadata(0);
Ref<Resource> parent = parent_meta[0];
Variant::Type property_type = parent->get(meta[1]).get_type();
if (property_type == Variant::OBJECT) {
parent->set(meta[1], unique_resource);
continue;
}
Variant property = parent->get(meta[1]);
if (!parent_meta.has(property)) {
property = property.duplicate();
parent->set(meta[1], property);
parent_meta.push_back(property); // Append Duplicated Type so we can check if it's already been duplicated.
}
if (property_type == Variant::ARRAY) {
Array arr = property;
arr[meta[2]] = unique_resource;
continue;
}
Dictionary dict = property;
LocalVector<Variant> keys = dict.get_key_list();
if (meta[2].get_type() == Variant::OBJECT) {
if (keys.has(meta[2])) {
//It's a key.
dict[unique_resource] = dict[meta[2]];
dict.erase(meta[2]);
parent_meta.push_back(unique_resource);
} else {
// If key has been erased, use last appended Resource key instead.
Variant key = keys.has(meta[3]) ? meta[3] : parent_meta.back();
dict[key] = unique_resource;
}
} else {
dict[meta[2]] = unique_resource;
}
}
}

View file

@ -37,6 +37,7 @@
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/spin_box.h"
#include "scene/resources/gradient.h"
#include "scene/resources/immediate_mesh.h"
class AcceptDialog;

View file

@ -4205,17 +4205,18 @@ void CanvasItemEditor::_notification(int p_what) {
Control *control = Object::cast_to<Control>(ci);
if (control) {
real_t anchors[4];
Vector2 pivot;
Vector2 pivot = control->get_pivot_offset();
Vector2 pivot_ratio = control->get_pivot_offset_ratio();
pivot = control->get_pivot_offset();
real_t anchors[4];
anchors[SIDE_LEFT] = control->get_anchor(SIDE_LEFT);
anchors[SIDE_RIGHT] = control->get_anchor(SIDE_RIGHT);
anchors[SIDE_TOP] = control->get_anchor(SIDE_TOP);
anchors[SIDE_BOTTOM] = control->get_anchor(SIDE_BOTTOM);
if (pivot != se->prev_pivot || anchors[SIDE_LEFT] != se->prev_anchors[SIDE_LEFT] || anchors[SIDE_RIGHT] != se->prev_anchors[SIDE_RIGHT] || anchors[SIDE_TOP] != se->prev_anchors[SIDE_TOP] || anchors[SIDE_BOTTOM] != se->prev_anchors[SIDE_BOTTOM]) {
if (pivot != se->prev_pivot || pivot_ratio != se->prev_pivot_ratio || anchors[SIDE_LEFT] != se->prev_anchors[SIDE_LEFT] || anchors[SIDE_RIGHT] != se->prev_anchors[SIDE_RIGHT] || anchors[SIDE_TOP] != se->prev_anchors[SIDE_TOP] || anchors[SIDE_BOTTOM] != se->prev_anchors[SIDE_BOTTOM]) {
se->prev_pivot = pivot;
se->prev_pivot_ratio = pivot_ratio;
se->prev_anchors[SIDE_LEFT] = anchors[SIDE_LEFT];
se->prev_anchors[SIDE_RIGHT] = anchors[SIDE_RIGHT];
se->prev_anchors[SIDE_TOP] = anchors[SIDE_TOP];

View file

@ -58,6 +58,7 @@ public:
Transform2D prev_xform;
Rect2 prev_rect;
Vector2 prev_pivot;
Vector2 prev_pivot_ratio;
real_t prev_anchors[4] = { (real_t)0.0 };
Transform2D pre_drag_xform;

View file

@ -32,6 +32,7 @@
#include "editor/inspector/editor_inspector.h"
#include "editor/plugins/editor_plugin.h"
#include "scene/resources/gradient.h"
class EditorSpinSlider;
class ColorPicker;

View file

@ -736,25 +736,26 @@ void ScriptEditor::_go_to_tab(int p_idx) {
c = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(c)) {
script_name_label->set_text(Object::cast_to<ScriptEditorBase>(c)->get_name());
script_icon->set_texture(Object::cast_to<ScriptEditorBase>(c)->get_theme_icon());
ScriptEditorBase *seb = Object::cast_to<ScriptEditorBase>(c);
if (seb) {
if (is_visible_in_tree()) {
Object::cast_to<ScriptEditorBase>(c)->ensure_focus();
seb->ensure_focus();
}
Ref<Script> scr = Object::cast_to<ScriptEditorBase>(c)->get_edited_resource();
Ref<Script> scr = seb->get_edited_resource();
if (scr.is_valid()) {
notify_script_changed(scr);
}
Object::cast_to<ScriptEditorBase>(c)->validate();
seb->validate();
}
if (Object::cast_to<EditorHelp>(c)) {
script_name_label->set_text(Object::cast_to<EditorHelp>(c)->get_class());
script_icon->set_texture(get_editor_theme_icon(SNAME("Help")));
EditorHelp *eh = Object::cast_to<EditorHelp>(c);
if (eh) {
script_name_label->set_text(eh->get_class());
if (is_visible_in_tree()) {
Object::cast_to<EditorHelp>(c)->set_focused();
eh->set_focused();
}
}
@ -934,6 +935,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
} else {
_update_selected_editor_menu();
_update_online_doc();
script_name_label->set_text(String());
}
_update_history_arrows();
@ -1836,8 +1838,6 @@ void ScriptEditor::_notification(int p_what) {
filter_scripts->set_right_icon(get_editor_theme_icon(SNAME("Search")));
filter_methods->set_right_icon(get_editor_theme_icon(SNAME("Search")));
filename->add_theme_style_override(CoreStringName(normal), get_theme_stylebox(CoreStringName(normal), SNAME("LineEdit")));
recent_scripts->reset_size();
if (is_inside_tree()) {
@ -2013,6 +2013,7 @@ void ScriptEditor::_script_selected(int p_idx) {
grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT); //amazing hack, simply amazing
_go_to_tab(script_list->get_item_metadata(p_idx));
script_name_label->set_text(script_list->get_item_text(p_idx));
grab_focus_block = false;
}
@ -2145,11 +2146,6 @@ void ScriptEditor::_update_members_overview() {
members_overview->set_item_metadata(-1, line);
}
}
String path = se->get_edited_resource()->get_path();
bool built_in = !path.is_resource_file();
String name = built_in ? path.get_file() : se->get_name();
filename->set_text(name);
}
void ScriptEditor::_update_help_overview_visibility() {
@ -2171,7 +2167,6 @@ void ScriptEditor::_update_help_overview_visibility() {
filter_methods->set_visible(false);
help_overview->set_visible(true);
overview_vbox->set_visible(true);
filename->set_text(se->get_name());
} else {
help_overview->set_visible(false);
overview_vbox->set_visible(false);
@ -2444,7 +2439,6 @@ void ScriptEditor::_update_script_names() {
script_list->select(index);
script_name_label->set_text(sedata_filtered[i].name);
script_icon->set_texture(sedata_filtered[i].icon);
ScriptEditorBase *se = _get_current_editor();
if (se) {
@ -4271,14 +4265,13 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
buttons_hbox = memnew(HBoxContainer);
overview_vbox->add_child(buttons_hbox);
filename = memnew(Label);
filename->set_focus_mode(FOCUS_ACCESSIBILITY);
filename->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
filename->set_clip_text(true);
filename->set_h_size_flags(SIZE_EXPAND_FILL);
filename->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
filename->add_theme_style_override(CoreStringName(normal), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(CoreStringName(normal), SNAME("LineEdit")));
buttons_hbox->add_child(filename);
filter_methods = memnew(LineEdit);
filter_methods->set_placeholder(TTRC("Filter Methods"));
filter_methods->set_accessibility_name(TTRC("Filter Methods"));
filter_methods->set_clear_button_enabled(true);
filter_methods->set_h_size_flags(SIZE_EXPAND_FILL);
filter_methods->connect(SceneStringName(text_changed), callable_mp(this, &ScriptEditor::_filter_methods_text_changed));
buttons_hbox->add_child(filter_methods);
members_overview_alphabeta_sort_button = memnew(Button);
members_overview_alphabeta_sort_button->set_theme_type_variation(SceneStringName(FlatButton));
@ -4286,16 +4279,8 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
members_overview_alphabeta_sort_button->set_toggle_mode(true);
members_overview_alphabeta_sort_button->set_pressed(EDITOR_GET("text_editor/script_list/sort_members_outline_alphabetically"));
members_overview_alphabeta_sort_button->connect(SceneStringName(toggled), callable_mp(this, &ScriptEditor::_toggle_members_overview_alpha_sort));
buttons_hbox->add_child(members_overview_alphabeta_sort_button);
filter_methods = memnew(LineEdit);
filter_methods->set_placeholder(TTRC("Filter Methods"));
filter_methods->set_accessibility_name(TTRC("Filter Methods"));
filter_methods->set_clear_button_enabled(true);
filter_methods->connect(SceneStringName(text_changed), callable_mp(this, &ScriptEditor::_filter_methods_text_changed));
overview_vbox->add_child(filter_methods);
members_overview = memnew(ItemList);
members_overview->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
members_overview->set_theme_type_variation("ItemListSecondary");
@ -4431,19 +4416,13 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
debugger->connect("breakpoint_set_in_tree", callable_mp(this, &ScriptEditor::_set_breakpoint));
debugger->connect("breakpoints_cleared_in_tree", callable_mp(this, &ScriptEditor::_clear_breakpoints));
menu_hb->add_spacer();
script_icon = memnew(TextureRect);
menu_hb->add_child(script_icon);
script_name_label = memnew(Label);
script_name_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
script_name_label->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
script_name_label->set_focus_mode(FOCUS_ACCESSIBILITY);
script_name_label->set_h_size_flags(SIZE_EXPAND_FILL);
menu_hb->add_child(script_name_label);
script_icon->hide();
script_name_label->hide();
menu_hb->add_spacer();
site_search = memnew(Button);
site_search->set_theme_type_variation(SceneStringName(FlatButton));
site_search->set_accessibility_name(TTRC("Site Search"));

View file

@ -346,7 +346,6 @@ class ScriptEditor : public PanelContainer {
VBoxContainer *scripts_vbox = nullptr;
VBoxContainer *overview_vbox = nullptr;
HBoxContainer *buttons_hbox = nullptr;
Label *filename = nullptr;
Button *members_overview_alphabeta_sort_button = nullptr;
bool members_overview_enabled;
ItemList *help_overview = nullptr;
@ -362,7 +361,6 @@ class ScriptEditor : public PanelContainer {
float zoom_factor = 1.0f;
TextureRect *script_icon = nullptr;
Label *script_name_label = nullptr;
Button *script_back = nullptr;

View file

@ -490,7 +490,11 @@ Array ScriptTextEditor::_inline_object_parse(const String &p_text) {
params.push_back(s_param.to_float());
}
if (valid_floats && params.size() == 3) {
params.push_back(1.0);
if (fn_name == ".from_rgba8") {
params.push_back(255);
} else {
params.push_back(1.0);
}
}
if (valid_floats && params.size() == 4) {
has_added_color = true;

View file

@ -31,6 +31,7 @@
#include "editor_fonts.h"
#include "core/io/dir_access.h"
#include "core/os/os.h"
#include "editor/editor_string_names.h"
#include "editor/settings/editor_settings.h"
#include "editor/themes/builtin_fonts.gen.h"

View file

@ -33,6 +33,7 @@
#include "core/io/file_access.h"
#include "core/io/file_access_memory.h"
#include "scene/resources/image_texture.h"
#include "servers/rendering/rendering_server.h"
#include <ktx.h>
#include <vk_format.h>

View file

@ -32,6 +32,8 @@
#include "noise.h"
#include "servers/rendering/rendering_server.h"
NoiseTexture2D::NoiseTexture2D() {
noise = Ref<Noise>();

View file

@ -33,6 +33,7 @@
#include "noise.h"
#include "core/object/ref_counted.h"
#include "scene/resources/gradient.h"
#include "scene/resources/texture.h"
class NoiseTexture2D : public Texture2D {

View file

@ -32,6 +32,8 @@
#include "noise.h"
#include "servers/rendering/rendering_server.h"
NoiseTexture3D::NoiseTexture3D() {
noise = Ref<Noise>();

View file

@ -33,6 +33,7 @@
#include "noise.h"
#include "core/object/ref_counted.h"
#include "scene/resources/gradient.h"
#include "scene/resources/texture.h"
class NoiseTexture3D : public Texture3D {

View file

@ -168,9 +168,9 @@ Error SnapshotCollector::parse_message(void *p_user, const String &p_msg, const
}
String SnapshotCollector::get_godot_version_string() {
String hash = String(VERSION_HASH);
String hash = String(GODOT_VERSION_HASH);
if (hash.length() != 0) {
hash = " " + vformat("[%s]", hash.left(9));
}
return "v" VERSION_FULL_BUILD + hash;
return "v" GODOT_VERSION_FULL_BUILD + hash;
}

View file

@ -379,7 +379,13 @@ RID OpenXRRenderModelExtension::render_model_create(XrRenderModelIdEXT p_render_
nullptr, // next
};
XrRenderModelPropertiesEXT properties;
XrRenderModelPropertiesEXT properties = {
XR_TYPE_RENDER_MODEL_PROPERTIES_EXT, // type
nullptr, // next
{}, // cacheId
0, // animatableNodeCount
};
result = xrGetRenderModelPropertiesEXT(render_model.xr_render_model, &properties_info, &properties);
if (XR_FAILED(result)) {
ERR_PRINT("OpenXR: Failed to get render model properties [" + OpenXRAPI::get_singleton()->get_error_string(result) + "]");

View file

@ -53,6 +53,7 @@ using namespace godot;
#include "core/object/worker_thread_pool.h"
#include "core/string/translation_server.h"
#include "scene/resources/image_texture.h"
#include "servers/rendering/rendering_server.h"
#include "modules/modules_enabled.gen.h" // For freetype, msdfgen, svg.

View file

@ -54,6 +54,7 @@ using namespace godot;
#include "core/io/file_access.h"
#include "core/string/print_string.h"
#include "core/string/translation_server.h"
#include "servers/rendering/rendering_server.h"
#include "modules/modules_enabled.gen.h" // For freetype, msdfgen, svg.

View file

@ -114,6 +114,8 @@ public:
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
static Vector<String> get_rendering_drivers_func();
void _window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
// MARK: - Events
virtual void process_events() override;

View file

@ -621,6 +621,10 @@ Size2i DisplayServerEmbedded::window_get_min_size(WindowID p_window) const {
}
void DisplayServerEmbedded::window_set_size(const Size2i p_size, WindowID p_window) {
print_line("Embedded window can't be resized.");
}
void DisplayServerEmbedded::_window_set_size(const Size2i p_size, WindowID p_window) {
[CATransaction begin];
[CATransaction setDisableActions:YES];

View file

@ -82,7 +82,7 @@ void EmbeddedDebugger::_init_parse_message_handlers() {
Error EmbeddedDebugger::_msg_window_size(const Array &p_args) {
ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'window_size' message.");
Size2i size = p_args[0];
ds->window_set_size(size);
ds->_window_set_size(size);
return OK;
}

View file

@ -555,7 +555,7 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) {
if (!exts.is_empty()) {
String str = String(";").join(exts);
filter_exts.push_back(str.utf16());
if (tokens.size() == 2) {
if (tokens.size() >= 2) {
filter_names.push_back(tokens[1].strip_edges().utf16());
} else {
filter_names.push_back(str.utf16());

View file

@ -31,6 +31,7 @@
#pragma once
#include "scene/2d/node_2d.h"
#include "scene/resources/gradient.h"
class RandomNumberGenerator;

View file

@ -30,7 +30,8 @@
#pragma once
#include "node_2d.h"
#include "scene/2d/node_2d.h"
#include "scene/resources/gradient.h"
class Line2D : public Node2D {
GDCLASS(Line2D, Node2D);

View file

@ -31,6 +31,7 @@
#pragma once
#include "scene/3d/visual_instance_3d.h"
#include "scene/resources/gradient.h"
class RandomNumberGenerator;

View file

@ -34,6 +34,8 @@
#include "core/debugger/engine_debugger.h"
#include "core/io/dir_access.h"
#include "core/io/marshalls.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/math/math_fieldwise.h"
#include "core/object/script_language.h"
#include "core/os/time.h"

View file

@ -58,6 +58,7 @@ Dictionary Control::_edit_get_state() const {
s["rotation"] = get_rotation();
s["scale"] = get_scale();
s["pivot"] = get_pivot_offset();
s["pivot_ratio"] = get_pivot_offset_ratio();
Array anchors = { get_anchor(SIDE_LEFT), get_anchor(SIDE_TOP), get_anchor(SIDE_RIGHT), get_anchor(SIDE_BOTTOM) };
s["anchors"] = anchors;
@ -74,13 +75,14 @@ Dictionary Control::_edit_get_state() const {
void Control::_edit_set_state(const Dictionary &p_state) {
ERR_FAIL_COND(p_state.is_empty() ||
!p_state.has("rotation") || !p_state.has("scale") ||
!p_state.has("pivot") || !p_state.has("anchors") || !p_state.has("offsets") ||
!p_state.has("pivot") || !p_state.has("pivot_ratio") || !p_state.has("anchors") || !p_state.has("offsets") ||
!p_state.has("layout_mode") || !p_state.has("anchors_layout_preset"));
Dictionary state = p_state;
set_rotation(state["rotation"]);
set_scale(state["scale"]);
set_pivot_offset(state["pivot"]);
set_pivot_offset_ratio(state["pivot_ratio"]);
Array anchors = state["anchors"];
@ -152,10 +154,11 @@ void Control::_edit_set_pivot(const Point2 &p_pivot) {
Vector2 move = Vector2((std::cos(data.rotation) - 1.0) * delta_pivot.x - std::sin(data.rotation) * delta_pivot.y, std::sin(data.rotation) * delta_pivot.x + (std::cos(data.rotation) - 1.0) * delta_pivot.y);
set_position(get_position() + move);
set_pivot_offset(p_pivot);
set_pivot_offset_ratio(Vector2());
}
Point2 Control::_edit_get_pivot() const {
return get_pivot_offset();
return get_combined_pivot_offset();
}
bool Control::_edit_use_pivot() const {
@ -536,7 +539,7 @@ void Control::_validate_property(PropertyInfo &p_property) const {
// If the parent is a container, display only container-related properties.
if (p_property.name.begins_with("anchor_") || p_property.name.begins_with("offset_") || p_property.name.begins_with("grow_") || p_property.name == "anchors_preset") {
p_property.usage ^= PROPERTY_USAGE_DEFAULT;
} else if (p_property.name == "position" || p_property.name == "rotation" || p_property.name == "scale" || p_property.name == "size" || p_property.name == "pivot_offset") {
} else if (p_property.name == "position" || p_property.name == "rotation" || p_property.name == "scale" || p_property.name == "size" || p_property.name == "pivot_offset" || p_property.name == "pivot_offset_ratio") {
p_property.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY;
} else if (Engine::get_singleton()->is_editor_hint() && p_property.name == "layout_mode") {
// Set the layout mode to be disabled with the proper value.
@ -709,8 +712,8 @@ Size2 Control::get_parent_area_size() const {
Transform2D Control::_get_internal_transform() const {
// T(pivot_offset) * R(rotation) * S(scale) * T(-pivot_offset)
Transform2D xform(data.rotation, data.scale, 0.0f, data.pivot_offset);
xform.translate_local(-data.pivot_offset);
Transform2D xform(data.rotation, data.scale, 0.0f, get_combined_pivot_offset());
xform.translate_local(-get_combined_pivot_offset());
return xform;
}
@ -1606,6 +1609,23 @@ real_t Control::get_rotation_degrees() const {
return Math::rad_to_deg(get_rotation());
}
void Control::set_pivot_offset_ratio(const Vector2 &p_ratio) {
ERR_MAIN_THREAD_GUARD;
if (data.pivot_offset_ratio == p_ratio) {
return;
}
data.pivot_offset_ratio = p_ratio;
queue_redraw();
_notify_transform();
queue_accessibility_update();
}
Vector2 Control::get_pivot_offset_ratio() const {
ERR_READ_THREAD_GUARD_V(Vector2());
return data.pivot_offset_ratio;
}
void Control::set_pivot_offset(const Vector2 &p_pivot) {
ERR_MAIN_THREAD_GUARD;
if (data.pivot_offset == p_pivot) {
@ -1623,6 +1643,11 @@ Vector2 Control::get_pivot_offset() const {
return data.pivot_offset;
}
Vector2 Control::get_combined_pivot_offset() const {
ERR_READ_THREAD_GUARD_V(Vector2());
return data.pivot_offset + data.pivot_offset_ratio * get_size();
}
/// Sizes.
void Control::_update_minimum_size() {
@ -3990,6 +4015,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &Control::set_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Control::set_scale);
ClassDB::bind_method(D_METHOD("set_pivot_offset", "pivot_offset"), &Control::set_pivot_offset);
ClassDB::bind_method(D_METHOD("set_pivot_offset_ratio", "ratio"), &Control::set_pivot_offset_ratio);
ClassDB::bind_method(D_METHOD("get_begin"), &Control::get_begin);
ClassDB::bind_method(D_METHOD("get_end"), &Control::get_end);
ClassDB::bind_method(D_METHOD("get_position"), &Control::get_position);
@ -3998,6 +4024,8 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &Control::get_rotation_degrees);
ClassDB::bind_method(D_METHOD("get_scale"), &Control::get_scale);
ClassDB::bind_method(D_METHOD("get_pivot_offset"), &Control::get_pivot_offset);
ClassDB::bind_method(D_METHOD("get_pivot_offset_ratio"), &Control::get_pivot_offset_ratio);
ClassDB::bind_method(D_METHOD("get_combined_pivot_offset"), &Control::get_combined_pivot_offset);
ClassDB::bind_method(D_METHOD("get_custom_minimum_size"), &Control::get_custom_minimum_size);
ClassDB::bind_method(D_METHOD("get_parent_area_size"), &Control::get_parent_area_size);
ClassDB::bind_method(D_METHOD("get_global_position"), &Control::get_global_position);
@ -4224,7 +4252,8 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians_as_degrees"), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pivot_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_pivot_offset", "get_pivot_offset");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pivot_offset", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "set_pivot_offset", "get_pivot_offset");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pivot_offset_ratio"), "set_pivot_offset_ratio", "get_pivot_offset_ratio");
ADD_SUBGROUP("Container Sizing", "size_flags_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill:1,Expand:2,Shrink Center:4,Shrink End:8"), "set_h_size_flags", "get_h_size_flags");

View file

@ -212,6 +212,7 @@ private:
real_t rotation = 0.0;
Vector2 scale = Vector2(1, 1);
Vector2 pivot_offset;
Vector2 pivot_offset_ratio;
Point2 pos_cache;
Size2 size_cache;
@ -535,8 +536,11 @@ public:
void set_rotation_degrees(real_t p_degrees);
real_t get_rotation() const;
real_t get_rotation_degrees() const;
void set_pivot_offset_ratio(const Vector2 &p_ratio);
Vector2 get_pivot_offset_ratio() const;
void set_pivot_offset(const Vector2 &p_pivot);
Vector2 get_pivot_offset() const;
Vector2 get_combined_pivot_offset() const;
void update_minimum_size();

View file

@ -255,8 +255,6 @@ void FileDialog::_notification(int p_what) {
_update_favorite_list();
_update_recent_list();
invalidate(); // Put it here to preview in the editor.
} else {
set_process_shortcut_input(false);
}
} break;
@ -292,65 +290,15 @@ void FileDialog::_notification(int p_what) {
}
void FileDialog::shortcut_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (p_event.is_null() || p_event->is_released() || p_event->is_echo()) {
return;
}
Ref<InputEventKey> k = p_event;
if (k.is_valid() && has_focus()) {
if (k->is_pressed()) {
bool handled = true;
switch (k->get_keycode()) {
case Key::H: {
if (k->is_command_or_control_pressed()) {
set_show_hidden_files(!show_hidden_files);
} else {
handled = false;
}
} break;
case Key::F: {
if (k->is_command_or_control_pressed()) {
show_filename_filter_button->set_pressed(!show_filename_filter_button->is_pressed());
} else {
handled = false;
}
} break;
case Key::F5: {
invalidate();
} break;
case Key::BACKSPACE: {
_dir_submitted("..");
} break;
#ifdef MACOS_ENABLED
// Cmd + Shift + G (matches Finder's "Go To" shortcut).
case Key::G: {
if (k->is_command_or_control_pressed() && k->is_shift_pressed()) {
directory_edit->grab_focus();
directory_edit->select_all();
} else {
handled = false;
}
} break;
#endif
// Ctrl + L (matches most Windows/Linux file managers' "focus on path bar" shortcut,
// plus macOS Safari's "focus on address bar" shortcut).
case Key::L: {
if (k->is_command_or_control_pressed()) {
directory_edit->grab_focus();
directory_edit->select_all();
} else {
handled = false;
}
} break;
default: {
handled = false;
}
}
if (handled) {
set_input_as_handled();
}
for (const KeyValue<ItemMenu, Ref<Shortcut>> &action : action_shortcuts) {
if (action.value->matches_event(p_event)) {
_item_menu_id_pressed(action.key);
set_input_as_handled();
break;
}
}
}
@ -427,8 +375,6 @@ void FileDialog::_post_popup() {
file_list->grab_focus(true);
}
set_process_shortcut_input(true);
// For open dir mode, deselect all items on file dialog open.
if (mode == FILE_MODE_OPEN_DIR) {
deselect_all();
@ -765,6 +711,23 @@ void FileDialog::_item_menu_id_pressed(int p_option) {
}
_push_history();
} break;
case ITEM_MENU_GO_UP: {
_dir_submitted("..");
} break;
case ITEM_MENU_TOGGLE_HIDDEN: {
set_show_hidden_files(!show_hidden_files);
} break;
case ITEM_MENU_FIND: {
show_filename_filter_button->set_pressed(!show_filename_filter_button->is_pressed());
} break;
case ITEM_MENU_FOCUS_PATH: {
directory_edit->grab_focus();
directory_edit->select_all();
} break;
}
}
@ -789,12 +752,14 @@ void FileDialog::_popup_menu(const Vector2 &p_pos, int p_for_item) {
item_menu->add_item(ETR("Copy Path"), ITEM_MENU_COPY_PATH);
if (customization_flags[CUSTOMIZATION_DELETE]) {
item_menu->add_item(ETR("Delete"), ITEM_MENU_DELETE);
item_menu->set_item_shortcut(-1, action_shortcuts[ITEM_MENU_DELETE]);
}
} else {
if (can_create_folders) {
item_menu->add_item(ETR("New Folder..."), ITEM_MENU_NEW_FOLDER);
}
item_menu->add_item(ETR("Refresh"), ITEM_MENU_REFRESH);
item_menu->set_item_shortcut(-1, action_shortcuts[ITEM_MENU_REFRESH]);
}
#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
@ -1162,13 +1127,13 @@ void FileDialog::update_filters() {
}
String native_all_name;
native_all_name += all_filters;
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE_MIME)) {
native_all_name += all_filters;
if (!native_all_name.is_empty()) {
native_all_name += ", ";
}
native_all_name += all_mime;
}
if (!native_all_name.is_empty()) {
native_all_name += ", ";
}
native_all_name += all_mime;
if (max_filters < filters.size()) {
all_filters += ", ...";
@ -1183,13 +1148,14 @@ void FileDialog::update_filters() {
String desc = filters[i].get_slicec(';', 1).strip_edges();
String mime = filters[i].get_slicec(';', 2).strip_edges();
String native_name;
native_name += flt;
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE_MIME)) {
native_name += flt;
if (!native_name.is_empty() && !mime.is_empty()) {
native_name += ", ";
}
native_name += mime;
}
if (!native_name.is_empty() && !mime.is_empty()) {
native_name += ", ";
}
native_name += mime;
if (!desc.is_empty()) {
filter->add_item(atr(desc) + " (" + flt + ")");
processed_filters.push_back(flt + ";" + atr(desc) + " (" + native_name + ");" + mime);
@ -2259,12 +2225,20 @@ FileDialog::FileDialog() {
set_hide_on_ok(false);
set_size(Size2(640, 360));
set_default_ok_text(ETR("Save")); // Default mode text.
set_process_shortcut_input(true);
thumbnail_callback = callable_mp(this, &FileDialog::_thumbnail_callback);
for (int i = 0; i < CUSTOMIZATION_MAX; i++) {
customization_flags[i] = true;
}
action_shortcuts[ITEM_MENU_DELETE] = Shortcut::make_from_action("ui_filedialog_delete");
action_shortcuts[ITEM_MENU_GO_UP] = Shortcut::make_from_action("ui_filedialog_up_one_level");
action_shortcuts[ITEM_MENU_REFRESH] = Shortcut::make_from_action("ui_filedialog_refresh");
action_shortcuts[ITEM_MENU_TOGGLE_HIDDEN] = Shortcut::make_from_action("ui_filedialog_show_hidden");
action_shortcuts[ITEM_MENU_FIND] = Shortcut::make_from_action("ui_filedialog_find");
action_shortcuts[ITEM_MENU_FOCUS_PATH] = Shortcut::make_from_action("ui_filedialog_focus_path");
show_hidden_files = default_show_hidden_files;
display_mode = default_display_mode;
dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
@ -2290,6 +2264,7 @@ FileDialog::FileDialog() {
dir_up = memnew(Button);
dir_up->set_theme_type_variation(SceneStringName(FlatButton));
dir_up->set_tooltip_text(ETR("Go to parent folder."));
dir_up->set_shortcut(action_shortcuts[ITEM_MENU_GO_UP]);
top_toolbar->add_child(dir_up);
dir_up->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_go_up));
@ -2319,6 +2294,7 @@ FileDialog::FileDialog() {
refresh_button = memnew(Button);
refresh_button->set_theme_type_variation(SceneStringName(FlatButton));
refresh_button->set_tooltip_text(ETR("Refresh files."));
refresh_button->set_shortcut(action_shortcuts[ITEM_MENU_REFRESH]);
top_toolbar->add_child(refresh_button);
refresh_button->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::update_file_list));
@ -2414,6 +2390,7 @@ FileDialog::FileDialog() {
show_hidden->set_toggle_mode(true);
show_hidden->set_pressed(is_showing_hidden_files());
show_hidden->set_tooltip_text(ETR("Toggle the visibility of hidden files."));
show_hidden->set_shortcut(action_shortcuts[ITEM_MENU_TOGGLE_HIDDEN]);
lower_toolbar->add_child(show_hidden);
show_hidden->connect(SceneStringName(toggled), callable_mp(this, &FileDialog::set_show_hidden_files));
@ -2449,8 +2426,8 @@ FileDialog::FileDialog() {
show_filename_filter_button = memnew(Button);
show_filename_filter_button->set_theme_type_variation(SceneStringName(FlatButton));
show_filename_filter_button->set_toggle_mode(true);
show_filename_filter_button->set_pressed(false);
show_filename_filter_button->set_tooltip_text(ETR("Toggle the visibility of the filter for file names."));
show_filename_filter_button->set_shortcut(action_shortcuts[ITEM_MENU_FIND]);
lower_toolbar->add_child(show_filename_filter_button);
show_filename_filter_button->connect(SceneStringName(toggled), callable_mp(this, &FileDialog::set_show_filename_filter));

View file

@ -136,6 +136,11 @@ public:
ITEM_MENU_NEW_FOLDER,
ITEM_MENU_SHOW_IN_EXPLORER,
ITEM_MENU_SHOW_BUNDLE_CONTENT,
// Not in the menu, only for shortcuts.
ITEM_MENU_GO_UP,
ITEM_MENU_TOGGLE_HIDDEN,
ITEM_MENU_FIND,
ITEM_MENU_FOCUS_PATH,
};
enum Customization {
@ -170,6 +175,8 @@ private:
bool can_create_folders = true;
bool customization_flags[CUSTOMIZATION_MAX]; // Initialized to true in the constructor.
HashMap<ItemMenu, Ref<Shortcut>> action_shortcuts;
inline static LocalVector<String> global_favorites;
inline static LocalVector<String> global_recents;

View file

@ -657,6 +657,43 @@ PackedStringArray Label::get_configuration_warnings() const {
}
}
Ref<FontFile> ff = font;
if (ff.is_valid() && ff->is_multichannel_signed_distance_field()) {
bool has_settings = settings.is_valid();
int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size;
int outline_size = has_settings ? settings->get_outline_size() : theme_cache.font_outline_size;
Vector<LabelSettings::StackedOutlineData> stacked_outline_datas = has_settings ? settings->get_stacked_outline_data() : Vector<LabelSettings::StackedOutlineData>();
Vector<LabelSettings::StackedShadowData> stacked_shadow_datas = has_settings ? settings->get_stacked_shadow_data() : Vector<LabelSettings::StackedShadowData>();
int max_outline_draw_size = outline_size;
if (stacked_outline_datas.size() != 0) {
int draw_iterations = stacked_outline_datas.size();
for (int j = 0; j < draw_iterations; j++) {
int stacked_outline_size = stacked_outline_datas[j].size;
if (stacked_outline_size <= 0) {
continue;
}
max_outline_draw_size += stacked_outline_size;
}
}
if (stacked_shadow_datas.size() != 0) {
int draw_iterations = stacked_shadow_datas.size();
for (int j = 0; j < draw_iterations; j++) {
LabelSettings::StackedShadowData stacked_shadow_data = stacked_shadow_datas[j];
if (stacked_shadow_data.outline_size > 0) {
max_outline_draw_size = MAX(max_outline_draw_size, stacked_shadow_data.outline_size);
}
}
}
float scale = (float)font_size / (float)ff->get_msdf_size();
float ol = (float)max_outline_draw_size / scale / 4.0;
float pxr = (float)ff->get_msdf_pixel_range() / 2.0 - 1.0;
float r_pxr = (ol + 1.0) * 2.0;
if (ol > pxr) {
warnings.push_back(vformat(RTR("MSDF font pixel range is too small, some outlines/shadows will not render. Set MSDF pixel range to be at least %d to render all outlines/shadows."), Math::ceil(r_pxr)));
}
}
return warnings;
}
@ -857,6 +894,7 @@ void Label::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
font_dirty = true;
queue_redraw();
update_configuration_warnings();
} break;
case NOTIFICATION_RESIZED: {
@ -1070,6 +1108,7 @@ void Label::set_text(const String &p_string) {
void Label::_invalidate() {
font_dirty = true;
queue_redraw();
update_configuration_warnings();
}
void Label::set_label_settings(const Ref<LabelSettings> &p_settings) {
@ -1082,6 +1121,7 @@ void Label::set_label_settings(const Ref<LabelSettings> &p_settings) {
settings->connect_changed(callable_mp(this, &Label::_invalidate), CONNECT_REFERENCE_COUNTED);
}
_invalidate();
update_configuration_warnings();
}
}

View file

@ -174,7 +174,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP && !mb->is_command_or_control_pressed()) {
if (mb->is_pressed() && (mb->get_button_index() == MouseButton::WHEEL_UP || (is_layout_rtl() ? mb->get_button_index() == MouseButton::WHEEL_RIGHT : mb->get_button_index() == MouseButton::WHEEL_LEFT)) && !mb->is_command_or_control_pressed()) {
if (scrolling_enabled && buttons_visible) {
if (offset > 0) {
offset--;
@ -184,7 +184,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
}
}
if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_or_control_pressed()) {
if (mb->is_pressed() && (mb->get_button_index() == MouseButton::WHEEL_DOWN || mb->get_button_index() == (is_layout_rtl() ? MouseButton::WHEEL_LEFT : MouseButton::WHEEL_RIGHT)) && !mb->is_command_or_control_pressed()) {
if (scrolling_enabled && buttons_visible) {
if (missing_right && offset < tabs.size()) {
offset++;

View file

@ -32,6 +32,7 @@
#include "scene/main/node.h"
#include "scene/resources/font.h"
#include "servers/rendering/rendering_server.h"
class CanvasLayer;
class MultiMesh;

View file

@ -1647,22 +1647,29 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name, InternalM
data.children.insert(p_name, p_child);
p_child->data.internal_mode = p_internal_mode;
bool can_push_back = false;
switch (p_internal_mode) {
case INTERNAL_MODE_FRONT: {
p_child->data.index = data.internal_children_front_count_cache++;
// Safe to push back when ordinary and back children are empty.
can_push_back = (data.external_children_count_cache + data.internal_children_back_count_cache) == 0;
} break;
case INTERNAL_MODE_BACK: {
p_child->data.index = data.internal_children_back_count_cache++;
// Safe to push back when cache is valid.
can_push_back = true;
} break;
case INTERNAL_MODE_DISABLED: {
p_child->data.index = data.external_children_count_cache++;
// Safe to push back when back children are empty.
can_push_back = data.internal_children_back_count_cache == 0;
} break;
}
p_child->data.parent = this;
if (!data.children_cache_dirty && p_internal_mode == INTERNAL_MODE_DISABLED && data.internal_children_back_count_cache == 0) {
// Special case, also add to the cached children array since its cheap.
if (!data.children_cache_dirty && can_push_back) {
data.children_cache.push_back(p_child);
} else {
data.children_cache_dirty = true;

View file

@ -196,7 +196,7 @@ private:
Node *parent = nullptr;
Node *owner = nullptr;
HashMap<StringName, Node *> children;
mutable bool children_cache_dirty = true;
mutable bool children_cache_dirty = false;
mutable LocalVector<Node *> children_cache;
HashMap<StringName, Node *> owned_unique_nodes;
bool unique_name_in_owner = false;

View file

@ -1180,6 +1180,8 @@ void Window::_update_window_size() {
DisplayServer::get_singleton()->window_set_max_size(max_size_used, window_id);
DisplayServer::get_singleton()->window_set_min_size(size_limit, window_id);
DisplayServer::get_singleton()->window_set_size(size, window_id);
} else if (Engine::get_singleton()->is_embedded_in_editor()) {
size = DisplayServer::get_singleton()->window_get_size(window_id); // Reset size.
}
}

View file

@ -30,6 +30,9 @@
#include "animated_texture.h"
#include "core/os/os.h"
#include "servers/rendering/rendering_server.h"
void AnimatedTexture::_update_proxy() {
RWLockRead r(rw_lock);

View file

@ -30,6 +30,8 @@
#include "bone_map.h"
#include "core/config/engine.h"
bool BoneMap::_set(const StringName &p_path, const Variant &p_value) {
String path = p_path;
if (path.begins_with("bone_map/")) {

View file

@ -31,6 +31,7 @@
#include "camera_texture.h"
#include "servers/camera/camera_feed.h"
#include "servers/rendering/rendering_server.h"
void CameraTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_camera_feed_id", "feed_id"), &CameraTexture::set_camera_feed_id);

View file

@ -31,6 +31,7 @@
#pragma once
#include "scene/resources/texture.h"
#include "servers/camera/camera_server.h"
class CameraTexture : public Texture2D {
GDCLASS(CameraTexture, Texture2D);

View file

@ -32,6 +32,7 @@
#include "core/io/resource_loader.h"
#include "scene/resources/texture.h"
#include "servers/rendering/rendering_server.h"
class BitMap;

View file

@ -30,6 +30,8 @@
#include "curve_texture.h"
#include "servers/rendering/rendering_server.h"
void CurveTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);

View file

@ -30,6 +30,8 @@
#include "external_texture.h"
#include "servers/rendering/rendering_server.h"
void ExternalTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "size"), &ExternalTexture::set_size);
ClassDB::bind_method(D_METHOD("get_external_texture_id"), &ExternalTexture::get_external_texture_id);

View file

@ -39,6 +39,7 @@
#include "scene/resources/text_paragraph.h"
#include "scene/resources/theme.h"
#include "scene/theme/theme_db.h"
#include "servers/rendering/rendering_server.h"
/*************************************************************************/
/* Font */

View file

@ -31,6 +31,7 @@
#include "gradient_texture.h"
#include "core/math/geometry_2d.h"
#include "servers/rendering/rendering_server.h"
GradientTexture1D::GradientTexture1D() {
_queue_update();

View file

@ -30,6 +30,7 @@
#pragma once
#include "scene/resources/gradient.h"
#include "scene/resources/texture.h"
class GradientTexture1D : public Texture2D {

View file

@ -33,6 +33,7 @@
#include "core/io/image_loader.h"
#include "scene/resources/bit_map.h"
#include "scene/resources/placeholder_textures.h"
#include "servers/rendering/rendering_server.h"
void ImageTexture::reload_from_file() {
String path = ResourceLoader::path_remap(get_path());

View file

@ -30,6 +30,8 @@
#include "placeholder_textures.h"
#include "servers/rendering/rendering_server.h"
void PlaceholderTexture2D::set_size(Size2 p_size) {
size = p_size;
emit_changed();

View file

@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/io/marshalls.h"
#include "scene/resources/bit_map.h"
#include "servers/rendering/rendering_server.h"
static const char *compression_mode_names[7] = {
"Lossless", "Lossy", "Basis Universal", "S3TC", "ETC2", "BPTC", "ASTC"

View file

@ -30,6 +30,8 @@
#include "skeleton_profile.h"
#include "core/config/engine.h"
bool SkeletonProfile::_set(const StringName &p_path, const Variant &p_value) {
ERR_FAIL_COND_V(is_read_only, false);
String path = p_path;

View file

@ -30,6 +30,8 @@
#include "style_box_texture.h"
#include "servers/rendering/rendering_server.h"
float StyleBoxTexture::get_style_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0.0);

View file

@ -31,6 +31,7 @@
#include "texture.h"
#include "scene/resources/placeholder_textures.h"
#include "servers/rendering/rendering_server.h"
int Texture2D::get_width() const {
int ret = 0;

View file

@ -30,12 +30,10 @@
#pragma once
#include "core/io/image.h"
#include "core/io/resource.h"
#include "core/math/rect2.h"
#include "core/variant/typed_array.h"
#include "scene/resources/curve.h"
#include "scene/resources/gradient.h"
#include "servers/camera/camera_server.h"
#include "servers/rendering/rendering_server.h"
class Texture : public Resource {
GDCLASS(Texture, Resource);

View file

@ -30,6 +30,8 @@
#include "texture_rd.h"
#include "servers/rendering/rendering_server.h"
////////////////////////////////////////////////////////////////////////////
// Texture2DRD

View file

@ -357,12 +357,12 @@ public:
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
virtual float screen_get_max_scale() const {
float scale = 1.f;
float max_scale = 1.f;
int screen_count = get_screen_count();
for (int i = 0; i < screen_count; i++) {
scale = std::fmax(scale, screen_get_scale(i));
max_scale = std::fmax(max_scale, screen_get_scale(i));
}
return scale;
return max_scale;
}
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual Color screen_get_pixel(const Point2i &p_position) const { return Color(); }

View file

@ -2690,7 +2690,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
if (view_count == 1) {
camera_data.set_camera(transforms[0], projections[0], false, false, camera->vaspect, jitter, p_jitter_phase_count, camera->visible_layers);
} else if (view_count == 2) {
camera_data.set_multiview_camera(view_count, transforms, projections, false, false, camera->vaspect);
camera_data.set_multiview_camera(view_count, transforms, projections, false, false, camera->vaspect, camera->visible_layers);
} else {
// this won't be called (see fail check above) but keeping this comment to indicate we may support more then 2 views in the future...
}

View file

@ -33,7 +33,7 @@
/////////////////////////////////////////////////////////////////////////////
// CameraData
void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, const Vector2 &p_taa_jitter, float p_taa_frame_count, const uint32_t p_visible_layers) {
void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, const Vector2 &p_taa_jitter, float p_taa_frame_count, uint32_t p_visible_layers) {
view_count = 1;
is_orthogonal = p_is_orthogonal;
is_frustum = p_is_frustum;
@ -49,10 +49,10 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform,
taa_frame_count = p_taa_frame_count;
}
void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect) {
void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, uint32_t p_visible_layers) {
ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view");
visible_layers = 0xFFFFFFFF;
visible_layers = p_visible_layers;
view_count = p_view_count;
is_orthogonal = p_is_orthogonal;
is_frustum = p_is_frustum;

View file

@ -312,7 +312,7 @@ public:
float taa_frame_count = 0.0f;
void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), float p_taa_frame_count = 0.0f, uint32_t p_visible_layers = 0xFFFFFFFF);
void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect);
void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, uint32_t p_visible_layers = 0xFFFFFFFF);
};
virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;