diff options
-rw-r--r-- | core/bind/core_bind.cpp | 75 | ||||
-rw-r--r-- | core/bind/core_bind.h | 1 | ||||
-rw-r--r-- | doc/base/classes.xml | 6 | ||||
-rw-r--r-- | scene/animation/animation_tree_player.cpp | 9 | ||||
-rw-r--r-- | scene/gui/control.cpp | 35 | ||||
-rw-r--r-- | scene/gui/control.h | 4 | ||||
-rw-r--r-- | servers/physics_2d/shape_2d_sw.cpp | 20 |
7 files changed, 124 insertions, 26 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 9d380aa33a..d67b93603c 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -6,6 +6,15 @@ #include "core/globals.h" #include "io/file_access_encrypted.h" #include "os/keyboard.h" + +/** + * Time constants borrowed from loc_time.h + */ +#define EPOCH_YR 1970 /* EPOCH = Jan 1 1970 00:00:00 */ +#define SECS_DAY (24L * 60L * 60L) +#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400))) +#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) + _ResourceLoader *_ResourceLoader::singleton=NULL; Ref<ResourceInteractiveLoader> _ResourceLoader::load_interactive(const String& p_path,const String& p_type_hint) { @@ -479,9 +488,8 @@ Dictionary _OS::get_date(bool utc) const { dated["weekday"]=date.weekday; dated["dst"]=date.dst; return dated; - - } + Dictionary _OS::get_time(bool utc) const { OS::Time time = OS::get_singleton()->get_time(utc); @@ -490,7 +498,67 @@ Dictionary _OS::get_time(bool utc) const { timed["minute"]=time.min; timed["second"]=time.sec; return timed; +} + +/** + * Get a dictionary of time values when given epoc time + * + * Dictionary Time values will be a union if values from #get_time + * and #get_date dictionaries (with the exception of dst = + * day light standard time, as it cannot be determined from epoc) + */ +Dictionary _OS::get_time_from_unix_time( uint64_t unix_time_val) const { + + OS::Date date; + OS::Time time; + + unsigned long dayclock, dayno; + int year = EPOCH_YR; + + dayclock = (unsigned long)unix_time_val % SECS_DAY; + dayno = (unsigned long)unix_time_val / SECS_DAY; + + time.sec = dayclock % 60; + time.min = (dayclock % 3600) / 60; + time.hour = dayclock / 3600; + + /* day 0 was a thursday */ + date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7); + + while (dayno >= YEARSIZE(year)) { + dayno -= YEARSIZE(year); + year++; + } + date.year = year; + + // Table of number of days in each month (for regular year and leap year) + const unsigned int _ytab[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + }; + + size_t imonth = 0; + + while (dayno >= _ytab[LEAPYEAR(year)][imonth]) { + dayno -= _ytab[LEAPYEAR(year)][imonth]; + imonth++; + } + + date.month = static_cast<OS::Month>(imonth); + + date.day = dayno + 1; + + Dictionary timed; + timed["hour"]=time.hour; + timed["minute"]=time.min; + timed["second"]=time.sec; + timed["year"]=date.year; + timed["month"]=date.month; + timed["day"]=date.day; + timed["weekday"]=date.weekday; + + return timed; } Dictionary _OS::get_time_zone_info() const { @@ -837,6 +905,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_time","utc"),&_OS::get_time,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_time_zone_info"),&_OS::get_time_zone_info); ObjectTypeDB::bind_method(_MD("get_unix_time"),&_OS::get_unix_time); + ObjectTypeDB::bind_method(_MD("get_time_from_unix_time", "unix_time_val"), + &_OS::get_time_from_unix_time); ObjectTypeDB::bind_method(_MD("get_system_time_secs"), &_OS::get_system_time_secs); ObjectTypeDB::bind_method(_MD("set_icon","icon"),&_OS::set_icon); @@ -1995,7 +2065,6 @@ String _Thread::get_id() const { return itos(thread->get_ID()); } - bool _Thread::is_active() const { return active; diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 64a4e94aec..7b3494ebc1 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -208,6 +208,7 @@ public: void set_icon(const Image& p_icon); Dictionary get_date(bool utc) const; Dictionary get_time(bool utc) const; + Dictionary get_time_from_unix_time(uint64_t unix_time_val) const; Dictionary get_time_zone_info() const; uint64_t get_unix_time() const; uint64_t get_system_time_secs() const; diff --git a/doc/base/classes.xml b/doc/base/classes.xml index d111569a60..04e08f166e 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -8385,8 +8385,12 @@ </argument> <argument index="1" name="anchor_mode" type="int"> </argument> + <argument index="2" name="keep_margin" type="bool" default="false"> + </argument> <description> - Change the anchor (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) type for a margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Changing the anchor mode converts the current margin offset from the previous anchor mode to the new one, so margin offsets ([method set_margin]) must be done after setting anchors, or at the same time ([method set_anchor_and_margin]). + Change the anchor (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) type for a margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Changing the anchor mode converts the current margin offset from the previous anchor mode to the new one, so margin offsets ([method set_margin]) must be done after setting anchors, or at the same time ([method set_anchor_and_margin]) + + Additionally, [code]keep_margin[/code] controls whether margins should be left the same, or changed to keep the same position and size on-screen. </description> </method> <method name="get_anchor" qualifiers="const"> diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index cc9e6c71e3..9dcad8a533 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -637,10 +637,15 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode } break; case NODE_TIMESCALE: { TimeScaleNode *tsn = static_cast<TimeScaleNode*>(nb); + float rem; if (p_seek) - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight); + rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight); + else + rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight); + if (tsn->scale == 0) + return INFINITY; else - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight); + return rem / tsn->scale; } break; case NODE_TIMESEEK: { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 295ec03702..0364f73275 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -39,6 +39,9 @@ #include "scene/scene_string_names.h" #include "scene/gui/panel.h" #include "scene/gui/label.h" +#ifdef TOOLS_ENABLED +#include "tools/editor/editor_settings.h" +#endif #include <stdio.h> @@ -1153,20 +1156,31 @@ float Control::_a2s(float p_val, AnchorType p_anchor,float p_range) const { } -void Control::set_anchor(Margin p_margin,AnchorType p_anchor) { +void Control::set_anchor(Margin p_margin,AnchorType p_anchor, bool p_keep_margin) { if (!is_inside_tree()) { - data.anchor[p_margin]=p_anchor; - } else { + data.anchor[p_margin] = p_anchor; + } else if(!p_keep_margin) { float pr = _get_parent_range(p_margin); float s = _a2s( data.margin[p_margin], data.anchor[p_margin], pr ); - data.anchor[p_margin]=p_anchor; + data.anchor[p_margin] = p_anchor; data.margin[p_margin] = _s2a( s, p_anchor, pr ); + } else { + data.anchor[p_margin] = p_anchor; + _size_changed(); } _change_notify(); } +void Control::_set_anchor(Margin p_margin,AnchorType p_anchor) { + #ifdef TOOLS_ENABLED + set_anchor(p_margin, p_anchor, EDITOR_DEF("2d_editor/keep_margins_when_changing_anchors", false)); + #else + set_anchor(p_margin, p_anchor); + #endif +} + void Control::set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p_pos) { set_anchor(p_margin,p_anchor); @@ -2090,7 +2104,8 @@ void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("accept_event"),&Control::accept_event); ObjectTypeDB::bind_method(_MD("get_minimum_size"),&Control::get_minimum_size); ObjectTypeDB::bind_method(_MD("get_combined_minimum_size"),&Control::get_combined_minimum_size); - ObjectTypeDB::bind_method(_MD("set_anchor","margin","anchor_mode"),&Control::set_anchor); + ObjectTypeDB::bind_method(_MD("set_anchor","margin","anchor_mode","keep_margin"),&Control::set_anchor,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("_set_anchor","margin","anchor_mode"),&Control::_set_anchor); ObjectTypeDB::bind_method(_MD("get_anchor","margin"),&Control::get_anchor); ObjectTypeDB::bind_method(_MD("set_margin","margin","offset"),&Control::set_margin); ObjectTypeDB::bind_method(_MD("set_anchor_and_margin","margin","anchor_mode","offset"),&Control::set_anchor_and_margin); @@ -2184,10 +2199,10 @@ void Control::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::BOOL,"can_drop_data",PropertyInfo(Variant::VECTOR2,"pos"),PropertyInfo(Variant::NIL,"data"))); BIND_VMETHOD(MethodInfo("drop_data",PropertyInfo(Variant::VECTOR2,"pos"),PropertyInfo(Variant::NIL,"data"))); - ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/left", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_LEFT ); - ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/top", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_TOP ); - ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/right", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_RIGHT ); - ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/bottom", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_BOTTOM ); + ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/left", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_LEFT ); + ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/top", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_TOP ); + ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/right", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_RIGHT ); + ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/bottom", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_BOTTOM ); ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"margin/left", PROPERTY_HINT_RANGE, "-4096,4096"), _SCS("set_margin"),_SCS("get_margin"), MARGIN_LEFT ); ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"margin/top", PROPERTY_HINT_RANGE, "-4096,4096"), _SCS("set_margin"),_SCS("get_margin"), MARGIN_TOP ); @@ -2304,5 +2319,3 @@ Control::Control() { Control::~Control() { } - - diff --git a/scene/gui/control.h b/scene/gui/control.h index 851d8316fb..1e2db7a575 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -162,6 +162,8 @@ private: Control *_get_focus_neighbour(Margin p_margin,int p_count=0); + void _set_anchor(Margin p_margin,AnchorType p_anchor); + float _get_parent_range(int p_idx) const; float _get_range(int p_idx) const; float _s2a(float p_val, AnchorType p_anchor,float p_range) const; @@ -244,7 +246,7 @@ public: /* POSITIONING */ - void set_anchor(Margin p_margin,AnchorType p_anchor); + void set_anchor(Margin p_margin,AnchorType p_anchor, bool p_keep_margin=false); void set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p_pos); AnchorType get_anchor(Margin p_margin) const; diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index bd36f4060b..8b583dd3c6 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -968,19 +968,25 @@ void ConcavePolygonShape2DSW::set_data(const Variant& p_data) { ERR_FAIL_COND(p_data.get_type()!=Variant::VECTOR2_ARRAY && p_data.get_type()!=Variant::REAL_ARRAY); - segments.clear();; - points.clear();; - bvh.clear();; - bvh_depth=1; - Rect2 aabb; if (p_data.get_type()==Variant::VECTOR2_ARRAY) { DVector<Vector2> p2arr = p_data; int len = p2arr.size(); - DVector<Vector2>::Read arr = p2arr.read(); + ERR_FAIL_COND(len%2); + segments.clear(); + points.clear(); + bvh.clear(); + bvh_depth=1; + + if (len==0) { + configure(aabb); + return; + } + + DVector<Vector2>::Read arr = p2arr.read(); Map<Point2,int> pointmap; for(int i=0;i<len;i+=2) { @@ -988,8 +994,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant& p_data) { Point2 p1 =arr[i]; Point2 p2 =arr[i+1]; int idx_p1,idx_p2; - if (p1==p2) - continue; //don't want it if (pointmap.has(p1)) { idx_p1=pointmap[p1]; |