diff options
31 files changed, 780 insertions, 243 deletions
diff --git a/.travis.yml b/.travis.yml index 6dd21dae0b..13f91b99e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,48 @@ language: cpp -compiler: + +sudo: required +dist: trusty + +compiler: - gcc -before_install: - - -before_script: - - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - - sudo apt-get update -qq - - sudo apt-get install -qq scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev - - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.8; fi - - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi - -script: scons platform=x11 + - clang + +os: + - linux + - osx + +env: + - GODOT_TARGET=iphone + - GODOT_TARGET=osx + - GODOT_TARGET=x11 + - GODOT_TARGET=android + - GODOT_TARGET=windows + +matrix: + exclude: + - os: linux + env: GODOT_TARGET=iphone + - os: linux + env: GODOT_TARGET=osx + - os: linux + env: GODOT_TARGET=android + - os: osx + env: GODOT_TARGET=x11 + - os: osx + env: GODOT_TARGET=windows + - compiler: gcc + env: GODOT_TARGET=iphone + - compiler: clang + env: GODOT_TARGET=android + - compiler: clang + env: GODOT_TARGET=windows + + +before_script: + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq; sudo apt-get install -y scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev libssl-dev libxinerama-dev libevdev-dev libudev-dev; fi + - if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$GODOT_TARGET" = "windows" ]; then sudo apt-get update -qq; sudo apt-get install -y mingw32 mingw-w64; fi + - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi + - if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then brew update; brew install android-sdk android-ndk; export ANDROID_HOME=/usr/local/opt/android-sdk; export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk; fi + +script: + - scons platform=$GODOT_TARGET CXX=$CXX diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 39b3791e84..075f97c68e 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -2412,7 +2412,7 @@ </class> <class name="AnimationPlayer" inherits="Node" category="Core"> <brief_description> - Container and player of [Animaton] resources. + Container and player of [Animation] resources. </brief_description> <description> An animation player is used for general purpose playback of [Animation] resources. It contains a dictionary of animations (referenced by name) and custom blend times between their transitions. Additionally, animations can be played and blended in diferent channels. @@ -3257,6 +3257,12 @@ <argument index="0" name="enable" type="int"> </argument> <description> + Set the space override mode. This mode controls how an area affects gravity and damp. + AREA_SPACE_OVERRIDE_DISABLED: This area does not affect gravity/damp. These are generally areas that exist only to detect collisions, and objects entering or exiting them. + AREA_SPACE_OVERRIDE_COMBINE: This area adds its gravity/damp values to whatever has been calculated so far. This way, many overlapping areas can combine their physics to make interesting effects. + AREA_SPACE_OVERRIDE_COMBINE_REPLACE: This area adds its gravity/damp values to whatever has been calculated so far. Then stops taking into account the rest of the areas, even the default one. + AREA_SPACE_OVERRIDE_REPLACE: This area replaces any gravity/damp, even the default one, and stops taking into account the rest of the areas. + AREA_SPACE_OVERRIDE_REPLACE_COMBINE: This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one. </description> </method> <method name="get_space_override_mode" qualifiers="const"> @@ -3481,133 +3487,162 @@ </class> <class name="Area2D" inherits="CollisionObject2D" category="Core"> <brief_description> - General purpose area detection and influence for 2D Phisics. + General purpose area detection and influence for 2D physics. </brief_description> <description> - General purpose area detection for 2D Phisics. Areas can be used for detection of objects that enter/exit them, as well as overriding space parameters (changing gravity, damping, etc). An Area2D can be set as a children to a RigidBody2D to generate a custom gravity field. For this, use SPACE_OVERRIDE_COMBINE and point gravity at the center of mass. + General purpose area detection for 2D physics. Areas can be used for detection of objects that enter/exit them, as well as overriding space parameters (changing gravity, damping, etc). For this, use any space override different from AREA_SPACE_OVERRIDE_DISABLE and point gravity at the center of mass. </description> <methods> <method name="set_space_override_mode"> <argument index="0" name="enable" type="int"> </argument> <description> + Set the space override mode. This mode controls how an area affects gravity and damp. + AREA_SPACE_OVERRIDE_DISABLED: This area does not affect gravity/damp. These are generally areas that exist only to detect collisions, and objects entering or exiting them. + AREA_SPACE_OVERRIDE_COMBINE: This area adds its gravity/damp values to whatever has been calculated so far. This way, many overlapping areas can combine their physics to make interesting effects. + AREA_SPACE_OVERRIDE_COMBINE_REPLACE: This area adds its gravity/damp values to whatever has been calculated so far. Then stops taking into account the rest of the areas, even the default one. + AREA_SPACE_OVERRIDE_REPLACE: This area replaces any gravity/damp, even the default one, and stops taking into account the rest of the areas. + AREA_SPACE_OVERRIDE_REPLACE_COMBINE: This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one. </description> </method> <method name="get_space_override_mode" qualifiers="const"> <return type="int"> </return> <description> + Return the space override mode. </description> </method> <method name="set_gravity_is_point"> <argument index="0" name="enable" type="bool"> </argument> <description> - When overriding space parameters, areas can have a center of gravity as a point. + When overriding space parameters, this method sets whether this area has a center of gravity. To set/get the location of the center of gravity, use [method set_gravity_vector]/[method get_gravity_vector]. </description> </method> <method name="is_gravity_a_point" qualifiers="const"> <return type="bool"> </return> <description> - Return if gravity is a point. When overriding space parameters, areas can have a center of gravity as a point. + Return whether gravity is a point. A point gravity will attract objects towards it, as opposed to a gravity vector, which moves them in a given direction. </description> </method> <method name="set_gravity_distance_scale"> <argument index="0" name="distance_scale" type="float"> </argument> <description> + Set the falloff factor for point gravity. The greater this value is, the faster the strength of gravity decreases with the square of distance. </description> </method> <method name="get_gravity_distance_scale" qualifiers="const"> <return type="float"> </return> <description> + Return the falloff factor for point gravity. </description> </method> <method name="set_gravity_vector"> <argument index="0" name="vector" type="Vector2"> </argument> <description> - Set gravity vector. If gravity is a point, this will be the attraction center. + Set the gravity vector. This vector does not have to be normalized. + If gravity is a point (see [method is_gravity_a_point]), this will be the attraction center. </description> </method> <method name="get_gravity_vector" qualifiers="const"> <return type="Vector2"> </return> <description> + Return the gravity vector. If gravity is a point (see [method is_gravity_a_point]), this will be the attraction center. </description> </method> <method name="set_gravity"> <argument index="0" name="gravity" type="float"> </argument> <description> + Set the gravity intensity. This is useful to alter the force of gravity without altering its direction. + This value multiplies the gravity vector, whether it is the given vector ([method set_gravity_vector]), or a calculated one (when using a center of gravity). </description> </method> <method name="get_gravity" qualifiers="const"> <return type="float"> </return> <description> + Return the gravity intensity. </description> </method> <method name="set_linear_damp"> <argument index="0" name="linear_damp" type="float"> </argument> <description> + Set the rate at which objects stop moving in this area, if there are not any other forces moving it. The value is a fraction of its current speed, lost per second. Thus, a value of 1.0 should mean stopping immediately, and 0.0 means the object never stops. + In practice, as the fraction of speed lost gets smaller with each frame, a value of 1.0 does not mean the object will stop in exactly one second. Only when the physics calculations are done at 1 frame per second, it does stop in a second. </description> </method> <method name="get_linear_damp" qualifiers="const"> <return type="float"> </return> <description> + Return the linear damp rate. </description> </method> <method name="set_angular_damp"> <argument index="0" name="angular_damp" type="float"> </argument> <description> + Set the rate at which objects stop spinning in this area, if there are not any other forces making it spin. The value is a fraction of its current speed, lost per second. Thus, a value of 1.0 should mean stopping immediately, and 0.0 means the object never stops. + In practice, as the fraction of speed lost gets smaller with each frame, a value of 1.0 does not mean the object will stop in exactly one second. Only when the physics calculations are done at 1 frame per second, it does stop in a second. </description> </method> <method name="get_angular_damp" qualifiers="const"> <return type="float"> </return> <description> + Return the angular damp rate. </description> </method> <method name="set_priority"> <argument index="0" name="priority" type="float"> </argument> <description> + Set the order in which the area is processed. Greater values mean the area gets processed first. This is useful for areas which have an space override different from AREA_SPACE_OVERRIDE_DISABLED or AREA_SPACE_OVERRIDE_COMBINE, as they replace values, and are thus order-dependent. + Areas with the same priority value get evaluated in an unpredictable order, and should be differentiated if evaluation order is to be important. </description> </method> <method name="get_priority" qualifiers="const"> <return type="float"> </return> <description> + Return the processing order of this area. </description> </method> <method name="set_collision_mask"> <argument index="0" name="collision_mask" type="int"> </argument> <description> + Set the physics layers this area can scan for collisions. </description> </method> <method name="get_collision_mask" qualifiers="const"> <return type="int"> </return> <description> + Return the physics layers this area can scan for collisions. </description> </method> <method name="set_layer_mask"> <argument index="0" name="layer_mask" type="int"> </argument> <description> + Set the physics layers this area is in. + Collidable objects can exist in any of 32 different layers. These layers are not visual, but more of a tagging system instead. A collidable can use these layers/tags to select with which objects it can collide, using [method set_collision_mask]. + A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. </description> </method> <method name="get_layer_mask" qualifiers="const"> <return type="int"> </return> <description> + Return the physics layer this area is in. </description> </method> <method name="set_collision_mask_bit"> @@ -3616,6 +3651,7 @@ <argument index="1" name="value" type="bool"> </argument> <description> + Set/clear individual bits on the collision mask. This makes selecting the areas scanned easier. </description> </method> <method name="get_collision_mask_bit" qualifiers="const"> @@ -3624,6 +3660,7 @@ <argument index="0" name="bit" type="int"> </argument> <description> + Return an individual bit on the collision mask. </description> </method> <method name="set_layer_mask_bit"> @@ -3632,6 +3669,7 @@ <argument index="1" name="value" type="bool"> </argument> <description> + Set/clear individual bits on the layer mask. This makes getting an area in/out of only one layer easier. </description> </method> <method name="get_layer_mask_bit" qualifiers="const"> @@ -3640,58 +3678,67 @@ <argument index="0" name="bit" type="int"> </argument> <description> + Return an individual bit on the layer mask. </description> </method> <method name="set_enable_monitoring"> <argument index="0" name="enable" type="bool"> </argument> <description> + Set whether this area can detect bodies/areas entering/exiting it. </description> </method> <method name="is_monitoring_enabled" qualifiers="const"> <return type="bool"> </return> <description> + Return whether this area detects bodies/areas entering/exiting it. </description> </method> <method name="set_monitorable"> <argument index="0" name="enable" type="bool"> </argument> <description> + Set whether this area can be detected by other, monitoring, areas. Only areas need to be marked as monitorable. Bodies are always so. </description> </method> <method name="is_monitorable" qualifiers="const"> <return type="bool"> </return> <description> + Set whether this area can be detected by other, monitoring, areas. </description> </method> <method name="get_overlapping_bodies" qualifiers="const"> <return type="Array"> </return> <description> + Return a list of the bodies ([PhysicsBody2D]) that are totally or partially inside this area. </description> </method> <method name="get_overlapping_areas" qualifiers="const"> <return type="Array"> </return> <description> + Return a list of the areas that are totally or partially inside this area. </description> </method> <method name="overlaps_body" qualifiers="const"> - <return type="PhysicsBody2D"> + <return type="bool"> </return> <argument index="0" name="body" type="Object"> </argument> <description> + Return whether the body passed is totally or partially inside this area. </description> </method> <method name="overlaps_area" qualifiers="const"> - <return type="Area2D"> + <return type="bool"> </return> <argument index="0" name="area" type="Object"> </argument> <description> + Return whether the area passed is totally or partially inside this area. </description> </method> </methods> @@ -3700,6 +3747,7 @@ <argument index="0" name="body" type="Object"> </argument> <description> + This signal is triggered only once when a body enters this area. The only parameter passed is the body that entered this area. </description> </signal> <signal name="body_enter_shape"> @@ -3712,12 +3760,14 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> + This signal triggers only once when a body enters this area. The first parameter is the body's [RID]. The second one is the body as an object. The third one is the index of the shape of the body that entered this area, and the fourth one is the index of the shape in this area that repored the entering. </description> </signal> <signal name="area_enter"> <argument index="0" name="area" type="Object"> </argument> <description> + This signal is triggered only once when an area enters this area. The only parameter passed is the area that entered this area. </description> </signal> <signal name="area_enter_shape"> @@ -3730,12 +3780,14 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> + This signal triggers only once when an area enters this area. The first parameter is the area's [RID]. The second one is the area as an object. The third one is the index of the shape entering this area, and the fourth one is the index of the shape in this area that reported the entering. </description> </signal> <signal name="body_exit"> <argument index="0" name="body" type="Object"> </argument> <description> + This signal is triggered only once when a body exits this area. The only parameter passed is the body that exited this area. </description> </signal> <signal name="body_exit_shape"> @@ -3748,12 +3800,14 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> + This signal triggers only once when a body exits this area. The first parameter is the body's [RID]. The second one is the body as an object. The third one is the index of the shape exiting this area, and the fourth one is the index of the shape in this area that reported the exit. </description> </signal> <signal name="area_exit"> <argument index="0" name="area" type="Object"> </argument> <description> + This signal is triggered only once when an area exits this area. The only parameter passed is the area that exited this area. </description> </signal> <signal name="area_exit_shape"> @@ -3766,6 +3820,7 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> + This signal triggers only once when an area exits this area. The first parameter is the area's [RID]. The second one is the area as an object. The third one is the index of the shape entering this area, and the fourth one is the index of the shape in this area that reported the entering. </description> </signal> </signals> @@ -6969,7 +7024,7 @@ Base node for 2D collisionables. </brief_description> <description> - CollisionObject2D is the base class for 2D physics collisionables. They can hold any number of 2D collision shapes. Usually, they are edited by placing [CollisionBody2D] and [CollisionPolygon2D] nodes as children. Such nodes are for reference and not present outside the editor, so code should use the regular shape API. + CollisionObject2D is the base class for 2D physics collisionables. They can hold any number of 2D collision shapes. Usually, they are edited by placing [CollisionShape2D] and/or [CollisionPolygon2D] nodes as children. Such nodes are for reference and not present outside the editor, so code should use the regular shape API. </description> <methods> <method name="_input_event" qualifiers="virtual"> @@ -6980,6 +7035,7 @@ <argument index="2" name="shape_idx" type="int"> </argument> <description> + This method can be used to override normal input processing. The first parameter is the viewport where the event took place. The second holds the input event received, and the third the shape of this object where it happened. </description> </method> <method name="add_shape"> @@ -6995,7 +7051,7 @@ <return type="int"> </return> <description> - Return the amount of shapes in the collision body. + Return the amount of shapes in the collision body. Because a [CollisionPolygon2D] can generate more than one [Shape2D], the amount returned does not have to match the sum of [CollisionShape2D] and [CollisionPolygon2D]. </description> </method> <method name="set_shape"> @@ -7004,7 +7060,7 @@ <argument index="1" name="shape" type="Shape"> </argument> <description> - Change a shape in the collision body. + Change a shape in the collision body. </description> </method> <method name="set_shape_transform"> @@ -7022,6 +7078,7 @@ <argument index="1" name="enable" type="bool"> </argument> <description> + Set whether a shape is a trigger. A trigger shape detects collisions, but is otherwise unaffected by physics (i.e. colliding objects will not get blocked). </description> </method> <method name="get_shape" qualifiers="const"> @@ -7048,6 +7105,7 @@ <argument index="0" name="shape_idx" type="int"> </argument> <description> + Return whether a shape is a trigger. A trigger shape detects collisions, but is otherwise unaffected by physics (i.e. colliding objects will not get blocked). </description> </method> <method name="remove_shape"> @@ -7066,25 +7124,28 @@ <return type="RID"> </return> <description> - Return the RID of the object. + Return the RID of this object. </description> </method> <method name="set_pickable"> <argument index="0" name="enabled" type="bool"> </argument> <description> + Set whether this object is pickable. A pickable object can detect the mouse pointer enter/leave it and, if the mouse is inside it, report input events. </description> </method> <method name="is_pickable" qualifiers="const"> <return type="bool"> </return> <description> + Return whether this object is pickable. </description> </method> </methods> <signals> <signal name="mouse_enter"> <description> + This event fires only once when the mouse pointer enters any shape of this object. </description> </signal> <signal name="input_event"> @@ -7095,10 +7156,12 @@ <argument index="2" name="shape_idx" type="int"> </argument> <description> + This signal triggers when an input event fires over a shape. The first parameter is the viewport where the event took place. The second holds the input event received, and the third the shape of this object where it happened. </description> </signal> <signal name="mouse_exit"> <description> + This event fires only once when the mouse pointer exits all shapes of this object. </description> </signal> </signals> @@ -23030,10 +23093,19 @@ This method controls whether the position between two cached points is interpola <constant name="AREA_PARAM_PRIORITY" value="7"> </constant> <constant name="AREA_SPACE_OVERRIDE_COMBINE" value="1"> + This area adds its gravity/damp values to whatever has been calculated so far. This way, many overlapping areas can combine their physics to make interesting effects. + </constant> + <constant name="AREA_SPACE_OVERRIDE_COMBINE_REPLACE" value="2"> + This area adds its gravity/damp values to whatever has been calculated so far. Then stops taking into account the rest of the areas, even the default one. </constant> <constant name="AREA_SPACE_OVERRIDE_DISABLED" value="0"> + This area does not affect gravity/damp. These are generally areas that exist only to detect collisions, and objects entering or exiting them. </constant> - <constant name="AREA_SPACE_OVERRIDE_REPLACE" value="2"> + <constant name="AREA_SPACE_OVERRIDE_REPLACE" value="3"> + This area replaces any gravity/damp, even the default one, and stops taking into account the rest of the areas. + </constant> + <constant name="AREA_SPACE_OVERRIDE_REPLACE_COMBINE" value="4"> + This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one. </constant> <constant name="BODY_MODE_STATIC" value="0"> </constant> @@ -23321,7 +23393,7 @@ This method controls whether the position between two cached points is interpola </class> <class name="PhysicsBody" inherits="CollisionObject" category="Core"> <brief_description> - Base class for differnt types of Physics bodies. + Base class for different types of Physics bodies. </brief_description> <description> PhysicsBody is an abstract base class for implementing a physics body. All PhysicsBody types inherit from it. @@ -23357,32 +23429,40 @@ This method controls whether the position between two cached points is interpola </class> <class name="PhysicsBody2D" inherits="CollisionObject2D" category="Core"> <brief_description> + Base class for all objects affected by physics. </brief_description> <description> + PhysicsBody2D is an abstract base class for implementing a physics body. All [i]x[/i]Body2D types inherit from it. </description> <methods> <method name="set_layer_mask"> <argument index="0" name="mask" type="int"> </argument> <description> + Set the physics layers this area is in. + Collidable objects can exist in any of 32 different layers. These layers are not visual, but more of a tagging system instead. A collidable can use these layers/tags to select with which objects it can collide, using [method set_collision_mask]. + A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. </description> </method> <method name="get_layer_mask" qualifiers="const"> <return type="int"> </return> <description> + Return the physics layer this area is in. </description> </method> <method name="set_collision_mask"> <argument index="0" name="mask" type="int"> </argument> <description> + Set the physics layers this area can scan for collisions. </description> </method> <method name="get_collision_mask" qualifiers="const"> <return type="int"> </return> <description> + Return the physics layers this area can scan for collisions. </description> </method> <method name="set_collision_mask_bit"> @@ -23391,6 +23471,7 @@ This method controls whether the position between two cached points is interpola <argument index="1" name="value" type="bool"> </argument> <description> + Set/clear individual bits on the collision mask. This makes selecting the areas scanned easier. </description> </method> <method name="get_collision_mask_bit" qualifiers="const"> @@ -23399,6 +23480,7 @@ This method controls whether the position between two cached points is interpola <argument index="0" name="bit" type="int"> </argument> <description> + Return an individual bit on the collision mask. </description> </method> <method name="set_layer_mask_bit"> @@ -23407,6 +23489,7 @@ This method controls whether the position between two cached points is interpola <argument index="1" name="value" type="bool"> </argument> <description> + Set/clear individual bits on the layer mask. This makes getting a body in/out of only one layer easier. </description> </method> <method name="get_layer_mask_bit" qualifiers="const"> @@ -23415,42 +23498,49 @@ This method controls whether the position between two cached points is interpola <argument index="0" name="bit" type="int"> </argument> <description> + Return an individual bit on the collision mask. </description> </method> <method name="set_one_way_collision_direction"> <argument index="0" name="dir" type="Vector2"> </argument> <description> + Set a direction in which bodies can go through this one. If this value is different from (0,0), any movement within 90 degrees of this vector is considered a valid movement. Set this direction to (0,0) to disable one-way collisions. </description> </method> <method name="get_one_way_collision_direction" qualifiers="const"> <return type="Vector2"> </return> <description> + Return the direction used for one-way collision detection. </description> </method> <method name="set_one_way_collision_max_depth"> <argument index="0" name="depth" type="float"> </argument> <description> + Set how far a body can go through this one, when it allows one-way collisions (see [method set_one_way_collision_detection]). </description> </method> <method name="get_one_way_collision_max_depth" qualifiers="const"> <return type="float"> </return> <description> + Return how far a body can go through this one, when it allows one-way collisions. </description> </method> <method name="add_collision_exception_with"> <argument index="0" name="body" type="PhysicsBody2D"> </argument> <description> + Adds a body to the collision exception list. This list contains bodies that this body will not collide with. </description> </method> <method name="remove_collision_exception_with"> <argument index="0" name="body" type="PhysicsBody2D"> </argument> <description> + Removes a body from the collision exception list. </description> </method> </methods> @@ -24766,10 +24856,19 @@ This method controls whether the position between two cached points is interpola <constant name="AREA_PARAM_PRIORITY" value="7"> </constant> <constant name="AREA_SPACE_OVERRIDE_COMBINE" value="1"> + This area adds its gravity/damp values to whatever has been calculated so far. This way, many overlapping areas can combine their physics to make interesting effects. + </constant> + <constant name="AREA_SPACE_OVERRIDE_COMBINE_REPLACE" value="2"> + This area adds its gravity/damp values to whatever has been calculated so far. Then stops taking into account the rest of the areas, even the default one. </constant> <constant name="AREA_SPACE_OVERRIDE_DISABLED" value="0"> + This area does not affect gravity/damp. These are generally areas that exist only to detect collisions, and objects entering or exiting them. + </constant> + <constant name="AREA_SPACE_OVERRIDE_REPLACE" value="3"> + This area replaces any gravity/damp, even the default one, and stops taking into account the rest of the areas. </constant> - <constant name="AREA_SPACE_OVERRIDE_REPLACE" value="2"> + <constant name="AREA_SPACE_OVERRIDE_REPLACE_COMBINE" value="4"> + This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one. </constant> <constant name="BODY_MODE_STATIC" value="0"> </constant> diff --git a/drivers/png/SCsub b/drivers/png/SCsub index 5682a5667e..5532e28ade 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -22,18 +22,19 @@ png_sources = [ "png/image_loader_png.cpp" ] -if ("neon_enabled" in env and env["neon_enabled"]): +if ("neon_enabled" in env and env["neon_enabled"]): + env.Append(CPPFLAGS=["-DPNG_ARM_NEON_OPT=2"]) env_neon = env.Clone(); if "S_compiler" in env: env_neon['CC'] = env['S_compiler'] - env_neon.Append(CPPFLAGS=["-DPNG_ARM_NEON"]) + #env_neon.Append(CPPFLAGS=["-DPNG_ARM_NEON"]) import os # Currently .ASM filter_neon.S does not compile on NT. if (os.name!="nt"): - env_neon.Append(CPPFLAGS=["-DPNG_ARM_NEON_OPT=2"]) png_sources.append(env_neon.Object("#drivers/png/arm/arm_init.c")) png_sources.append(env_neon.Object("#drivers/png/arm/filter_neon.S")) - +else: + env.Append(CPPFLAGS=["-DPNG_ARM_NEON_OPT=0"]) env.drivers_sources+=png_sources diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp index b7bcd44783..1c18ebd855 100644 --- a/drivers/unix/thread_posix.cpp +++ b/drivers/unix/thread_posix.cpp @@ -81,6 +81,11 @@ Error ThreadPosix::set_name(const String& p_name) { ERR_FAIL_COND_V(pthread == 0, ERR_UNCONFIGURED); + #ifdef PTHREAD_NO_RENAME + return ERR_UNAVAILABLE; + + #else + #ifdef PTHREAD_RENAME_SELF // check if thread is the same as caller @@ -100,6 +105,8 @@ Error ThreadPosix::set_name(const String& p_name) { #endif return err == 0 ? OK : ERR_INVALID_PARAMETER; + + #endif // PTHREAD_NO_RENAME }; void ThreadPosix::make_default() { diff --git a/drivers/webp/utils/bit_reader.c b/drivers/webp/utils/bit_reader.c index 5081d5cd4d..4d6b4f0164 100644 --- a/drivers/webp/utils/bit_reader.c +++ b/drivers/webp/utils/bit_reader.c @@ -17,6 +17,8 @@ #include "./bit_reader_inl.h" +#define JAVASCRIPT_ENABLED // testing + //------------------------------------------------------------------------------ // VP8BitReader @@ -40,7 +42,13 @@ void VP8InitBitReader(VP8BitReader* const br, br->bits_ = -8; // to load the very first 8bits br->eof_ = 0; VP8BitReaderSetBuffer(br, start, size); + +#ifdef JAVASCRIPT_ENABLED // html5 required aligned reads + while(((uintptr_t)br->buf_ & 1) != 0 && !br->eof_) + VP8LoadFinalBytes(br); +#else VP8LoadNewBytes(br); +#endif } void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) { diff --git a/drivers/webp/utils/bit_reader.h b/drivers/webp/utils/bit_reader.h index 7e09653ebc..f0f450231d 100644 --- a/drivers/webp/utils/bit_reader.h +++ b/drivers/webp/utils/bit_reader.h @@ -37,6 +37,12 @@ extern "C" { // BITS can be any multiple of 8 from 8 to 56 (inclusive). // Pick values that fit natural register size. +#ifdef JAVASCRIPT_ENABLED + +#define BITS 16 + +#else + #if defined(__i386__) || defined(_M_IX86) // x86 32bit #define BITS 24 #elif defined(__x86_64__) || defined(_M_X64) // x86 64bit @@ -49,6 +55,8 @@ extern "C" { #define BITS 24 // TODO(skal): test aarch64 and find the proper BITS value. #endif +#endif + //------------------------------------------------------------------------------ // Derived types and constants: // bit_t = natural register type for storing 'value_' (which is BITS+8 bits) diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index 137fcc56f5..9472f05e16 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -59,11 +59,11 @@ def configure(env): import string if (env["bits"]=="64"): #env['CCFLAGS'] = string.split('-arch arm64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-return-type -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wshorten-64-to-32 -Wno-newline-eof -Wno-c++11-extensions -fstrict-aliasing -Wdeprecated-declarations -Winvalid-offsetof -g -Wno-sign-conversion -miphoneos-version-min=5.1.1 -Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-invalid-offsetof -ffast-math -m64 -DDEBUG -D_DEBUG -MMD -MT dependencies -isysroot $IPHONESDK') - env['CCFLAGS'] = string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -gdwarf-2 -fvisibility=hidden -Wno-sign-conversion -MMD -MT dependencies -miphoneos-version-min=5.1.1 -isysroot $IPHONESDK') + env['CCFLAGS'] = string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -fvisibility=hidden -Wno-sign-conversion -MMD -MT dependencies -miphoneos-version-min=5.1.1 -isysroot $IPHONESDK') env.Append(CPPFLAGS=['-DNEED_LONG_INT']) env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON']) else: - env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -gdwarf-2 -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=5.1.1 -MMD -MT dependencies -isysroot $IPHONESDK') + env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=5.1.1 -MMD -MT dependencies -isysroot $IPHONESDK') if (env["bits"]=="64"): env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=5.1.1', @@ -116,12 +116,12 @@ def configure(env): if (env["target"]=="release"): - env.Append(CCFLAGS=['-O3', '-ffast-math', '-DNS_BLOCK_ASSERTIONS=1','-Wall']) - env.Append(LINKFLAGS=['-O3', '-ffast-math']) + env.Append(CCFLAGS=['-O3', '-DNS_BLOCK_ASSERTIONS=1','-Wall', '-gdwarf-2']) # removed -ffast-math + env.Append(LINKFLAGS=['-O3']) # elif env["target"] == "release_debug": - env.Append(CCFLAGS=['-Os', '-ffast-math', '-DNS_BLOCK_ASSERTIONS=1','-Wall','-DDEBUG_ENABLED']) - env.Append(LINKFLAGS=['-Os', '-ffast-math']) + env.Append(CCFLAGS=['-Os', '-DNS_BLOCK_ASSERTIONS=1','-Wall','-DDEBUG_ENABLED']) + env.Append(LINKFLAGS=['-Os']) env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ENABLED']) elif (env["target"]=="debug"): @@ -131,7 +131,7 @@ def configure(env): elif (env["target"]=="profile"): - env.Append(CCFLAGS=['-g','-pg', '-Os', '-ffast-math']) + env.Append(CCFLAGS=['-g','-pg', '-Os']) env.Append(LINKFLAGS=['-pg']) diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index ec21bf6ee4..0a6c8b1457 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -80,7 +80,7 @@ def configure(env): env.opus_fixed_point="yes" env.Append(CPPFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST','-fno-rtti']) - env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL','-DMPC_FIXED_POINT','-DTYPED_METHOD_BIND','-DNO_THREADS']) + env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DPTHREAD_NO_RENAME', '-DNO_FCNTL','-DMPC_FIXED_POINT','-DTYPED_METHOD_BIND','-DNO_THREADS']) env.Append(CPPFLAGS=['-DGLES2_ENABLED']) env.Append(CPPFLAGS=['-DGLES_NO_CLIENT_ARRAYS']) env.Append(CPPFLAGS=['-s','ASM_JS=1']) @@ -98,3 +98,10 @@ def configure(env): #print "CCCOM is:", env.subst('$CCCOM') #print "P: ", env['p'], " Platofrm: ", env['platform'] + + import methods + + env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) + env.Append( BUILDERS = { 'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) + env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) + #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } ) diff --git a/platform/windows/joystick.cpp b/platform/windows/joystick.cpp index 68364ea8d5..bda092de53 100644 --- a/platform/windows/joystick.cpp +++ b/platform/windows/joystick.cpp @@ -100,6 +100,13 @@ int joystick_windows::check_free_joy_slot() const { // adapted from SDL2, works a lot better than the MSDN version bool joystick_windows::is_xinput_device(const GUID *p_guid) { + static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + + if (p_guid == &IID_ValveStreamingGamepad || p_guid == &IID_X360WiredGamepad || p_guid == &IID_X360WirelessGamepad) + return true; + PRAWINPUTDEVICELIST dev_list = NULL; unsigned int dev_list_count = 0; @@ -144,7 +151,7 @@ bool joystick_windows::setup_dinput_joystick(const DIDEVICEINSTANCE* instance) { return false; d_joysticks[joystick_count] = dinput_gamepad(); - dinput_gamepad* joy = &d_joysticks[num]; + dinput_gamepad* joy = &d_joysticks[joystick_count]; const DWORD devtype = (instance->dwDevType & 0xFF); @@ -168,7 +175,8 @@ bool joystick_windows::setup_dinput_joystick(const DIDEVICEINSTANCE* instance) { guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); - id_to_change = num; + id_to_change = joystick_count; + joy->di_joy->SetDataFormat(&c_dfDIJoystick2); joy->di_joy->SetCooperativeLevel(*hWnd, DISCL_FOREGROUND); joy->di_joy->EnumObjects(objectsCallback, this, NULL); @@ -218,7 +226,7 @@ void joystick_windows::setup_joystick_object(const DIDEVICEOBJECTINSTANCE *ob, i dinput_gamepad &joy = d_joysticks[p_joy_id]; - res = joy.di_joy->SetProperty(DIPROP_RANGE, &prop_range.diph); + res = IDirectInputDevice8_SetProperty(joy.di_joy, DIPROP_RANGE, &prop_range.diph); if (FAILED(res)) return; @@ -365,13 +373,13 @@ unsigned int joystick_windows::process_joysticks(unsigned int p_last_id) { IDirectInputDevice8_Acquire(joy->di_joy); joy->di_joy->Poll(); } - if (FAILED(hr = d_joysticks[i].di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js))) { + if (FAILED(hr = joy->di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js))) { //printf("failed to read joy #%d\n", i); continue; } - p_last_id = post_hat(p_last_id, i, js.rgdwPOV[0]); + p_last_id = post_hat(p_last_id, joy->id, js.rgdwPOV[0]); for (int j = 0; j < 128; j++) { @@ -379,7 +387,7 @@ unsigned int joystick_windows::process_joysticks(unsigned int p_last_id) { if (!joy->last_buttons[j]) { - p_last_id = input->joy_button(p_last_id, i, j, true); + p_last_id = input->joy_button(p_last_id, joy->id, j, true); joy->last_buttons[j] = true; } } @@ -387,7 +395,7 @@ unsigned int joystick_windows::process_joysticks(unsigned int p_last_id) { if (joy->last_buttons[j]) { - p_last_id = input->joy_button(p_last_id, i, j, false); + p_last_id = input->joy_button(p_last_id, joy->id, j, false); joy->last_buttons[j] = false; } } @@ -402,7 +410,7 @@ unsigned int joystick_windows::process_joysticks(unsigned int p_last_id) { for (int k=0; k<count; k++) { if (joy->joy_axis[j] == axes[k]) { - p_last_id = input->joy_axis(p_last_id, i, j, axis_correct(values[k])); + p_last_id = input->joy_axis(p_last_id, joy->id, j, axis_correct(values[k])); break; }; }; diff --git a/platform/x11/detect.py b/platform/x11/detect.py index c93905ed3c..0226c8b8c0 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -45,10 +45,6 @@ def can_build(): print("xinerama not found.. x11 disabled.") return False - x11_error=os.system("pkg-config libevdev --modversion > /dev/null ") - if (x11_error): - print("evdev not found.. x11 disabled.") - return False return True # X11 enabled @@ -133,7 +129,6 @@ def configure(env): env.ParseConfig('pkg-config x11 --cflags --libs') env.ParseConfig('pkg-config xinerama --cflags --libs') env.ParseConfig('pkg-config xcursor --cflags --libs') - env.ParseConfig('pkg-config libevdev --cflags --libs') if (env["openssl"]=="yes"): env.ParseConfig('pkg-config openssl --cflags --libs') @@ -155,7 +150,18 @@ def configure(env): env.Append(CPPFLAGS=['-DOPENGL_ENABLED','-DGLEW_ENABLED']) if platform.system() == 'Linux': env.Append(CPPFLAGS=["-DALSA_ENABLED"]) - env.Append(LIBS=['asound', 'udev']) + env.Append(LIBS=['asound']) + + if not os.system("pkg-config --exists libudev"): + if not os.system("pkg-config --exists libevdev"): + print("Enabling udev/evdev") + env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + env.ParseConfig('pkg-config libudev --cflags --libs') + env.ParseConfig('pkg-config libevdev --cflags --libs') + else: + print("libevdev development libraries not found, disabling gamepad support") + else: + print("libudev development libraries not found, disabling gamepad support") if (env["pulseaudio"]=="yes"): if not os.system("pkg-config --exists libpulse-simple"): diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp index e50916d2c2..cc806f6f78 100644 --- a/platform/x11/joystick_linux.cpp +++ b/platform/x11/joystick_linux.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ //author: Andreas Haas <hondres, liugam3@gmail.com> -#ifdef __linux__ +#ifdef JOYDEV_ENABLED #include "joystick_linux.h" #include "print_string.h" diff --git a/platform/x11/joystick_linux.h b/platform/x11/joystick_linux.h index 339a5f239d..1064a6f841 100644 --- a/platform/x11/joystick_linux.h +++ b/platform/x11/joystick_linux.h @@ -30,7 +30,7 @@ //author: Andreas Haas <hondres, liugam3@gmail.com> #ifndef JOYSTICK_LINUX_H #define JOYSTICK_LINUX_H -#ifdef __linux__ +#ifdef JOYDEV_ENABLED #include "main/input_default.h" #include "os/thread.h" #include "os/mutex.h" diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index d23994edd7..0afab6442b 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -426,7 +426,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi physics_2d_server->init(); input = memnew( InputDefault ); -#ifdef __linux__ +#ifdef JOYDEV_ENABLED joystick = memnew( joystick_linux(input)); #endif _ensure_data_dir(); @@ -461,7 +461,7 @@ void OS_X11::finalize() { physics_2d_server->finish(); memdelete(physics_2d_server); -#ifdef __linux__ +#ifdef JOYDEV_ENABLED memdelete(joystick); #endif memdelete(input); @@ -1753,7 +1753,7 @@ void OS_X11::run() { while (!force_quit) { process_xevents(); // get rid of pending events -#ifdef __linux__ +#ifdef JOYDEV_ENABLED event_id = joystick->process_joysticks(event_id); #endif if (Main::iteration()==true) diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 02518189e0..eee3e40136 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -126,7 +126,7 @@ class OS_X11 : public OS_Unix { InputDefault *input; -#ifdef __linux__ +#ifdef JOYDEV_ENABLED joystick_linux *joystick; #endif diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index c44b46adbf..5038752b22 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -652,7 +652,7 @@ void Area2D::_bind_methods() { ADD_SIGNAL( MethodInfo("area_exit",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area2D"))); - ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode")); + ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Combine-Replace,Replace,Replace-Combine"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode")); ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point")); ADD_PROPERTYNZ( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector")); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index f5a88390e7..2b74655109 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -40,7 +40,9 @@ public: enum SpaceOverride { SPACE_OVERRIDE_DISABLED, SPACE_OVERRIDE_COMBINE, - SPACE_OVERRIDE_REPLACE + SPACE_OVERRIDE_COMBINE_REPLACE, + SPACE_OVERRIDE_REPLACE, + SPACE_OVERRIDE_REPLACE_COMBINE }; private: diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index ff35837bc0..47cebd25a2 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -579,7 +579,7 @@ void Area::_bind_methods() { ADD_SIGNAL( MethodInfo("area_enter",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"))); ADD_SIGNAL( MethodInfo("area_exit",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"))); - ADD_PROPERTY( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Combine-Replace,Replace,Replace-Combine"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector")); diff --git a/scene/3d/area.h b/scene/3d/area.h index f03955d1e7..529a116937 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -40,7 +40,9 @@ public: enum SpaceOverride { SPACE_OVERRIDE_DISABLED, SPACE_OVERRIDE_COMBINE, - SPACE_OVERRIDE_REPLACE + SPACE_OVERRIDE_COMBINE_REPLACE, + SPACE_OVERRIDE_REPLACE, + SPACE_OVERRIDE_REPLACE_COMBINE }; private: diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 5abb6c1d01..0db85981f7 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -30,35 +30,62 @@ #include "scene/scene_string_names.h" #include "os/keyboard.h" #include "os/os.h" -RichTextLabel::Item *RichTextLabel::_get_next_item(Item* p_item) { +RichTextLabel::Item *RichTextLabel::_get_next_item(Item* p_item,bool p_free) { - if (p_item->subitems.size()) { + if (p_free) { - return p_item->subitems.front()->get(); - } else if (!p_item->parent) { - return NULL; - } else if (p_item->E->next()) { + if (p_item->subitems.size()) { + + return p_item->subitems.front()->get(); + } else if (!p_item->parent) { + return NULL; + } else if (p_item->E->next()) { + + return p_item->E->next()->get(); + } else { + //go up until something with a next is found + while (p_item->parent && !p_item->E->next()) { + p_item=p_item->parent; + } + + + if (p_item->parent) + return p_item->E->next()->get(); + else + return NULL; - return p_item->E->next()->get(); - } else { - //go up until something with a next is found - while (p_item->parent && !p_item->E->next()) { - p_item=p_item->parent; } + } else { + if (p_item->subitems.size() && p_item->type!=ITEM_TABLE) { - if (p_item && p_item->parent) - return p_item->E->next()->get(); - else + return p_item->subitems.front()->get(); + } else if (p_item->type==ITEM_FRAME) { return NULL; + } else if (p_item->E->next()) { + + return p_item->E->next()->get(); + } else { + //go up until something with a next is found + while (p_item->type!=ITEM_FRAME && !p_item->E->next()) { + p_item=p_item->parent; + } + + if (p_item->type!=ITEM_FRAME) + return p_item->E->next()->get(); + else + return NULL; + + } } return NULL; } -void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos,Item **r_click_item,int *r_click_char,bool *r_outside,int p_char_count) { + +void RichTextLabel::_process_line(ItemFrame *p_frame,const Vector2& p_ofs,int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos,Item **r_click_item,int *r_click_char,bool *r_outside,int p_char_count) { RID ci; if (r_outside) @@ -70,7 +97,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p *r_click_item=NULL; } - Line &l = lines[p_line]; + Line &l = p_frame->lines[p_line]; Item *it = l.from; @@ -91,6 +118,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p l.offset_caches.clear(); l.height_caches.clear(); l.char_count=0; + l.minimum_width=0; } int wofs=margin; @@ -138,7 +166,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p if (p_mode!=PROCESS_CACHE) {\ lh=line<l.height_caches.size()?l.height_caches[line]:1;\ }\ - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x<wofs) {\ + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh && p_click_pos.x<p_ofs.x+wofs) {\ if (r_outside) *r_outside=true;\ *r_click_item=it;\ *r_click_char=rchar;\ @@ -148,12 +176,15 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p #define ENSURE_WIDTH(m_width) \ + if (p_mode==PROCESS_CACHE) { \ + l.minimum_width=MAX(l.minimum_width,wofs+m_width);\ + }\ if (wofs + m_width > p_width) {\ if (p_mode==PROCESS_CACHE) {\ if (spaces>0) \ spaces-=1;\ }\ - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x>wofs) {\ + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh && p_click_pos.x>p_ofs.x+wofs) {\ if (r_outside) *r_outside=true; \ *r_click_item=it;\ *r_click_char=rchar;\ @@ -165,7 +196,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p #define ADVANCE(m_width) \ {\ - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x>=wofs && p_click_pos.x<wofs+m_width) {\ + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh && p_click_pos.x>=p_ofs.x+wofs && p_click_pos.x<p_ofs.x+wofs+m_width) {\ if (r_outside) *r_outside=false; \ *r_click_item=it;\ *r_click_char=rchar;\ @@ -218,8 +249,10 @@ if (m_height > line_height) {\ underline=true; } + } else if (p_mode==PROCESS_CACHE) { l.char_count+=text->text.length(); + } rchar=0; @@ -263,7 +296,6 @@ if (m_height > line_height) {\ } - ENSURE_WIDTH(w); @@ -294,7 +326,7 @@ if (m_height > line_height) {\ - if (p_mode==PROCESS_POINTER && r_click_char && p_click_pos.y>=y && p_click_pos.y<=y+lh) { + if (p_mode==PROCESS_POINTER && r_click_char && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh) { //int o = (wofs+w)-p_click_pos.x; @@ -303,7 +335,7 @@ if (m_height > line_height) {\ cw=tab_size*font->get_char_size(' ').width; } - if (p_click_pos.x-cw/2>pofs) { + if (p_click_pos.x-cw/2>p_ofs.x+pofs) { rchar=int((&c[i])-cf); //print_line("GOT: "+itos(rchar)); @@ -337,13 +369,13 @@ if (m_height > line_height) {\ if (selected) { cw = font->get_char_size(c[i],c[i+1]).x; - draw_rect(Rect2(pofs,y,cw,lh),selection_bg); + draw_rect(Rect2(p_ofs.x+pofs,p_ofs.y+y,cw,lh),selection_bg); if (visible) - font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],selection_fg); + font->draw_char(ci,p_ofs+Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],selection_fg); } else { if (visible) - cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color); + cw=font->draw_char(ci,p_ofs+Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color); } p_char_count++; @@ -359,7 +391,7 @@ if (m_height > line_height) {\ uc.a*=0.5; //VS::get_singleton()->canvas_item_add_line(ci,Point2(pofs,y+ascent+2),Point2(pofs+cw,y+ascent+2),uc); int uy = y+lh-fh+ascent+2; - VS::get_singleton()->canvas_item_add_line(ci,Point2(pofs,uy),Point2(pofs+cw,uy),uc); + VS::get_singleton()->canvas_item_add_line(ci,p_ofs+Point2(pofs,uy),p_ofs+Point2(pofs+cw,uy),uc); } ofs+=cw; } @@ -397,7 +429,7 @@ if (m_height > line_height) {\ bool visible = visible_characters<0 || p_char_count<visible_characters; if (p_mode==PROCESS_DRAW && visible) { - img->image->draw(ci,Point2(wofs,y+lh-font->get_descent()-img->image->get_height())); + img->image->draw(ci,p_ofs+Point2(wofs,y+lh-font->get_descent()-img->image->get_height())); } p_char_count++; @@ -435,6 +467,148 @@ if (m_height > line_height) {\ #endif } break; + case ITEM_TABLE: { + + lh=0; + ItemTable *table = static_cast<ItemTable*>(it); + int hseparation=get_constant("table_hseparation"); + int vseparation=get_constant("table_vseparation"); + Color ccolor = _find_color(table,p_base_color); + Vector2 draw_ofs = Point2(wofs,y); + int max_y=get_size().height; + + if (p_mode==PROCESS_CACHE) { + + int idx=0; + //set minimums to zero + for(int i=0;i<table->columns.size();i++) { + table->columns[i].min_width=0; + table->columns[i].width=0; + } + //compute minimum width for each cell + for (List<Item*>::Element *E=table->subitems.front();E;E=E->next()) { + ERR_CONTINUE(E->get()->type!=ITEM_FRAME); //children should all be frames + ItemFrame *frame = static_cast<ItemFrame*>(E->get()); + + int column = idx % table->columns.size(); + + int ly=0; + + + for(int i=0;i<frame->lines.size();i++) { + + _process_line(frame,Point2(),ly,p_width,i,PROCESS_CACHE,cfont,Color()); + table->columns[column].min_width=MAX( table->columns[i].min_width, frame->lines[i].minimum_width ); + } + idx++; + } + + //compute available width and total radio (for expanders) + + + int total_ratio=0; + int available_width=p_width - hseparation * (table->columns.size() -1); + table->total_width=hseparation; + + for(int i=0;i<table->columns.size();i++) { + available_width-=table->columns[i].min_width; + if (table->columns[i].expand) + total_ratio+=table->columns[i].expand_ratio; + } + + //assign actual widths + + for(int i=0;i<table->columns.size();i++) { + table->columns[i].width = table->columns[i].min_width; + if (table->columns[i].expand) + table->columns[i].width+=table->columns[i].expand_ratio*available_width/total_ratio; + table->total_width+=table->columns[i].width+hseparation; + } + + //compute caches properly again with the right width + idx=0; + for (List<Item*>::Element *E=table->subitems.front();E;E=E->next()) { + ERR_CONTINUE(E->get()->type!=ITEM_FRAME); //children should all be frames + ItemFrame *frame = static_cast<ItemFrame*>(E->get()); + + int column = idx % table->columns.size(); + + + for(int i=0;i<frame->lines.size();i++) { + + int ly=0; + _process_line(frame,Point2(),ly,table->columns[column].width,i,PROCESS_CACHE,cfont,Color()); + frame->lines[i].height_cache=ly; //actual height + frame->lines[i].height_accum_cache=ly; //actual height + } + idx++; + } + + } + + + + Point2 offset(hseparation,vseparation); + + int row_height=0; + //draw using computed caches + int idx=0; + for (List<Item*>::Element *E=table->subitems.front();E;E=E->next()) { + ERR_CONTINUE(E->get()->type!=ITEM_FRAME); //children should all be frames + ItemFrame *frame = static_cast<ItemFrame*>(E->get()); + + int column = idx % table->columns.size(); + + int ly=0; + int yofs=0; + + + int lines_h = frame->lines[frame->lines.size()-1].height_accum_cache - (frame->lines[0].height_accum_cache - frame->lines[0].height_cache); + int lines_ofs = p_ofs.y+offset.y+draw_ofs.y; + + bool visible = lines_ofs < get_size().height && lines_ofs+lines_h >=0; + + for(int i=0;i<frame->lines.size();i++) { + + + if (visible) { + if (p_mode==PROCESS_DRAW) { + _process_line(frame,p_ofs+offset+draw_ofs+Vector2(0,yofs),ly,table->columns[column].width,i,PROCESS_DRAW,cfont,ccolor); + } else if (p_mode==PROCESS_POINTER) { + _process_line(frame,p_ofs+offset+draw_ofs+Vector2(0,yofs),ly,table->columns[column].width,i,PROCESS_POINTER,cfont,ccolor,p_click_pos,r_click_item,r_click_char,r_outside); + } + } + + yofs+=frame->lines[i].height_cache; + if (p_mode==PROCESS_CACHE) { + frame->lines[i].height_accum_cache=offset.y+draw_ofs.y+frame->lines[i].height_cache; + } + + } + + row_height=MAX(yofs,row_height); + offset.x+=table->columns[column].width+hseparation; + + if (column==table->columns.size()-1) { + + offset.y+=row_height+vseparation; + offset.x=hseparation; + row_height=0; + } + idx++; + } + + int total_height = offset.y; + if (row_height) { + total_height=row_height+vseparation; + } + + + + ADVANCE( table->total_width ); + CHECK_HEIGHT( total_height ); + + } break; default: {} @@ -445,7 +619,7 @@ if (m_height > line_height) {\ it = _get_next_item(it); - if (p_mode == PROCESS_POINTER && r_click_item && itp && !it && p_click_pos.y>y+lh) { + if (p_mode == PROCESS_POINTER && r_click_item && itp && !it && p_click_pos.y>p_ofs.y+y+lh) { //at the end of all, return this if (r_outside) *r_outside=true; *r_click_item=itp; @@ -453,9 +627,9 @@ if (m_height > line_height) {\ return; } - if (it && (p_line+1 < lines.size()) && lines[p_line+1].from==it) { + if (it && (p_line+1 < p_frame->lines.size()) && p_frame->lines[p_line+1].from==it) { - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh) { + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh) { //went to next line, but pointer was on the previous one if (r_outside) *r_outside=true; *r_click_item=itp; @@ -493,8 +667,8 @@ void RichTextLabel::_scroll_changed(double) { void RichTextLabel::_update_scroll() { int total_height=0; - if (lines.size()) - total_height=lines[lines.size()-1].height_accum_cache; + if (main->lines.size()) + total_height=main->lines[main->lines.size()-1].height_accum_cache; bool exceeds = total_height > get_size().height && scroll_active; @@ -503,18 +677,18 @@ void RichTextLabel::_update_scroll() { if (exceeds) { scroll_visible=true; - first_invalid_line=0; + main->first_invalid_line=0; scroll_w=vscroll->get_combined_minimum_size().width; vscroll->show(); vscroll->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_END,scroll_w); - _validate_line_caches(); + _validate_line_caches(main); } else { scroll_visible=false; vscroll->hide(); scroll_w=0; - _validate_line_caches(); + _validate_line_caches(main); } } @@ -527,7 +701,7 @@ void RichTextLabel::_notification(int p_what) { case NOTIFICATION_RESIZED: { - first_invalid_line=0; //invalidate ALL + main->first_invalid_line=0; //invalidate ALL update(); } break; @@ -535,7 +709,7 @@ void RichTextLabel::_notification(int p_what) { if (use_bbcode) parse_bbcode(bbcode); - first_invalid_line=0; //invalidate ALL + main->first_invalid_line=0; //invalidate ALL update(); } break; @@ -550,7 +724,7 @@ void RichTextLabel::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - _validate_line_caches(); + _validate_line_caches(main); _update_scroll(); @@ -571,25 +745,25 @@ void RichTextLabel::_notification(int p_what) { int from_line = 0; int total_chars = 0; - while (from_line<lines.size()) { + while (from_line<main->lines.size()) { - if (lines[from_line].height_accum_cache>=ofs) + if (main->lines[from_line].height_accum_cache>=ofs) break; from_line++; - total_chars+=lines[from_line].char_count; + total_chars+=main->lines[from_line].char_count; } - if (from_line>=lines.size()) + if (from_line>=main->lines.size()) break; //nothing to draw - int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs; + int y = (main->lines[from_line].height_accum_cache - main->lines[from_line].height_cache) - ofs; Ref<Font> base_font=get_font("normal_font"); Color base_color=get_color("default_color"); - while (y<size.height && from_line<lines.size()) { + while (y<size.height && from_line<main->lines.size()) { - _process_line(y,size.width-scroll_w,from_line,PROCESS_DRAW,base_font,base_color,Point2i(),NULL,NULL,NULL,total_chars); - total_chars+=lines[from_line].char_count; + _process_line(main,Point2(),y,size.width-scroll_w,from_line,PROCESS_DRAW,base_font,base_color,Point2i(),NULL,NULL,NULL,total_chars); + total_chars+=main->lines[from_line].char_count; from_line++; } } @@ -597,7 +771,7 @@ void RichTextLabel::_notification(int p_what) { } -void RichTextLabel::_find_click(const Point2i& p_click,Item **r_click_item,int *r_click_char,bool *r_outside) { +void RichTextLabel::_find_click(ItemFrame* p_frame,const Point2i& p_click,Item **r_click_item,int *r_click_char,bool *r_outside) { if (r_click_item) *r_click_item=NULL; @@ -609,26 +783,26 @@ void RichTextLabel::_find_click(const Point2i& p_click,Item **r_click_item,int * //todo, change to binary search int from_line = 0; - while (from_line<lines.size()) { + while (from_line<p_frame->lines.size()) { - if (lines[from_line].height_accum_cache>=ofs) + if (p_frame->lines[from_line].height_accum_cache>=ofs) break; from_line++; } - if (from_line>=lines.size()) + if (from_line>=p_frame->lines.size()) return; - int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs; + int y = (p_frame->lines[from_line].height_accum_cache - p_frame->lines[from_line].height_cache) - ofs; Ref<Font> base_font=get_font("normal_font"); Color base_color=get_color("default_color"); - while (y<size.height && from_line<lines.size()) { + while (y<size.height && from_line<p_frame->lines.size()) { - _process_line(y,size.width-scroll_w,from_line,PROCESS_POINTER,base_font,base_color,p_click,r_click_item,r_click_char,r_outside); + _process_line(p_frame,Point2(),y,size.width-scroll_w,from_line,PROCESS_POINTER,base_font,base_color,p_click,r_click_item,r_click_char,r_outside); if (r_click_item && *r_click_item) return; from_line++; @@ -643,13 +817,13 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2& p_pos) const if (!underline_meta || selection.click) return CURSOR_ARROW; - if (first_invalid_line<lines.size()) + if (main->first_invalid_line<main->lines.size()) return CURSOR_ARROW; //invalid int line=0; Item *item=NULL; - ((RichTextLabel*)(this))->_find_click(p_pos,&item,&line); + ((RichTextLabel*)(this))->_find_click(main,p_pos,&item,&line); if (item && ((RichTextLabel*)(this))->_find_meta(item,NULL)) @@ -665,7 +839,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { case InputEvent::MOUSE_BUTTON: { - if (first_invalid_line<lines.size()) + if (main->first_invalid_line<main->lines.size()) return; const InputEventMouseButton& b = p_event.mouse_button; @@ -680,7 +854,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { Item *item=NULL; bool outside; - _find_click(Point2i(b.x,b.y),&item,&line,&outside); + _find_click(main,Point2i(b.x,b.y),&item,&line,&outside); if (item) { @@ -773,7 +947,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { } break; case InputEvent::MOUSE_MOTION: { - if (first_invalid_line<lines.size()) + if (main->first_invalid_line<main->lines.size()) return; const InputEventMouseMotion& m = p_event.mouse_motion; @@ -782,7 +956,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { int line=0; Item *item=NULL; - _find_click(Point2i(m.x,m.y),&item,&line); + _find_click(main,Point2i(m.x,m.y),&item,&line); if (!item) return; // do not update @@ -950,9 +1124,9 @@ bool RichTextLabel::_find_meta(Item *p_item,Variant *r_meta) { } -void RichTextLabel::_validate_line_caches() { +void RichTextLabel::_validate_line_caches(ItemFrame* p_frame) { - if (first_invalid_line==lines.size()) + if (p_frame->first_invalid_line==p_frame->lines.size()) return; //validate invalid lines!s @@ -960,24 +1134,24 @@ void RichTextLabel::_validate_line_caches() { Ref<Font> base_font=get_font("normal_font"); - for(int i=first_invalid_line;i<lines.size();i++) { + for(int i=p_frame->first_invalid_line;i<p_frame->lines.size();i++) { int y=0; - _process_line(y,size.width-scroll_w,i,PROCESS_CACHE,base_font,Color()); - lines[i].height_cache=y; - lines[i].height_accum_cache=y; + _process_line(p_frame,Point2(),y,size.width-scroll_w,i,PROCESS_CACHE,base_font,Color()); + p_frame->lines[i].height_cache=y; + p_frame->lines[i].height_accum_cache=y; if (i>0) - lines[i].height_accum_cache+=lines[i-1].height_accum_cache; + p_frame->lines[i].height_accum_cache+=p_frame->lines[i-1].height_accum_cache; } int total_height=0; - if (lines.size()) - total_height=lines[lines.size()-1].height_accum_cache; + if (p_frame->lines.size()) + total_height=p_frame->lines[p_frame->lines.size()-1].height_accum_cache; - first_invalid_line=lines.size(); + main->first_invalid_line=p_frame->lines.size(); updating_scroll=true; vscroll->set_max(total_height); @@ -990,17 +1164,20 @@ void RichTextLabel::_validate_line_caches() { } -void RichTextLabel::_invalidate_current_line() { +void RichTextLabel::_invalidate_current_line(ItemFrame* p_frame) { - if (lines.size()-1 <= first_invalid_line) { + if (p_frame->lines.size()-1 <= p_frame->first_invalid_line) { - first_invalid_line=lines.size()-1; + p_frame->first_invalid_line=p_frame->lines.size()-1; update(); } } void RichTextLabel::add_text(const String& p_text) { + if (current->type==ITEM_TABLE) + return; //can't add anything here + int pos=0; while (pos<p_text.length()) { @@ -1027,7 +1204,7 @@ void RichTextLabel::add_text(const String& p_text) { //append text condition! ItemText *ti = static_cast<ItemText*>(current->subitems.back()->get()); ti->text+=line; - _invalidate_current_line(); + _invalidate_current_line(main); } else { //append item condition @@ -1043,11 +1220,11 @@ void RichTextLabel::add_text(const String& p_text) { if (eol) { ItemNewline *item = memnew( ItemNewline ); - item->line=lines.size(); + item->line=current_frame->lines.size(); _add_item(item,false); - lines.resize(lines.size()+1); - lines[lines.size()-1].from=item; - _invalidate_current_line(); + current_frame->lines.resize(current_frame->lines.size()+1); + current_frame->lines[current_frame->lines.size()-1].from=item; + _invalidate_current_line(current_frame); } @@ -1055,25 +1232,38 @@ void RichTextLabel::add_text(const String& p_text) { } } -void RichTextLabel::_add_item(Item *p_item, bool p_enter) { +void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) { + + p_item->parent=current; p_item->E=current->subitems.push_back(p_item); p_item->index=current_idx++; + if (p_enter) current=p_item; - if (lines[lines.size()-1].from==NULL) { - lines[lines.size()-1].from=p_item; + if (p_ensure_newline && current_frame->lines[current_frame->lines.size()-1].from) { + _invalidate_current_line(current_frame); + current_frame->lines.resize( current_frame->lines.size() +1 ); + } - _invalidate_current_line(); + if (current_frame->lines[current_frame->lines.size()-1].from==NULL) { + current_frame->lines[current_frame->lines.size()-1].from=p_item; + } + p_item->line=current_frame->lines.size()-1; + + _invalidate_current_line(current_frame); } void RichTextLabel::add_image(const Ref<Texture>& p_image) { + if (current->type==ITEM_TABLE) + return; + ERR_FAIL_COND(p_image.is_null()); ItemImage *item = memnew( ItemImage ); @@ -1084,15 +1274,18 @@ void RichTextLabel::add_image(const Ref<Texture>& p_image) { void RichTextLabel::add_newline() { + if (current->type==ITEM_TABLE) + return; ItemNewline *item = memnew( ItemNewline ); - item->line=lines.size(); - lines.resize(lines.size()+1); + item->line=current_frame->lines.size(); + current_frame->lines.resize(current_frame->lines.size()+1); _add_item(item,false); } void RichTextLabel::push_font(const Ref<Font>& p_font) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ERR_FAIL_COND(p_font.is_null()); ItemFont *item = memnew( ItemFont ); @@ -1102,6 +1295,7 @@ void RichTextLabel::push_font(const Ref<Font>& p_font) { } void RichTextLabel::push_color(const Color& p_color) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemColor *item = memnew( ItemColor ); item->color=p_color; @@ -1110,6 +1304,7 @@ void RichTextLabel::push_color(const Color& p_color) { } void RichTextLabel::push_underline() { + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemUnderline *item = memnew( ItemUnderline ); _add_item(item,true); @@ -1118,47 +1313,40 @@ void RichTextLabel::push_underline() { void RichTextLabel::push_align(Align p_align) { - lines.resize(lines.size()+1); + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemAlign *item = memnew( ItemAlign ); item->align=p_align; - _add_item(item,true); - - ItemNewline *itemnl = memnew( ItemNewline ); - itemnl->line=lines.size()-1; - _add_item(itemnl,false); + _add_item(item,true,true); } void RichTextLabel::push_indent(int p_level) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ERR_FAIL_COND(p_level<0); - lines.resize(lines.size()+1); - ItemIndent *item = memnew( ItemIndent ); item->level=p_level; - _add_item(item,true); - - ItemNewline *itemnl = memnew( ItemNewline ); - itemnl->line=lines.size()-1; - _add_item(itemnl,false); + _add_item(item,true,true); } void RichTextLabel::push_list(ListType p_list) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ERR_FAIL_INDEX(p_list,3); ItemList *item = memnew( ItemList ); item->list_type=p_list; - _add_item(item,true); + _add_item(item,true,true); } void RichTextLabel::push_meta(const Variant& p_meta) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemMeta *item = memnew( ItemMeta ); item->meta=p_meta; @@ -1166,9 +1354,62 @@ void RichTextLabel::push_meta(const Variant& p_meta) { } +void RichTextLabel::push_table(int p_columns) { + + ERR_FAIL_COND( p_columns < 1); + ItemTable *item = memnew( ItemTable ); + + item->columns.resize(p_columns); + item->total_width=0; + for(int i=0;i<item->columns.size();i++) { + item->columns[i].expand=false; + item->columns[i].expand_ratio=1; + } + _add_item(item,true,true); + +} + +void RichTextLabel::set_table_column_expand(int p_column,bool p_expand,int p_ratio) { + + ERR_FAIL_COND(current->type!=ITEM_TABLE); + ItemTable *table = static_cast<ItemTable*>(current); + ERR_FAIL_INDEX(p_column,table->columns.size()); + table->columns[p_column].expand=p_expand; + table->columns[p_column].expand_ratio=p_ratio; +} + +void RichTextLabel::push_cell(){ + + ERR_FAIL_COND(current->type!=ITEM_TABLE); + + ItemFrame *item = memnew( ItemFrame ); + item->parent_frame=current_frame; + _add_item(item,true); + current_frame=item; + item->cell=true; + item->parent_line=item->parent_frame->lines.size()-1; + item->lines.resize(1); + item->lines[0].from=NULL; + item->first_invalid_line=0; + +} + +int RichTextLabel::get_current_table_column() const { + + ERR_FAIL_COND_V(current->type!=ITEM_TABLE,-1); + + ItemTable *table = static_cast<ItemTable*>(current); + + return table->subitems.size() % table->columns.size(); + +} + void RichTextLabel::pop() { ERR_FAIL_COND(!current->parent); + if (current->type==ITEM_FRAME) { + current_frame = static_cast<ItemFrame*>(current)->parent_frame; + } current=current->parent; } @@ -1176,9 +1417,10 @@ void RichTextLabel::clear() { main->_clear_children(); current=main; - lines.clear(); - lines.resize(1); - first_invalid_line=0; + current_frame=main; + main->lines.clear(); + main->lines.resize(1); + main->first_invalid_line=0; update(); selection.click=NULL; selection.active=false; @@ -1189,7 +1431,7 @@ void RichTextLabel::clear() { void RichTextLabel::set_tab_size(int p_spaces) { tab_size=p_spaces; - first_invalid_line=0; + main->first_invalid_line=0; update(); } @@ -1345,6 +1587,30 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) { push_font(mono_font); pos=brk_end+1; tag_stack.push_front(tag); + } else if (tag.begins_with("table=")) { + + int columns = tag.substr(6,tag.length()).to_int(); + if (columns<1) + columns=1; + //use monospace font + push_table(columns); + pos=brk_end+1; + tag_stack.push_front("table"); + } else if (tag=="cell") { + + push_cell(); + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag.begins_with("cell=")) { + + int ratio = tag.substr(6,tag.length()).to_int(); + if (ratio<1) + ratio=1; + //use monospace font + set_table_column_expand(get_current_table_column(),true,ratio); + push_cell(); + pos=brk_end+1; + tag_stack.push_front("cell"); } else if (tag=="u") { //use underline @@ -1504,15 +1770,15 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) { void RichTextLabel::scroll_to_line(int p_line) { - ERR_FAIL_INDEX(p_line,lines.size()); - _validate_line_caches(); - vscroll->set_val(lines[p_line].height_accum_cache-lines[p_line].height_cache); + ERR_FAIL_INDEX(p_line,main->lines.size()); + _validate_line_caches(main); + vscroll->set_val(main->lines[p_line].height_accum_cache-main->lines[p_line].height_cache); } int RichTextLabel::get_line_count() const { - return lines.size(); + return current_frame->lines.size(); } void RichTextLabel::set_selection_enabled(bool p_enabled) { @@ -1556,29 +1822,31 @@ bool RichTextLabel::search(const String& p_string,bool p_from_selection) { selection.active=true; update(); - if (line==-1) { + _validate_line_caches(main); - while(it) { + int fh = _find_font(t).is_valid()?_find_font(t)->get_height():get_font("normal_font")->get_height(); - if (it->type==ITEM_NEWLINE) { + float offset =0; - line=static_cast<ItemNewline*>(it)->line; - break; + int line = t->line; + Item *item =t; + while(item) { + if (item->type==ITEM_FRAME) { + ItemFrame *frame = static_cast<ItemFrame*>(item); + if (line>=0 && line<frame->lines.size()) { + offset+=frame->lines[line].height_accum_cache-frame->lines[line].height_cache; + line=frame->line; } - - it=_get_next_item(it); } - + item=item->parent; } - - line-=2; - scroll_to_line(line<0?0:line); + vscroll->set_val(offset-fh); return true; } } - it=_get_next_item(it); + it=_get_next_item(it,true); charidx=0; } @@ -1617,7 +1885,7 @@ void RichTextLabel::selection_copy() { if (item==selection.to) break; - item=_get_next_item(item); + item=_get_next_item(item,true); } if (text!="") { @@ -1670,6 +1938,9 @@ void RichTextLabel::_bind_methods() { ObjectTypeDB::bind_method(_MD("push_list","type"),&RichTextLabel::push_list); ObjectTypeDB::bind_method(_MD("push_meta","data"),&RichTextLabel::push_meta); ObjectTypeDB::bind_method(_MD("push_underline"),&RichTextLabel::push_underline); + ObjectTypeDB::bind_method(_MD("push_table","columns"),&RichTextLabel::push_table); + ObjectTypeDB::bind_method(_MD("set_table_column_expand","column","expand"),&RichTextLabel::set_table_column_expand); + ObjectTypeDB::bind_method(_MD("push_cell"),&RichTextLabel::push_cell); ObjectTypeDB::bind_method(_MD("pop"),&RichTextLabel::pop); ObjectTypeDB::bind_method(_MD("clear"),&RichTextLabel::clear); @@ -1722,7 +1993,7 @@ void RichTextLabel::_bind_methods() { BIND_CONSTANT( LIST_LETTERS ); BIND_CONSTANT( LIST_DOTS ); - BIND_CONSTANT( ITEM_MAIN ); + BIND_CONSTANT( ITEM_FRAME ); BIND_CONSTANT( ITEM_TEXT ); BIND_CONSTANT( ITEM_IMAGE ); BIND_CONSTANT( ITEM_NEWLINE ); @@ -1750,8 +2021,8 @@ int RichTextLabel::get_visible_characters() const { int RichTextLabel::get_total_character_count() const { int tc=0; - for(int i=0;i<lines.size();i++) - tc+=lines[i].char_count; + for(int i=0;i<current_frame->lines.size();i++) + tc+=current_frame->lines[i].char_count; return tc; } @@ -1760,12 +2031,13 @@ int RichTextLabel::get_total_character_count() const { RichTextLabel::RichTextLabel() { - main = memnew( ItemMain ); + main = memnew( ItemFrame ); main->index=0; current=main; - lines.resize(1); - lines[0].from=main; - first_invalid_line=0; + main->lines.resize(1); + main->lines[0].from=main; + main->first_invalid_line=0; + current_frame=main; tab_size=4; default_align=ALIGN_LEFT; underline_meta=true; diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index eaa8d5d60a..bc45ded4ad 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -54,7 +54,7 @@ public: enum ItemType { - ITEM_MAIN, + ITEM_FRAME, ITEM_TEXT, ITEM_IMAGE, ITEM_NEWLINE, @@ -64,6 +64,7 @@ public: ITEM_ALIGN, ITEM_INDENT, ITEM_LIST, + ITEM_TABLE, ITEM_META }; @@ -72,6 +73,24 @@ protected: static void _bind_methods(); private: + struct Item; + + struct Line { + + Item *from; + Vector<int> offset_caches; + Vector<int> height_caches; + Vector<int> space_caches; + int height_cache; + int height_accum_cache; + int char_count; + int minimum_width; + + Line() { from=NULL; char_count=0; } + }; + + + struct Item { int index; @@ -79,18 +98,26 @@ private: ItemType type; List<Item*> subitems; List<Item*>::Element *E; + int line; void _clear_children() { while (subitems.size()) { memdelete(subitems.front()->get()); subitems.pop_front(); } } - Item() { parent=NULL; E=NULL; } + Item() { parent=NULL; E=NULL; line=0;} virtual ~Item() { _clear_children(); } }; - struct ItemMain : public Item { + struct ItemFrame : public Item{ + + int parent_line; + bool cell; + Vector<Line> lines; + int first_invalid_line; + ItemFrame *parent_frame; - ItemMain() { type=ITEM_MAIN; } + ItemFrame() { type=ITEM_FRAME; parent_frame=NULL; cell=false; parent_line=0; } }; + struct ItemText : public Item { String text; @@ -150,11 +177,28 @@ private: ItemNewline() { type=ITEM_NEWLINE; } }; - ItemMain *main; + + struct ItemTable : public Item{ + + struct Column { + bool expand; + int expand_ratio; + int min_width; + int width; + }; + + Vector<Column> columns; + int total_width; + ItemTable() { type=ITEM_TABLE; } + }; + + ItemFrame *main; Item *current; + ItemFrame *current_frame; VScrollBar *vscroll; + bool scroll_visible; bool scroll_follow; bool scroll_following; @@ -163,34 +207,16 @@ private: bool updating_scroll; int current_idx; - struct Line { - - Item *from; - Vector<int> offset_caches; - Vector<int> height_caches; - Vector<int> space_caches; - int height_cache; - int height_accum_cache; - int char_count; - - Line() { from=NULL; char_count=0; } - }; - - - - - Vector<Line> lines; - int first_invalid_line; int tab_size; bool underline_meta; Align default_align; - void _invalidate_current_line(); - void _validate_line_caches(); + void _invalidate_current_line(ItemFrame *p_frame); + void _validate_line_caches(ItemFrame *p_frame); - void _add_item(Item *p_item, bool p_enter=false); + void _add_item(Item *p_item, bool p_enter=false,bool p_ensure_newline=false); @@ -227,8 +253,8 @@ private: int visible_characters; - void _process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos=Point2i(),Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL,int p_char_count=0); - void _find_click(const Point2i& p_click,Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL); + void _process_line(ItemFrame *p_frame,const Vector2& p_ofs,int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos=Point2i(),Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL,int p_char_count=0); + void _find_click(ItemFrame *p_frame, const Point2i& p_click,Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL); Ref<Font> _find_font(Item *p_item); @@ -242,12 +268,12 @@ private: void _scroll_changed(double); void _input_event(InputEvent p_event); - Item *_get_next_item(Item* p_item); + Item *_get_next_item(Item* p_item, bool p_free=false); bool use_bbcode; String bbcode; - + void _update_all_lines(); protected: void _notification(int p_what); @@ -264,6 +290,10 @@ public: void push_indent(int p_level); void push_list(ListType p_list); void push_meta(const Variant& p_data); + void push_table(int p_columns); + void set_table_column_expand(int p_column, bool p_expand, int p_ratio=1); + int get_current_table_column() const; + void push_cell(); void pop(); void clear(); diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 58683a07ad..5db809a618 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -271,6 +271,7 @@ void VideoPlayer::set_paused(bool p_paused) { playback->set_paused(p_paused); set_process(!p_paused); }; + last_audio_time = 0; }; bool VideoPlayer::is_paused() const { diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 7c43b66af3..e642efebb6 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -801,6 +801,8 @@ void make_default_theme() { t->set_color("selection_color","RichTextLabel", Color(0.1,0.1,1,0.8) ); t->set_constant("line_separation","RichTextLabel", 1 ); + t->set_constant("table_hseparation","RichTextLabel", 3 ); + t->set_constant("table_vseparation","RichTextLabel", 3 ); diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index c66e73b430..79d08b1e75 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -406,29 +406,41 @@ void BodySW::integrate_forces(real_t p_step) { return; AreaSW *def_area = get_space()->get_default_area(); - AreaSW *damp_area = def_area; + // AreaSW *damp_area = def_area; ERR_FAIL_COND(!def_area); int ac = areas.size(); - bool replace = false; + bool stopped = false; gravity = Vector3(0,0,0); area_linear_damp = 0; area_angular_damp = 0; if (ac) { areas.sort(); const AreaCMP *aa = &areas[0]; - damp_area = aa[ac-1].area; - for(int i=ac-1;i>=0;i--) { - _compute_area_gravity_and_dampenings(aa[i].area); - if (aa[i].area->get_space_override_mode() == PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE) { - replace = true; - break; + // damp_area = aa[ac-1].area; + for(int i=ac-1;i>=0 && !stopped;i--) { + PhysicsServer::AreaSpaceOverrideMode mode=aa[i].area->get_space_override_mode(); + switch (mode) { + case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE: + case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: { + _compute_area_gravity_and_dampenings(aa[i].area); + stopped = mode==PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE; + } break; + case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE: + case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: { + gravity = Vector3(0,0,0); + area_angular_damp = 0; + area_linear_damp = 0; + _compute_area_gravity_and_dampenings(aa[i].area); + stopped = mode==PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE; + } break; + default: {} } } } - if( !replace ) { + if( !stopped ) { _compute_area_gravity_and_dampenings(def_area); } diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index d0c5cbc77b..8d82d4a920 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -395,6 +395,7 @@ void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) { area_linear_damp += p_area->get_linear_damp(); area_angular_damp += p_area->get_angular_damp(); + printf("%f\n",gravity.y); } void Body2DSW::integrate_forces(real_t p_step) { @@ -403,27 +404,39 @@ void Body2DSW::integrate_forces(real_t p_step) { return; Area2DSW *def_area = get_space()->get_default_area(); - Area2DSW *damp_area = def_area; + // Area2DSW *damp_area = def_area; ERR_FAIL_COND(!def_area); int ac = areas.size(); - bool replace = false; + bool stopped = false; gravity = Vector2(0,0); area_angular_damp = 0; area_linear_damp = 0; if (ac) { areas.sort(); const AreaCMP *aa = &areas[0]; - damp_area = aa[ac-1].area; - for(int i=ac-1;i>=0;i--) { - _compute_area_gravity_and_dampenings(aa[i].area); - if (aa[i].area->get_space_override_mode() == Physics2DServer::AREA_SPACE_OVERRIDE_REPLACE) { - replace = true; - break; + // damp_area = aa[ac-1].area; + for(int i=ac-1;i>=0 && !stopped;i--) { + Physics2DServer::AreaSpaceOverrideMode mode=aa[i].area->get_space_override_mode(); + switch (mode) { + case Physics2DServer::AREA_SPACE_OVERRIDE_COMBINE: + case Physics2DServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: { + _compute_area_gravity_and_dampenings(aa[i].area); + stopped = mode==Physics2DServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE; + } break; + case Physics2DServer::AREA_SPACE_OVERRIDE_REPLACE: + case Physics2DServer::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: { + gravity = Vector2(0,0); + area_angular_damp = 0; + area_linear_damp = 0; + _compute_area_gravity_and_dampenings(aa[i].area); + stopped = mode==Physics2DServer::AREA_SPACE_OVERRIDE_REPLACE; + } break; + default: {} } } } - if( !replace ) { + if( !stopped ) { _compute_area_gravity_and_dampenings(def_area); } gravity*=gravity_scale; @@ -501,7 +514,7 @@ void Body2DSW::integrate_forces(real_t p_step) { _update_shapes_with_motion(motion); } - damp_area=NULL; // clear the area, so it is set in the next frame + // damp_area=NULL; // clear the area, so it is set in the next frame def_area=NULL; // clear the area, so it is set in the next frame contact_count=0; diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 5d8446ed38..c18b32468a 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -663,9 +663,11 @@ void Physics2DServer::_bind_methods() { BIND_CONSTANT( AREA_PARAM_ANGULAR_DAMP); BIND_CONSTANT( AREA_PARAM_PRIORITY ); - BIND_CONSTANT( AREA_SPACE_OVERRIDE_COMBINE ); BIND_CONSTANT( AREA_SPACE_OVERRIDE_DISABLED ); + BIND_CONSTANT( AREA_SPACE_OVERRIDE_COMBINE ); + BIND_CONSTANT( AREA_SPACE_OVERRIDE_COMBINE_REPLACE ); BIND_CONSTANT( AREA_SPACE_OVERRIDE_REPLACE ); + BIND_CONSTANT( AREA_SPACE_OVERRIDE_REPLACE_COMBINE ); BIND_CONSTANT( BODY_MODE_STATIC ); BIND_CONSTANT( BODY_MODE_KINEMATIC ); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 6845c7dfe1..a53cfae752 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -325,7 +325,9 @@ public: enum AreaSpaceOverrideMode { AREA_SPACE_OVERRIDE_DISABLED, AREA_SPACE_OVERRIDE_COMBINE, + AREA_SPACE_OVERRIDE_COMBINE_REPLACE, // Combines, then discards all subsequent calculations AREA_SPACE_OVERRIDE_REPLACE, + AREA_SPACE_OVERRIDE_REPLACE_COMBINE // Discards all previous calculations, then keeps combining }; virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode)=0; diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 53409acdfb..bc2b37d92c 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -693,9 +693,11 @@ void PhysicsServer::_bind_methods() { BIND_CONSTANT( AREA_PARAM_ANGULAR_DAMP ); BIND_CONSTANT( AREA_PARAM_PRIORITY ); - BIND_CONSTANT( AREA_SPACE_OVERRIDE_COMBINE ); BIND_CONSTANT( AREA_SPACE_OVERRIDE_DISABLED ); + BIND_CONSTANT( AREA_SPACE_OVERRIDE_COMBINE ); + BIND_CONSTANT( AREA_SPACE_OVERRIDE_COMBINE_REPLACE ); BIND_CONSTANT( AREA_SPACE_OVERRIDE_REPLACE ); + BIND_CONSTANT( AREA_SPACE_OVERRIDE_REPLACE_COMBINE ); BIND_CONSTANT( BODY_MODE_STATIC ); BIND_CONSTANT( BODY_MODE_KINEMATIC ); diff --git a/servers/physics_server.h b/servers/physics_server.h index 75584966bb..66296fa15d 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -318,7 +318,9 @@ public: enum AreaSpaceOverrideMode { AREA_SPACE_OVERRIDE_DISABLED, AREA_SPACE_OVERRIDE_COMBINE, + AREA_SPACE_OVERRIDE_COMBINE_REPLACE, AREA_SPACE_OVERRIDE_REPLACE, + AREA_SPACE_OVERRIDE_REPLACE_COMBINE }; virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode)=0; diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 25e6a68469..52381cf096 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -526,6 +526,7 @@ void VisualServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("canvas_item_get_opacity"),&VisualServer::canvas_item_get_opacity); ObjectTypeDB::bind_method(_MD("canvas_item_set_self_opacity"),&VisualServer::canvas_item_set_self_opacity); ObjectTypeDB::bind_method(_MD("canvas_item_get_self_opacity"),&VisualServer::canvas_item_get_self_opacity); + ObjectTypeDB::bind_method(_MD("canvas_item_set_z"),&VisualServer::canvas_item_set_z); ObjectTypeDB::bind_method(_MD("canvas_item_add_line"),&VisualServer::canvas_item_add_line, DEFVAL(1.0)); ObjectTypeDB::bind_method(_MD("canvas_item_add_rect"),&VisualServer::canvas_item_add_rect); diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index a5a3890129..1905ab731f 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -690,16 +690,28 @@ Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) { class_desc->pop(); //class_desc->add_newline(); - class_desc->add_newline(); +// class_desc->add_newline(); class_desc->push_indent(1); + class_desc->push_table(2); + class_desc->set_table_column_expand(1,1); for(int i=0;i<cd.methods.size();i++) { + class_desc->push_cell(); + + method_line[cd.methods[i].name]=class_desc->get_line_count()-2; //gets overriden if description + class_desc->push_align(RichTextLabel::ALIGN_RIGHT); class_desc->push_font(doc_code_font); _add_type(cd.methods[i].return_type); - class_desc->add_text(" "); + //class_desc->add_text(" "); + class_desc->pop(); //align + class_desc->pop(); //font + class_desc->pop(); //cell + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + if (cd.methods[i].description!="") { method_descr=true; class_desc->push_meta("@"+cd.methods[i].name); @@ -742,12 +754,14 @@ Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) { } class_desc->pop();//monofont - class_desc->add_newline(); +// class_desc->add_newline(); + class_desc->pop(); //cell } - + class_desc->pop(); //table class_desc->pop(); class_desc->add_newline(); + class_desc->add_newline(); } diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index f22bd3d956..59f5d89073 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -316,6 +316,8 @@ void ScriptTextEditor::_load_theme_settings() { get_text_edit()->add_keyword_color("Color",basetype_color); get_text_edit()->add_keyword_color("Image",basetype_color); get_text_edit()->add_keyword_color("InputEvent",basetype_color); + get_text_edit()->add_keyword_color("Rect2",basetype_color); + get_text_edit()->add_keyword_color("NodePath",basetype_color); //colorize engine types Color type_color= EDITOR_DEF("text_editor/engine_type_color",Color(0.0,0.2,0.4)); |