Merge pull request #49237 from akien-mga/3.x-cherrypicks
This commit is contained in:
commit
e0fb05ad30
|
@ -760,7 +760,7 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
|||
unsigned int hour = ((datetime.has(HOUR_KEY)) ? static_cast<unsigned int>(datetime[HOUR_KEY]) : 0);
|
||||
unsigned int day = ((datetime.has(DAY_KEY)) ? static_cast<unsigned int>(datetime[DAY_KEY]) : 1);
|
||||
unsigned int month = ((datetime.has(MONTH_KEY)) ? static_cast<unsigned int>(datetime[MONTH_KEY]) : 1);
|
||||
unsigned int year = ((datetime.has(YEAR_KEY)) ? static_cast<unsigned int>(datetime[YEAR_KEY]) : 0);
|
||||
unsigned int year = ((datetime.has(YEAR_KEY)) ? static_cast<unsigned int>(datetime[YEAR_KEY]) : 1970);
|
||||
|
||||
/// How many days come before each month (0-12)
|
||||
static const unsigned short int DAYS_PAST_THIS_YEAR_TABLE[2][13] = {
|
||||
|
@ -771,15 +771,14 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
|||
};
|
||||
|
||||
ERR_FAIL_COND_V_MSG(second > 59, 0, "Invalid second value of: " + itos(second) + ".");
|
||||
|
||||
ERR_FAIL_COND_V_MSG(minute > 59, 0, "Invalid minute value of: " + itos(minute) + ".");
|
||||
|
||||
ERR_FAIL_COND_V_MSG(hour > 23, 0, "Invalid hour value of: " + itos(hour) + ".");
|
||||
|
||||
ERR_FAIL_COND_V_MSG(year == 0, 0, "Years before 1 AD are not supported. Value passed: " + itos(year) + ".");
|
||||
ERR_FAIL_COND_V_MSG(month > 12 || month == 0, 0, "Invalid month value of: " + itos(month) + ".");
|
||||
|
||||
// Do this check after month is tested as valid
|
||||
ERR_FAIL_COND_V_MSG(day > MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1] || day == 0, 0, "Invalid day value of '" + itos(day) + "' which is larger than '" + itos(MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1]) + "' or 0.");
|
||||
unsigned int days_in_month = MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1];
|
||||
ERR_FAIL_COND_V_MSG(day == 0 || day > days_in_month, 0, "Invalid day value of: " + itos(day) + ". It should be comprised between 1 and " + itos(days_in_month) + " for month " + itos(month) + ".");
|
||||
|
||||
// Calculate all the seconds from months past in this year
|
||||
uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = DAYS_PAST_THIS_YEAR_TABLE[LEAPYEAR(year)][month - 1] * SECONDS_PER_DAY;
|
||||
|
||||
|
|
|
@ -550,7 +550,7 @@
|
|||
<description>
|
||||
Gets an epoch time value from a dictionary of time values.
|
||||
[code]datetime[/code] must be populated with the following keys: [code]year[/code], [code]month[/code], [code]day[/code], [code]hour[/code], [code]minute[/code], [code]second[/code].
|
||||
If the dictionary is empty [code]0[/code] is returned.
|
||||
If the dictionary is empty [code]0[/code] is returned. If some keys are omitted, they default to the equivalent values for the UNIX epoch timestamp 0 (1970-01-01 at 00:00:00 UTC).
|
||||
You can pass the output from [method get_datetime_from_unix_time] directly into this function. Daylight Savings Time ([code]dst[/code]), if present, is ignored.
|
||||
</description>
|
||||
</method>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<description>
|
||||
Duplicates the resource, returning a new resource. By default, sub-resources are shared between resource copies for efficiency. This can be changed by passing [code]true[/code] to the [code]subresources[/code] argument which will copy the subresources.
|
||||
[b]Note:[/b] If [code]subresources[/code] is [code]true[/code], this method will only perform a shallow copy. Nested resources within subresources will not be duplicated and will still be shared.
|
||||
[b]Note:[/b] When duplicating a resource, only [code]export[/code]ed properties are copied. Other properties will be set to their default value in the new resource.
|
||||
</description>
|
||||
</method>
|
||||
<method name="emit_changed">
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
<member name="expand" type="bool" setter="set_expand" getter="get_expand" default="false">
|
||||
If [code]true[/code], the texture stretches to the edges of the node's bounding rectangle using the [member stretch_mode]. If [code]false[/code], the texture will not scale with the node.
|
||||
</member>
|
||||
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h" default="false">
|
||||
If [code]true[/code], texture is flipped horizontally.
|
||||
</member>
|
||||
<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v" default="false">
|
||||
If [code]true[/code], texture is flipped vertically.
|
||||
</member>
|
||||
<member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureButton.StretchMode" default="0">
|
||||
Controls the texture's behavior when you resize the node's bounding rectangle, [b]only if[/b] [member expand] is [code]true[/code]. Set it to one of the [enum StretchMode] constants. See the constants to learn more.
|
||||
</member>
|
||||
|
|
|
@ -432,7 +432,7 @@ uint64_t DirAccessUnix::get_space_left() {
|
|||
return 0;
|
||||
};
|
||||
|
||||
return vfs.f_bfree * vfs.f_bsize;
|
||||
return (uint64_t)vfs.f_bavail * (uint64_t)vfs.f_frsize;
|
||||
#else
|
||||
// FIXME: Implement this.
|
||||
return 0;
|
||||
|
|
|
@ -173,6 +173,9 @@ void EditorAudioBus::_notification(int p_what) {
|
|||
bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons"));
|
||||
|
||||
bus_options->set_icon(get_icon("GuiTabMenuHl", "EditorIcons"));
|
||||
|
||||
audio_value_preview_box->add_color_override("font_color", get_color("font_color", "TooltipLabel"));
|
||||
audio_value_preview_box->add_style_override("panel", get_stylebox("panel", "TooltipPanel"));
|
||||
} break;
|
||||
case NOTIFICATION_MOUSE_EXIT:
|
||||
case NOTIFICATION_DRAG_END: {
|
||||
|
@ -379,15 +382,24 @@ void EditorAudioBus::_show_value(float slider_value) {
|
|||
db = _normalized_volume_to_scaled_db(slider_value);
|
||||
}
|
||||
|
||||
String text = vformat("%10.1f dB", db);
|
||||
String text;
|
||||
if (Math::is_zero_approx(Math::stepify(db, 0.1))) {
|
||||
// Prevent displaying `-0.0 dB` and show ` 0.0 dB` instead.
|
||||
// The leading space makes the text visually line up with its positive/negative counterparts.
|
||||
text = " 0.0 dB";
|
||||
} else {
|
||||
// Show an explicit `+` sign if positive.
|
||||
text = vformat("%+.1f dB", db);
|
||||
}
|
||||
|
||||
// Also set the preview text as a standard Control tooltip.
|
||||
// This way, it can be seen when the slider is merely hovered (instead of dragged).
|
||||
slider->set_tooltip(text);
|
||||
audio_value_preview_label->set_text(text);
|
||||
Vector2 slider_size = slider->get_size();
|
||||
Vector2 slider_position = slider->get_global_position();
|
||||
float left_padding = 5.0f;
|
||||
float vert_padding = 10.0f;
|
||||
Vector2 box_position = Vector2(slider_size.x + left_padding, (slider_size.y - vert_padding) * (1.0f - slider->get_value()) - vert_padding);
|
||||
const Vector2 slider_size = slider->get_size();
|
||||
const Vector2 slider_position = slider->get_global_position();
|
||||
const float vert_padding = 10.0f;
|
||||
const Vector2 box_position = Vector2(slider_size.x, (slider_size.y - vert_padding) * (1.0f - slider->get_value()) - vert_padding);
|
||||
audio_value_preview_box->set_position(slider_position + box_position);
|
||||
audio_value_preview_box->set_size(audio_value_preview_label->get_size());
|
||||
if (slider->has_focus() && !audio_value_preview_box->is_visible()) {
|
||||
|
@ -818,7 +830,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
|
|||
bus_options = memnew(MenuButton);
|
||||
bus_options->set_h_size_flags(SIZE_SHRINK_END);
|
||||
bus_options->set_anchor(MARGIN_RIGHT, 0.0);
|
||||
bus_options->set_tooltip(TTR("Bus options"));
|
||||
bus_options->set_tooltip(TTR("Bus Options"));
|
||||
hbc->add_child(bus_options);
|
||||
|
||||
Ref<StyleBoxEmpty> sbempty = memnew(StyleBoxEmpty);
|
||||
|
@ -853,14 +865,13 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
|
|||
audio_value_preview_label->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
audio_value_preview_label->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
audio_value_preview_label->set_mouse_filter(MOUSE_FILTER_PASS);
|
||||
audio_value_preview_box->add_color_override("font_color", get_color("font_color", "TooltipLabel"));
|
||||
|
||||
audioprev_hbc->add_child(audio_value_preview_label);
|
||||
|
||||
slider->add_child(audio_value_preview_box);
|
||||
audio_value_preview_box->set_as_toplevel(true);
|
||||
Ref<StyleBoxFlat> panel_style = memnew(StyleBoxFlat);
|
||||
panel_style->set_bg_color(Color(0.0f, 0.0f, 0.0f, 0.8f));
|
||||
audio_value_preview_box->add_style_override("panel", panel_style);
|
||||
audio_value_preview_box->add_style_override("panel", get_stylebox("panel", "TooltipPanel"));
|
||||
audio_value_preview_box->set_mouse_filter(MOUSE_FILTER_PASS);
|
||||
audio_value_preview_box->hide();
|
||||
|
||||
|
@ -1427,7 +1438,7 @@ void EditorAudioMeterNotches::_bind_methods() {
|
|||
void EditorAudioMeterNotches::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
notch_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(0, 0, 0);
|
||||
notch_color = get_color("font_color", "Editor");
|
||||
} break;
|
||||
case NOTIFICATION_DRAW: {
|
||||
_draw_audio_notches();
|
||||
|
@ -1442,13 +1453,13 @@ void EditorAudioMeterNotches::_draw_audio_notches() {
|
|||
for (int i = 0; i < notches.size(); i++) {
|
||||
AudioNotch n = notches[i];
|
||||
draw_line(Vector2(0, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding),
|
||||
Vector2(line_length, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding),
|
||||
Vector2(line_length * EDSCALE, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding),
|
||||
notch_color,
|
||||
1);
|
||||
Math::round(EDSCALE));
|
||||
|
||||
if (n.render_db_value) {
|
||||
draw_string(font,
|
||||
Vector2(line_length + label_space,
|
||||
Vector2((line_length + label_space) * EDSCALE,
|
||||
(1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + (font_height / 4) + top_padding),
|
||||
String::num(Math::abs(n.db_value)) + "dB",
|
||||
notch_color);
|
||||
|
@ -1456,10 +1467,6 @@ void EditorAudioMeterNotches::_draw_audio_notches() {
|
|||
}
|
||||
}
|
||||
|
||||
EditorAudioMeterNotches::EditorAudioMeterNotches() :
|
||||
line_length(5.0f),
|
||||
label_space(2.0f),
|
||||
btm_padding(9.0f),
|
||||
top_padding(5.0f) {
|
||||
notch_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(0, 0, 0);
|
||||
EditorAudioMeterNotches::EditorAudioMeterNotches() {
|
||||
notch_color = get_color("font_color", "Editor");
|
||||
}
|
||||
|
|
|
@ -244,10 +244,10 @@ private:
|
|||
List<AudioNotch> notches;
|
||||
|
||||
public:
|
||||
float line_length;
|
||||
float label_space;
|
||||
float btm_padding;
|
||||
float top_padding;
|
||||
const float line_length = 5.0f;
|
||||
const float label_space = 2.0f;
|
||||
const float btm_padding = 9.0f;
|
||||
const float top_padding = 5.0f;
|
||||
Color notch_color;
|
||||
|
||||
void add_notch(float p_normalized_offset, float p_db_value, bool p_render_value = false);
|
||||
|
|
|
@ -116,6 +116,18 @@ bool EditorFeatureProfile::has_class_properties_disabled(const StringName &p_cla
|
|||
return disabled_properties.has(p_class);
|
||||
}
|
||||
|
||||
void EditorFeatureProfile::set_item_collapsed(const StringName &p_class, bool p_collapsed) {
|
||||
if (p_collapsed) {
|
||||
collapsed_classes.insert(p_class);
|
||||
} else {
|
||||
collapsed_classes.erase(p_class);
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorFeatureProfile::is_item_collapsed(const StringName &p_class) const {
|
||||
return collapsed_classes.has(p_class);
|
||||
}
|
||||
|
||||
void EditorFeatureProfile::set_disable_feature(Feature p_feature, bool p_disable) {
|
||||
ERR_FAIL_INDEX(p_feature, FEATURE_MAX);
|
||||
features_disabled[p_feature] = p_disable;
|
||||
|
@ -478,6 +490,9 @@ void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const S
|
|||
class_item->set_selectable(0, true);
|
||||
class_item->set_metadata(0, p_class);
|
||||
|
||||
bool collapsed = edited->is_item_collapsed(p_class);
|
||||
class_item->set_collapsed(collapsed);
|
||||
|
||||
if (p_class == p_selected) {
|
||||
class_item->select(0);
|
||||
}
|
||||
|
@ -590,6 +605,26 @@ void EditorFeatureProfileManager::_class_list_item_edited() {
|
|||
}
|
||||
}
|
||||
|
||||
void EditorFeatureProfileManager::_class_list_item_collapsed(Object *p_item) {
|
||||
if (updating_features) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreeItem *item = Object::cast_to<TreeItem>(p_item);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
Variant md = item->get_metadata(0);
|
||||
if (md.get_type() != Variant::STRING) {
|
||||
return;
|
||||
}
|
||||
|
||||
String class_name = md;
|
||||
bool collapsed = item->is_collapsed();
|
||||
edited->set_item_collapsed(class_name, collapsed);
|
||||
}
|
||||
|
||||
void EditorFeatureProfileManager::_property_item_edited() {
|
||||
if (updating_features) {
|
||||
return;
|
||||
|
@ -781,6 +816,7 @@ void EditorFeatureProfileManager::_bind_methods() {
|
|||
ClassDB::bind_method("_export_profile", &EditorFeatureProfileManager::_export_profile);
|
||||
ClassDB::bind_method("_class_list_item_selected", &EditorFeatureProfileManager::_class_list_item_selected);
|
||||
ClassDB::bind_method("_class_list_item_edited", &EditorFeatureProfileManager::_class_list_item_edited);
|
||||
ClassDB::bind_method("_class_list_item_collapsed", &EditorFeatureProfileManager::_class_list_item_collapsed);
|
||||
ClassDB::bind_method("_property_item_edited", &EditorFeatureProfileManager::_property_item_edited);
|
||||
ClassDB::bind_method("_emit_current_profile_changed", &EditorFeatureProfileManager::_emit_current_profile_changed);
|
||||
|
||||
|
@ -852,6 +888,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
|
|||
class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
|
||||
class_list->connect("cell_selected", this, "_class_list_item_selected");
|
||||
class_list->connect("item_edited", this, "_class_list_item_edited", varray(), CONNECT_DEFERRED);
|
||||
class_list->connect("item_collapsed", this, "_class_list_item_collapsed");
|
||||
|
||||
VBoxContainer *property_list_vbc = memnew(VBoxContainer);
|
||||
h_split->add_child(property_list_vbc);
|
||||
|
|
|
@ -60,6 +60,8 @@ private:
|
|||
Set<StringName> disabled_editors;
|
||||
Map<StringName, Set<StringName>> disabled_properties;
|
||||
|
||||
Set<StringName> collapsed_classes;
|
||||
|
||||
bool features_disabled[FEATURE_MAX];
|
||||
static const char *feature_names[FEATURE_MAX];
|
||||
static const char *feature_identifiers[FEATURE_MAX];
|
||||
|
@ -80,6 +82,9 @@ public:
|
|||
bool is_class_property_disabled(const StringName &p_class, const StringName &p_property) const;
|
||||
bool has_class_properties_disabled(const StringName &p_class) const;
|
||||
|
||||
void set_item_collapsed(const StringName &p_class, bool p_collapsed);
|
||||
bool is_item_collapsed(const StringName &p_class) const;
|
||||
|
||||
void set_disable_feature(Feature p_feature, bool p_disable);
|
||||
bool is_feature_disabled(Feature p_feature) const;
|
||||
|
||||
|
@ -148,6 +153,7 @@ class EditorFeatureProfileManager : public AcceptDialog {
|
|||
|
||||
void _class_list_item_selected();
|
||||
void _class_list_item_edited();
|
||||
void _class_list_item_collapsed(Object *p_item);
|
||||
void _property_item_edited();
|
||||
void _save_and_update();
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ PluginConfigDialog::PluginConfigDialog() {
|
|||
|
||||
desc_edit = memnew(TextEdit);
|
||||
desc_edit->set_custom_minimum_size(Size2(400, 80) * EDSCALE);
|
||||
desc_edit->set_wrap_enabled(true);
|
||||
grid->add_child(desc_edit);
|
||||
|
||||
Label *author_lb = memnew(Label);
|
||||
|
|
|
@ -5252,8 +5252,10 @@ void CanvasItemEditor::_bind_methods() {
|
|||
ClassDB::bind_method("_popup_warning_depop", &CanvasItemEditor::_popup_warning_depop);
|
||||
ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &CanvasItemEditor::_selection_result_pressed);
|
||||
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &CanvasItemEditor::_selection_menu_hide);
|
||||
ClassDB::bind_method(D_METHOD("get_state"), &CanvasItemEditor::get_state);
|
||||
ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state);
|
||||
ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport);
|
||||
ClassDB::bind_method(D_METHOD("_zoom_on_position"), &CanvasItemEditor::_zoom_on_position);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
|
||||
ADD_SIGNAL(MethodInfo("item_group_status_changed"));
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "script_text_editor.h"
|
||||
|
||||
#include "core/math/expression.h"
|
||||
#include "core/os/input.h"
|
||||
#include "core/os/keyboard.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_scale.h"
|
||||
|
@ -1506,11 +1507,17 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
|
|||
Array files = d["files"];
|
||||
|
||||
String text_to_drop;
|
||||
bool preload = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
if (i > 0) {
|
||||
text_to_drop += ",";
|
||||
text_to_drop += ", ";
|
||||
}
|
||||
|
||||
if (preload) {
|
||||
text_to_drop += "preload(\"" + String(files[i]).c_escape() + "\")";
|
||||
} else {
|
||||
text_to_drop += "\"" + String(files[i]).c_escape() + "\"";
|
||||
}
|
||||
text_to_drop += "\"" + String(files[i]).c_escape() + "\"";
|
||||
}
|
||||
|
||||
te->cursor_set_line(row);
|
||||
|
|
|
@ -247,7 +247,7 @@
|
|||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
OTHER_LDFLAGS = "$linker_flags";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "$targeted_device_family";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -286,7 +286,7 @@
|
|||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
OTHER_LDFLAGS = "$linker_flags";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "$targeted_device_family";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
@ -315,7 +315,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = $identifier;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "$provisioning_profile_uuid_debug";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "$targeted_device_family";
|
||||
VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
@ -345,7 +345,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = $identifier;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "$provisioning_profile_uuid_release";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "$targeted_device_family";
|
||||
VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "$default_build_config"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
|
@ -42,7 +42,7 @@
|
|||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "$default_build_config"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
|
@ -67,7 +67,7 @@
|
|||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "$default_build_config"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
|
@ -84,10 +84,10 @@
|
|||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
buildConfiguration = "$default_build_config">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "$default_build_config"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
|
@ -203,6 +203,8 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) {
|
|||
}
|
||||
|
||||
bool PluginScript::instance_has(const Object *p_this) const {
|
||||
ERR_FAIL_COND_V(!_language, false);
|
||||
|
||||
_language->lock();
|
||||
bool hasit = _instances.has((Object *)p_this);
|
||||
_language->unlock();
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
<member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise">
|
||||
The [OpenSimplexNoise] instance used to generate the noise.
|
||||
</member>
|
||||
<member name="noise_offset" type="Vector2" setter="set_noise_offset" getter="get_noise_offset" default="Vector2( 0, 0 )">
|
||||
An offset used to specify the noise space coordinate of the top left corner of the generated noise. This value is ignored if [member seamless] is enabled.
|
||||
</member>
|
||||
<member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false">
|
||||
Whether the texture can be tiled without visible seams or not. Seamless textures take longer to generate.
|
||||
[b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise.
|
||||
|
|
|
@ -31,8 +31,10 @@
|
|||
</argument>
|
||||
<argument index="1" name="height" type="int">
|
||||
</argument>
|
||||
<argument index="2" name="noise_offset" type="Vector2" default="Vector2( 0, 0 )">
|
||||
</argument>
|
||||
<description>
|
||||
Generate a noise image in [constant Image.FORMAT_L8] format with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters.
|
||||
Generate a noise image in [constant Image.FORMAT_L8] format with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters. If [code]noise_offset[/code] is specified, then the offset value is used as the coordinates of the top-left corner of the generated noise.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_1d" qualifiers="const">
|
||||
|
|
|
@ -62,6 +62,9 @@ void NoiseTexture::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise);
|
||||
ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_noise_offset", "noise_offset"), &NoiseTexture::set_noise_offset);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_offset"), &NoiseTexture::get_noise_offset);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture::set_seamless);
|
||||
ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);
|
||||
|
||||
|
@ -82,6 +85,7 @@ void NoiseTexture::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "noise_offset"), "set_noise_offset", "get_noise_offset");
|
||||
}
|
||||
|
||||
void NoiseTexture::_validate_property(PropertyInfo &property) const {
|
||||
|
@ -137,7 +141,7 @@ Ref<Image> NoiseTexture::_generate_texture() {
|
|||
if (seamless) {
|
||||
image = ref_noise->get_seamless_image(size.x);
|
||||
} else {
|
||||
image = ref_noise->get_image(size.x, size.y);
|
||||
image = ref_noise->get_image(size.x, size.y, noise_offset);
|
||||
}
|
||||
|
||||
if (as_normalmap) {
|
||||
|
@ -205,6 +209,14 @@ void NoiseTexture::set_height(int p_height) {
|
|||
_queue_update();
|
||||
}
|
||||
|
||||
void NoiseTexture::set_noise_offset(Vector2 p_noise_offset) {
|
||||
if (noise_offset == p_noise_offset) {
|
||||
return;
|
||||
}
|
||||
noise_offset = p_noise_offset;
|
||||
_queue_update();
|
||||
}
|
||||
|
||||
void NoiseTexture::set_seamless(bool p_seamless) {
|
||||
if (p_seamless == seamless) {
|
||||
return;
|
||||
|
@ -252,6 +264,10 @@ int NoiseTexture::get_height() const {
|
|||
return size.y;
|
||||
}
|
||||
|
||||
Vector2 NoiseTexture::get_noise_offset() const {
|
||||
return noise_offset;
|
||||
}
|
||||
|
||||
void NoiseTexture::set_flags(uint32_t p_flags) {
|
||||
flags = p_flags;
|
||||
VS::get_singleton()->texture_set_flags(texture, flags);
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
|
||||
Ref<OpenSimplexNoise> noise;
|
||||
Vector2i size;
|
||||
Vector2 noise_offset;
|
||||
bool seamless;
|
||||
bool as_normalmap;
|
||||
float bump_strength;
|
||||
|
@ -79,6 +80,9 @@ public:
|
|||
void set_width(int p_width);
|
||||
void set_height(int p_height);
|
||||
|
||||
void set_noise_offset(Vector2 p_noise_offset);
|
||||
Vector2 get_noise_offset() const;
|
||||
|
||||
void set_seamless(bool p_seamless);
|
||||
bool get_seamless();
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
|
|||
emit_changed();
|
||||
}
|
||||
|
||||
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
|
||||
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height, const Vector2 &p_noise_offset) const {
|
||||
PoolVector<uint8_t> data;
|
||||
data.resize(p_width * p_height);
|
||||
|
||||
|
@ -110,7 +110,7 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
|
|||
|
||||
for (int i = 0; i < p_height; i++) {
|
||||
for (int j = 0; j < p_width; j++) {
|
||||
float v = get_noise_2d(i, j);
|
||||
float v = get_noise_2d(float(j) + p_noise_offset.x, float(i) + p_noise_offset.y);
|
||||
v = v * 0.5 + 0.5; // Normalize [0..1]
|
||||
wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ void OpenSimplexNoise::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_lacunarity", "lacunarity"), &OpenSimplexNoise::set_lacunarity);
|
||||
ClassDB::bind_method(D_METHOD("get_lacunarity"), &OpenSimplexNoise::get_lacunarity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_image", "width", "height"), &OpenSimplexNoise::get_image);
|
||||
ClassDB::bind_method(D_METHOD("get_image", "width", "height", "noise_offset"), &OpenSimplexNoise::get_image, DEFVAL(Vector2()));
|
||||
ClassDB::bind_method(D_METHOD("get_seamless_image", "size"), &OpenSimplexNoise::get_seamless_image);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_noise_1d", "x"), &OpenSimplexNoise::get_noise_1d);
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
void set_lacunarity(float p_lacunarity);
|
||||
float get_lacunarity() const { return lacunarity; }
|
||||
|
||||
Ref<Image> get_image(int p_width, int p_height) const;
|
||||
Ref<Image> get_image(int p_width, int p_height, const Vector2 &p_noise_offset = Vector2()) const;
|
||||
Ref<Image> get_seamless_image(int p_size) const;
|
||||
|
||||
float get_noise_1d(float x) const;
|
||||
|
|
|
@ -134,6 +134,7 @@ bool VisualScriptBuiltinFunc::has_input_sequence_port() const {
|
|||
case TEXT_PRINT:
|
||||
case TEXT_PRINTERR:
|
||||
case TEXT_PRINTRAW:
|
||||
case MATH_SEED:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -352,6 +352,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
|
|||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_release", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Distribution"), ""));
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_release", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 0));
|
||||
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/targeted_device_family", PROPERTY_HINT_ENUM, "iPhone,iPad,iPhone & iPad"), 2));
|
||||
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), ""));
|
||||
|
@ -444,6 +446,8 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
|
|||
strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n";
|
||||
} else if (lines[i].find("$team_id") != -1) {
|
||||
strnew += lines[i].replace("$team_id", p_preset->get("application/app_store_team_id")) + "\n";
|
||||
} else if (lines[i].find("$default_build_config") != -1) {
|
||||
strnew += lines[i].replace("$default_build_config", p_debug ? "Debug" : "Release") + "\n";
|
||||
} else if (lines[i].find("$export_method") != -1) {
|
||||
int export_method = p_preset->get(p_debug ? "application/export_method_debug" : "application/export_method_release");
|
||||
strnew += lines[i].replace("$export_method", export_method_string[export_method]) + "\n";
|
||||
|
@ -464,6 +468,20 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
|
|||
strnew += lines[i].replace("$godot_archs", p_config.architectures) + "\n";
|
||||
} else if (lines[i].find("$linker_flags") != -1) {
|
||||
strnew += lines[i].replace("$linker_flags", p_config.linker_flags) + "\n";
|
||||
} else if (lines[i].find("$targeted_device_family") != -1) {
|
||||
String xcode_value;
|
||||
switch ((int)p_preset->get("application/targeted_device_family")) {
|
||||
case 0: // iPhone
|
||||
xcode_value = "1";
|
||||
break;
|
||||
case 1: // iPad
|
||||
xcode_value = "2";
|
||||
break;
|
||||
case 2: // iPhone & iPad
|
||||
xcode_value = "1,2";
|
||||
break;
|
||||
}
|
||||
strnew += lines[i].replace("$targeted_device_family", xcode_value) + "\n";
|
||||
} else if (lines[i].find("$cpp_code") != -1) {
|
||||
strnew += lines[i].replace("$cpp_code", p_config.cpp_code) + "\n";
|
||||
} else if (lines[i].find("$docs_in_place") != -1) {
|
||||
|
|
|
@ -272,11 +272,10 @@ void Camera2D::_notification(int p_what) {
|
|||
}
|
||||
|
||||
if (screen_drawing_enabled) {
|
||||
Color area_axis_color(0.5, 0.42, 0.87, 0.63);
|
||||
Color area_axis_color(1, 0.4, 1, 0.63);
|
||||
float area_axis_width = 1;
|
||||
if (is_current()) {
|
||||
area_axis_width = 3;
|
||||
area_axis_color.a = 0.83;
|
||||
}
|
||||
|
||||
Transform2D inv_camera_transform = get_camera_transform().affine_inverse();
|
||||
|
@ -297,10 +296,9 @@ void Camera2D::_notification(int p_what) {
|
|||
}
|
||||
|
||||
if (limit_drawing_enabled) {
|
||||
Color limit_drawing_color(1, 1, 0, 0.63);
|
||||
Color limit_drawing_color(1, 1, 0.25, 0.63);
|
||||
float limit_drawing_width = 1;
|
||||
if (is_current()) {
|
||||
limit_drawing_color.a = 0.83;
|
||||
limit_drawing_width = 3;
|
||||
}
|
||||
|
||||
|
@ -319,11 +317,10 @@ void Camera2D::_notification(int p_what) {
|
|||
}
|
||||
|
||||
if (margin_drawing_enabled) {
|
||||
Color margin_drawing_color(0, 1, 1, 0.63);
|
||||
Color margin_drawing_color(0.25, 1, 1, 0.63);
|
||||
float margin_drawing_width = 1;
|
||||
if (is_current()) {
|
||||
margin_drawing_width = 3;
|
||||
margin_drawing_color.a = 0.83;
|
||||
}
|
||||
|
||||
Transform2D inv_camera_transform = get_camera_transform().affine_inverse();
|
||||
|
|
|
@ -666,7 +666,7 @@ void Skeleton::_rebuild_physical_bones_cache() {
|
|||
const int b_size = bones.size();
|
||||
for (int i = 0; i < b_size; ++i) {
|
||||
PhysicalBone *parent_pb = _get_physical_bone_parent(i);
|
||||
if (parent_pb != bones[i].physical_bone) {
|
||||
if (parent_pb != bones[i].cache_parent_physical_bone) {
|
||||
bones.write[i].cache_parent_physical_bone = parent_pb;
|
||||
if (bones[i].physical_bone) {
|
||||
bones[i].physical_bone->_on_bone_parent_changed();
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
|
||||
#include "core/method_bind_ext.gen.inc"
|
||||
|
||||
struct _MinSizeCache {
|
||||
int min_size;
|
||||
bool will_stretch;
|
||||
int final_size;
|
||||
};
|
||||
|
||||
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
|
||||
if (!p_name.operator String().begins_with("slot/")) {
|
||||
return false;
|
||||
|
@ -119,15 +125,23 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
}
|
||||
|
||||
void GraphNode::_resort() {
|
||||
int sep = get_constant("separation");
|
||||
Ref<StyleBox> sb = get_stylebox("frame");
|
||||
bool first = true;
|
||||
/** First pass, determine minimum size AND amount of stretchable elements */
|
||||
|
||||
Size2 minsize;
|
||||
Size2 new_size = get_size();
|
||||
Ref<StyleBox> sb = get_stylebox("frame");
|
||||
|
||||
int sep = get_constant("separation");
|
||||
|
||||
bool first = true;
|
||||
int children_count = 0;
|
||||
int stretch_min = 0;
|
||||
int stretch_avail = 0;
|
||||
float stretch_ratio_total = 0;
|
||||
Map<Control *, _MinSizeCache> min_size_cache;
|
||||
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
if (!c) {
|
||||
if (!c || !c->is_visible_in_tree()) {
|
||||
continue;
|
||||
}
|
||||
if (c->is_set_as_toplevel()) {
|
||||
|
@ -135,38 +149,120 @@ void GraphNode::_resort() {
|
|||
}
|
||||
|
||||
Size2i size = c->get_combined_minimum_size();
|
||||
_MinSizeCache msc;
|
||||
|
||||
minsize.y += size.y;
|
||||
minsize.x = MAX(minsize.x, size.x);
|
||||
stretch_min += size.height;
|
||||
msc.min_size = size.height;
|
||||
msc.will_stretch = c->get_v_size_flags() & SIZE_EXPAND;
|
||||
|
||||
if (msc.will_stretch) {
|
||||
stretch_avail += msc.min_size;
|
||||
stretch_ratio_total += c->get_stretch_ratio();
|
||||
}
|
||||
msc.final_size = msc.min_size;
|
||||
min_size_cache[c] = msc;
|
||||
children_count++;
|
||||
}
|
||||
|
||||
if (children_count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int stretch_max = new_size.height - (children_count - 1) * sep;
|
||||
int stretch_diff = stretch_max - stretch_min;
|
||||
if (stretch_diff < 0) {
|
||||
//avoid negative stretch space
|
||||
stretch_diff = 0;
|
||||
}
|
||||
|
||||
stretch_avail += stretch_diff - sb->get_margin(MARGIN_BOTTOM) - sb->get_margin(MARGIN_TOP); //available stretch space.
|
||||
/** Second, pass sucessively to discard elements that can't be stretched, this will run while stretchable
|
||||
elements exist */
|
||||
|
||||
while (stretch_ratio_total > 0) { // first of all, don't even be here if no stretchable objects exist
|
||||
bool refit_successful = true; //assume refit-test will go well
|
||||
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
if (!c || !c->is_visible_in_tree()) {
|
||||
continue;
|
||||
}
|
||||
if (c->is_set_as_toplevel()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(!min_size_cache.has(c));
|
||||
_MinSizeCache &msc = min_size_cache[c];
|
||||
|
||||
if (msc.will_stretch) { //wants to stretch
|
||||
//let's see if it can really stretch
|
||||
|
||||
int final_pixel_size = stretch_avail * c->get_stretch_ratio() / stretch_ratio_total;
|
||||
if (final_pixel_size < msc.min_size) {
|
||||
//if available stretching area is too small for widget,
|
||||
//then remove it from stretching area
|
||||
msc.will_stretch = false;
|
||||
stretch_ratio_total -= c->get_stretch_ratio();
|
||||
refit_successful = false;
|
||||
stretch_avail -= msc.min_size;
|
||||
msc.final_size = msc.min_size;
|
||||
break;
|
||||
} else {
|
||||
msc.final_size = final_pixel_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (refit_successful) { //uf refit went well, break
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Final pass, draw and stretch elements **/
|
||||
|
||||
int ofs = sb->get_margin(MARGIN_TOP);
|
||||
|
||||
first = true;
|
||||
int idx = 0;
|
||||
cache_y.clear();
|
||||
int w = new_size.width - sb->get_minimum_size().x;
|
||||
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
if (!c || !c->is_visible_in_tree()) {
|
||||
continue;
|
||||
}
|
||||
if (c->is_set_as_toplevel()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_MinSizeCache &msc = min_size_cache[c];
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
minsize.y += sep;
|
||||
}
|
||||
}
|
||||
|
||||
int vofs = 0;
|
||||
int w = get_size().x - sb->get_minimum_size().x;
|
||||
|
||||
cache_y.clear();
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
if (c->is_set_as_toplevel()) {
|
||||
continue;
|
||||
ofs += sep;
|
||||
}
|
||||
|
||||
Size2i size = c->get_combined_minimum_size();
|
||||
int from = ofs;
|
||||
int to = ofs + msc.final_size;
|
||||
|
||||
Rect2 r(sb->get_margin(MARGIN_LEFT), sb->get_margin(MARGIN_TOP) + vofs, w, size.y);
|
||||
if (msc.will_stretch && idx == children_count - 1) {
|
||||
//adjust so the last one always fits perfect
|
||||
//compensating for numerical imprecision
|
||||
|
||||
fit_child_in_rect(c, r);
|
||||
cache_y.push_back(vofs + size.y * 0.5);
|
||||
to = new_size.height - sb->get_margin(MARGIN_BOTTOM);
|
||||
}
|
||||
|
||||
vofs += size.y + sep;
|
||||
int size = to - from;
|
||||
|
||||
Rect2 rect(sb->get_margin(MARGIN_LEFT), from, w, size);
|
||||
|
||||
fit_child_in_rect(c, rect);
|
||||
cache_y.push_back(from - sb->get_margin(MARGIN_TOP) + size * 0.5);
|
||||
|
||||
ofs = to;
|
||||
idx++;
|
||||
}
|
||||
|
||||
update();
|
||||
|
|
|
@ -166,9 +166,11 @@ void TextureButton::_notification(int p_what) {
|
|||
} break;
|
||||
}
|
||||
|
||||
Point2 ofs;
|
||||
Size2 size;
|
||||
|
||||
if (texdraw.is_valid()) {
|
||||
Point2 ofs;
|
||||
Size2 size = texdraw->get_size();
|
||||
size = texdraw->get_size();
|
||||
_texture_region = Rect2(Point2(), texdraw->get_size());
|
||||
_tile = false;
|
||||
if (expand) {
|
||||
|
@ -218,17 +220,21 @@ void TextureButton::_notification(int p_what) {
|
|||
}
|
||||
|
||||
_position_rect = Rect2(ofs, size);
|
||||
|
||||
size.width *= hflip ? -1.0f : 1.0f;
|
||||
size.height *= vflip ? -1.0f : 1.0f;
|
||||
|
||||
if (_tile) {
|
||||
draw_texture_rect(texdraw, _position_rect, _tile);
|
||||
draw_texture_rect(texdraw, Rect2(ofs, size), _tile);
|
||||
} else {
|
||||
draw_texture_rect_region(texdraw, _position_rect, _texture_region);
|
||||
draw_texture_rect_region(texdraw, Rect2(ofs, size), _texture_region);
|
||||
}
|
||||
} else {
|
||||
_position_rect = Rect2();
|
||||
}
|
||||
|
||||
if (has_focus() && focused.is_valid()) {
|
||||
draw_texture_rect(focused, _position_rect, false);
|
||||
draw_texture_rect(focused, Rect2(ofs, size), false);
|
||||
};
|
||||
} break;
|
||||
}
|
||||
|
@ -243,6 +249,10 @@ void TextureButton::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_click_mask", "mask"), &TextureButton::set_click_mask);
|
||||
ClassDB::bind_method(D_METHOD("set_expand", "p_expand"), &TextureButton::set_expand);
|
||||
ClassDB::bind_method(D_METHOD("set_stretch_mode", "p_mode"), &TextureButton::set_stretch_mode);
|
||||
ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureButton::set_flip_h);
|
||||
ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureButton::is_flipped_h);
|
||||
ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureButton::set_flip_v);
|
||||
ClassDB::bind_method(D_METHOD("is_flipped_v"), &TextureButton::is_flipped_v);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_normal_texture"), &TextureButton::get_normal_texture);
|
||||
ClassDB::bind_method(D_METHOD("get_pressed_texture"), &TextureButton::get_pressed_texture);
|
||||
|
@ -262,6 +272,8 @@ void TextureButton::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_click_mask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_click_mask", "get_click_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand", PROPERTY_HINT_RESOURCE_TYPE, "bool"), "set_expand", "get_expand");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h", PROPERTY_HINT_RESOURCE_TYPE, "bool"), "set_flip_h", "is_flipped_h");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v", PROPERTY_HINT_RESOURCE_TYPE, "bool"), "set_flip_v", "is_flipped_v");
|
||||
|
||||
BIND_ENUM_CONSTANT(STRETCH_SCALE);
|
||||
BIND_ENUM_CONSTANT(STRETCH_TILE);
|
||||
|
@ -338,9 +350,29 @@ TextureButton::StretchMode TextureButton::get_stretch_mode() const {
|
|||
return stretch_mode;
|
||||
}
|
||||
|
||||
void TextureButton::set_flip_h(bool p_flip) {
|
||||
hflip = p_flip;
|
||||
update();
|
||||
}
|
||||
|
||||
bool TextureButton::is_flipped_h() const {
|
||||
return hflip;
|
||||
}
|
||||
|
||||
void TextureButton::set_flip_v(bool p_flip) {
|
||||
vflip = p_flip;
|
||||
update();
|
||||
}
|
||||
|
||||
bool TextureButton::is_flipped_v() const {
|
||||
return vflip;
|
||||
}
|
||||
|
||||
TextureButton::TextureButton() {
|
||||
expand = false;
|
||||
stretch_mode = STRETCH_SCALE;
|
||||
hflip = false;
|
||||
vflip = false;
|
||||
|
||||
_texture_region = Rect2();
|
||||
_position_rect = Rect2();
|
||||
|
|
|
@ -61,6 +61,9 @@ private:
|
|||
Rect2 _position_rect;
|
||||
bool _tile;
|
||||
|
||||
bool hflip;
|
||||
bool vflip;
|
||||
|
||||
protected:
|
||||
virtual Size2 get_minimum_size() const;
|
||||
virtual bool has_point(const Point2 &p_point) const;
|
||||
|
@ -88,6 +91,12 @@ public:
|
|||
void set_stretch_mode(StretchMode p_stretch_mode);
|
||||
StretchMode get_stretch_mode() const;
|
||||
|
||||
void set_flip_h(bool p_flip);
|
||||
bool is_flipped_h() const;
|
||||
|
||||
void set_flip_v(bool p_flip);
|
||||
bool is_flipped_v() const;
|
||||
|
||||
TextureButton();
|
||||
};
|
||||
|
||||
|
|
|
@ -322,17 +322,19 @@ bool HTTPRequest::_update_connection() {
|
|||
}
|
||||
|
||||
PoolByteArray chunk = client->read_response_body_chunk();
|
||||
downloaded.add(chunk.size());
|
||||
|
||||
if (file) {
|
||||
PoolByteArray::Read r = chunk.read();
|
||||
file->store_buffer(r.ptr(), chunk.size());
|
||||
if (file->get_error() != OK) {
|
||||
call_deferred("_request_done", RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PoolByteArray());
|
||||
return true;
|
||||
if (chunk.size()) {
|
||||
downloaded.add(chunk.size());
|
||||
if (file) {
|
||||
PoolByteArray::Read r = chunk.read();
|
||||
file->store_buffer(r.ptr(), chunk.size());
|
||||
if (file->get_error() != OK) {
|
||||
call_deferred("_request_done", RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PoolByteArray());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
body.append_array(chunk);
|
||||
}
|
||||
} else {
|
||||
body.append_array(chunk);
|
||||
}
|
||||
|
||||
if (body_size_limit >= 0 && downloaded.get() > body_size_limit) {
|
||||
|
|
|
@ -65,17 +65,19 @@ void BodySW::update_inertias() {
|
|||
// We have to recompute the center of mass.
|
||||
center_of_mass_local.zero();
|
||||
|
||||
for (int i = 0; i < get_shape_count(); i++) {
|
||||
real_t area = get_shape_area(i);
|
||||
if (total_area != 0.0) {
|
||||
for (int i = 0; i < get_shape_count(); i++) {
|
||||
real_t area = get_shape_area(i);
|
||||
|
||||
real_t mass = area * this->mass / total_area;
|
||||
real_t mass = area * this->mass / total_area;
|
||||
|
||||
// NOTE: we assume that the shape origin is also its center of mass.
|
||||
center_of_mass_local += mass * get_shape_transform(i).origin;
|
||||
// NOTE: we assume that the shape origin is also its center of mass.
|
||||
center_of_mass_local += mass * get_shape_transform(i).origin;
|
||||
}
|
||||
|
||||
center_of_mass_local /= mass;
|
||||
}
|
||||
|
||||
center_of_mass_local /= mass;
|
||||
|
||||
// Recompute the inertia tensor.
|
||||
Basis inertia_tensor;
|
||||
inertia_tensor.set_zero();
|
||||
|
@ -86,12 +88,15 @@ void BodySW::update_inertias() {
|
|||
continue;
|
||||
}
|
||||
|
||||
real_t area = get_shape_area(i);
|
||||
if (area == 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inertia_set = true;
|
||||
|
||||
const ShapeSW *shape = get_shape(i);
|
||||
|
||||
real_t area = get_shape_area(i);
|
||||
|
||||
real_t mass = area * this->mass / total_area;
|
||||
|
||||
Basis shape_inertia_tensor = shape->get_moment_of_inertia(mass).to_diagonal_matrix();
|
||||
|
|
Loading…
Reference in New Issue