diff options
Diffstat (limited to 'scene')
115 files changed, 2946 insertions, 2516 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 75f1497edc..3def41eaa5 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -426,36 +426,36 @@ bool Area2D::is_monitorable() const { } TypedArray<Node2D> Area2D::get_overlapping_bodies() const { - ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); TypedArray<Node2D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping bodies when monitoring is off."); ret.resize(body_map.size()); int idx = 0; for (const KeyValue<ObjectID, BodyState> &E : body_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } + ret.resize(idx); return ret; } TypedArray<Area2D> Area2D::get_overlapping_areas() const { - ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); TypedArray<Area2D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping areas when monitoring is off."); ret.resize(area_map.size()); int idx = 0; for (const KeyValue<ObjectID, AreaState> &E : area_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } + ret.resize(idx); return ret; } @@ -607,7 +607,7 @@ void Area2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:px"), "set_gravity_point_center", "get_gravity_point_center"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_direction"), "set_gravity_direction", "get_gravity_direction"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-4096,4096,0.001,or_lesser,or_greater,suffix:px/s\u00B2"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-4096,4096,0.001,or_less,or_greater,suffix:px/s\u00B2"), "set_gravity", "get_gravity"); ADD_GROUP("Linear Damp", "linear_damp_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_linear_damp_space_override_mode", "get_linear_damp_space_override_mode"); diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index fc019b6cf9..85ec745aee 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -43,13 +43,18 @@ void AudioStreamPlayer2D::_notification(int p_what) { if (autoplay && !Engine::get_singleton()->is_editor_hint()) { play(); } + set_stream_paused(false); } break; case NOTIFICATION_EXIT_TREE: { - stop(); + set_stream_paused(true); AudioServer::get_singleton()->remove_listener_changed_callback(_listener_changed_cb, this); } break; + case NOTIFICATION_PREDELETE: { + stop(); + } break; + case NOTIFICATION_PAUSED: { if (!can_process()) { // Node can't process so we start fading out to silence. diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index ce77c6ba8d..a11b2b66bf 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -701,8 +701,8 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_drag_margin", "margin", "drag_margin"), &Camera2D::set_drag_margin); ClassDB::bind_method(D_METHOD("get_drag_margin", "margin"), &Camera2D::get_drag_margin); - ClassDB::bind_method(D_METHOD("get_camera_position"), &Camera2D::get_camera_position); - ClassDB::bind_method(D_METHOD("get_camera_screen_center"), &Camera2D::get_camera_screen_center); + ClassDB::bind_method(D_METHOD("get_target_position"), &Camera2D::get_camera_position); + ClassDB::bind_method(D_METHOD("get_screen_center_position"), &Camera2D::get_camera_screen_center); ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &Camera2D::set_zoom); ClassDB::bind_method(D_METHOD("get_zoom"), &Camera2D::get_zoom); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 58e357ab5f..4523e5dfe9 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -1383,32 +1383,32 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater,suffix:px/s"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater,suffix:px/s"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE); @@ -1428,8 +1428,8 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp index 38a03aaf97..8ba51482ee 100644 --- a/scene/2d/navigation_link_2d.cpp +++ b/scene/2d/navigation_link_2d.cpp @@ -113,6 +113,10 @@ void NavigationLink2D::_notification(int p_what) { #ifdef TOOLS_ENABLED Rect2 NavigationLink2D::_edit_get_rect() const { + if (!is_inside_tree()) { + return Rect2(); + } + real_t radius = NavigationServer2D::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map()); Rect2 rect(get_start_location(), Size2()); diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index a592d20cba..1850e00ecd 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -38,6 +38,9 @@ void NavigationObstacle2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rid"), &NavigationObstacle2D::get_rid); + ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationObstacle2D::set_navigation_map); + ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationObstacle2D::get_navigation_map); + ClassDB::bind_method(D_METHOD("set_estimate_radius", "estimate_radius"), &NavigationObstacle2D::set_estimate_radius); ClassDB::bind_method(D_METHOD("is_radius_estimated"), &NavigationObstacle2D::is_radius_estimated); ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationObstacle2D::set_radius); @@ -57,28 +60,26 @@ void NavigationObstacle2D::_validate_property(PropertyInfo &p_property) const { void NavigationObstacle2D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - parent_node2d = Object::cast_to<Node2D>(get_parent()); - reevaluate_agent_radius(); - if (parent_node2d != nullptr) { - // place agent on navigation map first or else the RVO agent callback creation fails silently later - NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map()); - } + case NOTIFICATION_POST_ENTER_TREE: { + set_agent_parent(get_parent()); set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { - parent_node2d = nullptr; + set_agent_parent(nullptr); set_physics_process_internal(false); } break; case NOTIFICATION_PARENTED: { - parent_node2d = Object::cast_to<Node2D>(get_parent()); - reevaluate_agent_radius(); + if (is_inside_tree() && (get_parent() != parent_node2d)) { + set_agent_parent(get_parent()); + set_physics_process_internal(true); + } } break; case NOTIFICATION_UNPARENTED: { - parent_node2d = nullptr; + set_agent_parent(nullptr); + set_physics_process_internal(false); } break; case NOTIFICATION_PAUSED: { @@ -182,6 +183,35 @@ real_t NavigationObstacle2D::estimate_agent_radius() const { return 1.0; // Never a 0 radius } +void NavigationObstacle2D::set_agent_parent(Node *p_agent_parent) { + if (Object::cast_to<Node2D>(p_agent_parent) != nullptr) { + parent_node2d = Object::cast_to<Node2D>(p_agent_parent); + if (map_override.is_valid()) { + NavigationServer2D::get_singleton()->agent_set_map(get_rid(), map_override); + } else { + NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map()); + } + reevaluate_agent_radius(); + } else { + parent_node2d = nullptr; + NavigationServer2D::get_singleton()->agent_set_map(get_rid(), RID()); + } +} + +void NavigationObstacle2D::set_navigation_map(RID p_navigation_map) { + map_override = p_navigation_map; + NavigationServer2D::get_singleton()->agent_set_map(agent, map_override); +} + +RID NavigationObstacle2D::get_navigation_map() const { + if (map_override.is_valid()) { + return map_override; + } else if (parent_node2d != nullptr) { + return parent_node2d->get_world_2d()->get_navigation_map(); + } + return RID(); +} + void NavigationObstacle2D::set_estimate_radius(bool p_estimate_radius) { estimate_radius = p_estimate_radius; notify_property_list_changed(); diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index 5795c6c94f..6eff95adec 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -38,8 +38,10 @@ class NavigationObstacle2D : public Node { GDCLASS(NavigationObstacle2D, Node); Node2D *parent_node2d = nullptr; + RID agent; RID map_before_pause; + RID map_override; bool estimate_radius = true; real_t radius = 1.0; @@ -57,6 +59,11 @@ public: return agent; } + void set_agent_parent(Node *p_agent_parent); + + void set_navigation_map(RID p_navigation_map); + RID get_navigation_map() const; + void set_estimate_radius(bool p_estimate_radius); bool is_radius_estimated() const { return estimate_radius; diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 4599785ce4..7765533016 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -437,8 +437,8 @@ void Node2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent); ADD_GROUP("Transform", ""); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_lesser,or_greater,no_slider,suffix:px"), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_less,or_greater,no_slider,suffix:px"), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale", PROPERTY_HINT_LINK), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians"), "set_skew", "get_skew"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_NONE), "set_transform", "get_transform"); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index be17299f07..90b2e3d460 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -252,7 +252,7 @@ void PathFollow2D::_validate_property(PropertyInfo &p_property) const { max = path->get_curve()->get_baked_length(); } - p_property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater"; + p_property.hint_string = "0," + rtos(max) + ",0.01,or_less,or_greater"; } } @@ -293,8 +293,8 @@ void PathFollow2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead); ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater,suffix:px"), "set_progress", "get_progress"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_less,or_greater,suffix:px"), "set_progress", "get_progress"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_less,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotates"), "set_rotates", "is_rotating"); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 43158344b4..714d196779 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1024,7 +1024,7 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,1000,0.01,or_greater,exp,suffix:kg"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inertia", PROPERTY_HINT_RANGE, U"0,1000,0.01,or_greater,exp,suffix:kg\u22C5px\u00B2"), "set_inertia", "get_inertia"); ADD_PROPERTY(PropertyInfo(Variant::INT, "center_of_mass_mode", PROPERTY_HINT_ENUM, "Auto,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_center_of_mass_mode", "get_center_of_mass_mode"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_lesser,or_greater,suffix:px"), "set_center_of_mass", "get_center_of_mass"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_less,or_greater,suffix:px"), "set_center_of_mass", "get_center_of_mass"); ADD_LINKED_PROPERTY("center_of_mass_mode", "center_of_mass"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); @@ -1142,7 +1142,7 @@ bool CharacterBody2D::move_and_slide() { on_ceiling = false; on_wall = false; - if (!current_platform_velocity.is_equal_approx(Vector2())) { + if (!current_platform_velocity.is_zero_approx()) { PhysicsServer2D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin); parameters.recovery_as_collision = true; // Also report collisions generated only from recovery. parameters.exclude_bodies.insert(platform_rid); @@ -1241,7 +1241,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo break; } - if (result.remainder.is_equal_approx(Vector2())) { + if (result.remainder.is_zero_approx()) { motion = Vector2(); break; } @@ -1325,7 +1325,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo sliding_enabled = true; first_slide = false; - if (!collided || motion.is_equal_approx(Vector2())) { + if (!collided || motion.is_zero_approx()) { break; } } @@ -1371,7 +1371,7 @@ void CharacterBody2D::_move_and_slide_floating(double p_delta) { motion_results.push_back(result); _set_collision_direction(result); - if (result.remainder.is_equal_approx(Vector2())) { + if (result.remainder.is_zero_approx()) { motion = Vector2(); break; } @@ -1390,7 +1390,7 @@ void CharacterBody2D::_move_and_slide_floating(double p_delta) { } } - if (!collided || motion.is_equal_approx(Vector2())) { + if (!collided || motion.is_zero_approx()) { break; } diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 111a0df89a..5e77902977 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -640,7 +640,7 @@ void Polygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_texture_offset", "get_texture_offset"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale", PROPERTY_HINT_LINK), "set_texture_scale", "get_texture_scale"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_texture_rotation", "get_texture_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_texture_rotation", "get_texture_rotation"); ADD_GROUP("Skeleton", ""); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton"); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 129cce93fa..5de6d547d7 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -34,6 +34,10 @@ #include "scene/resources/world_2d.h" #include "servers/navigation_server_2d.h" +#ifdef DEBUG_ENABLED +#include "servers/navigation_server_3d.h" +#endif // DEBUG_ENABLED + HashMap<Vector2i, TileSet::CellNeighbor> TileMap::TerrainConstraint::get_overlapping_coords_and_peering_bits() const { HashMap<Vector2i, TileSet::CellNeighbor> output; @@ -828,13 +832,13 @@ void TileMap::_update_dirty_quadrants() { // Update the coords cache. for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) { - q->self()->map_to_world.clear(); - q->self()->world_to_map.clear(); + q->self()->map_to_local.clear(); + q->self()->local_to_map.clear(); for (const Vector2i &E : q->self()->cells) { Vector2i pk = E; - Vector2i pk_world_coords = map_to_world(pk); - q->self()->map_to_world[pk] = pk_world_coords; - q->self()->world_to_map[pk_world_coords] = pk; + Vector2i pk_local_coords = map_to_local(pk); + q->self()->map_to_local[pk] = pk_local_coords; + q->self()->local_to_map[pk_local_coords] = pk; } } @@ -852,7 +856,7 @@ void TileMap::_update_dirty_quadrants() { for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) { rs->canvas_item_clear(q->self()->debug_canvas_item); Transform2D xform; - xform.set_origin(map_to_world(q->self()->coords * get_effective_quadrant_size(layer))); + xform.set_origin(map_to_local(q->self()->coords * get_effective_quadrant_size(layer))); rs->canvas_item_set_transform(q->self()->debug_canvas_item, xform); _rendering_draw_quadrant_debug(q->self()); @@ -978,10 +982,10 @@ void TileMap::_recompute_rect_cache() { for (unsigned int layer = 0; layer < layers.size(); layer++) { for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { Rect2 r; - r.position = map_to_world(E.key * get_effective_quadrant_size(layer)); - r.expand_to(map_to_world((E.key + Vector2i(1, 0)) * get_effective_quadrant_size(layer))); - r.expand_to(map_to_world((E.key + Vector2i(1, 1)) * get_effective_quadrant_size(layer))); - r.expand_to(map_to_world((E.key + Vector2i(0, 1)) * get_effective_quadrant_size(layer))); + r.position = map_to_local(E.key * get_effective_quadrant_size(layer)); + r.expand_to(map_to_local((E.key + Vector2i(1, 0)) * get_effective_quadrant_size(layer))); + r.expand_to(map_to_local((E.key + Vector2i(1, 1)) * get_effective_quadrant_size(layer))); + r.expand_to(map_to_local((E.key + Vector2i(0, 1)) * get_effective_quadrant_size(layer))); if (first) { r_total = r; first = false; @@ -1010,7 +1014,7 @@ void TileMap::_rendering_notification(int p_what) { TileMapQuadrant &q = E_quadrant.value; // Update occluders transform. - for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { + for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) { Transform2D xform; xform.set_origin(E_cell.key); for (const RID &occluder : q.occluders) { @@ -1030,7 +1034,7 @@ void TileMap::_rendering_notification(int p_what) { TileMapQuadrant &q = E_quadrant.value; // Update occluders transform. - for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { + for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) { Transform2D xform; xform.set_origin(E_cell.key); for (const RID &occluder : q.occluders) { @@ -1126,7 +1130,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List } // Iterate over the cells of the quadrant. - for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { + for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) { TileMapCell c = get_cell(q.layer, E_cell.value, true); TileSetSource *source; @@ -1151,7 +1155,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List int z_index = tile_data->get_z_index(); // Quandrant pos. - Vector2 position = map_to_world(q.coords * get_effective_quadrant_size(q.layer)); + Vector2 position = map_to_local(q.coords * get_effective_quadrant_size(q.layer)); if (is_y_sort_enabled() && layers[q.layer].y_sort_enabled) { // When Y-sorting, the quandrant size is sure to be 1, we can thus offset the CanvasItem. position.y += layers[q.layer].y_sort_origin + tile_data->get_y_sort_origin(); @@ -1223,14 +1227,14 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List int index = -(int64_t)0x80000000; //always must be drawn below children. for (int layer = 0; layer < (int)layers.size(); layer++) { - // Sort the quadrants coords per world coordinates - RBMap<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator> world_to_map; + // Sort the quadrants coords per local coordinates. + RBMap<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator> local_to_map; for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { - world_to_map[map_to_world(E.key)] = E.key; + local_to_map[map_to_local(E.key)] = E.key; } - // Sort the quadrants - for (const KeyValue<Vector2i, Vector2i> &E : world_to_map) { + // Sort the quadrants. + for (const KeyValue<Vector2i, Vector2i> &E : local_to_map) { TileMapQuadrant &q = layers[layer].quadrant_map[E.value]; for (const RID &ci : q.canvas_items) { RS::get_singleton()->canvas_item_set_draw_index(ci, index++); @@ -1270,7 +1274,7 @@ void TileMap::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { // Draw a placeholder for scenes needing one. RenderingServer *rs = RenderingServer::get_singleton(); - Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); + Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); for (const Vector2i &E_cell : p_quadrant->cells) { const TileMapCell &c = get_cell(p_quadrant->layer, E_cell, true); @@ -1302,7 +1306,7 @@ void TileMap::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { // Draw a placeholder tile. Transform2D xform; - xform.set_origin(map_to_world(E_cell) - quadrant_pos); + xform.set_origin(map_to_local(E_cell) - quadrant_pos); rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color); } @@ -1423,7 +1427,7 @@ void TileMap::_physics_notification(int p_what) { for (RID body : q.bodies) { Transform2D xform; - xform.set_origin(map_to_world(bodies_coords[body])); + xform.set_origin(map_to_local(bodies_coords[body])); xform = global_transform * xform; PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); } @@ -1446,7 +1450,7 @@ void TileMap::_physics_notification(int p_what) { for (RID body : q.bodies) { Transform2D xform; - xform.set_origin(map_to_world(bodies_coords[body])); + xform.set_origin(map_to_local(bodies_coords[body])); xform = new_transform * xform; PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); @@ -1516,7 +1520,7 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r ps->body_set_space(body, space); Transform2D xform; - xform.set_origin(map_to_world(E_cell)); + xform.set_origin(map_to_local(E_cell)); xform = global_transform * xform; ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); @@ -1602,7 +1606,7 @@ void TileMap::_physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { Vector<Color> color; color.push_back(debug_collision_color); - Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); + Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); Transform2D qudrant_xform; qudrant_xform.set_origin(quadrant_pos); Transform2D global_transform_inv = (get_global_transform() * qudrant_xform).affine_inverse(); @@ -1641,7 +1645,7 @@ void TileMap::_navigation_notification(int p_what) { continue; } Transform2D tile_transform; - tile_transform.set_origin(map_to_world(E_region.key)); + tile_transform.set_origin(map_to_local(E_region.key)); NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform); } } @@ -1656,14 +1660,6 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List ERR_FAIL_COND(!is_inside_tree()); ERR_FAIL_COND(!tile_set.is_valid()); - // Get colors for debug. - SceneTree *st = SceneTree::get_singleton(); - Color debug_navigation_color; - bool debug_navigation = st && st->is_debugging_navigation_hint(); - if (debug_navigation) { - debug_navigation_color = st->get_debug_navigation_color(); - } - Transform2D tilemap_xform = get_global_transform(); SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first(); while (q_list_element) { @@ -1709,7 +1705,7 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List if (navpoly.is_valid()) { Transform2D tile_transform; - tile_transform.set_origin(map_to_world(E_cell)); + tile_transform.set_origin(map_to_local(E_cell)); RID region = NavigationServer2D::get_singleton()->region_create(); NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); @@ -1766,10 +1762,13 @@ void TileMap::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { RenderingServer *rs = RenderingServer::get_singleton(); - Color color = get_tree()->get_debug_navigation_color(); + Color color = Color(0.5, 1.0, 1.0, 1.0); +#ifdef DEBUG_ENABLED + color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color(); +#endif // DEBUG_ENABLED RandomPCG rand; - Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); + Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); for (const Vector2i &E_cell : p_quadrant->cells) { TileMapCell c = get_cell(p_quadrant->layer, E_cell, true); @@ -1792,7 +1791,7 @@ void TileMap::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { } Transform2D xform; - xform.set_origin(map_to_world(E_cell) - quadrant_pos); + xform.set_origin(map_to_local(E_cell) - quadrant_pos); rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); for (int layer_index = 0; layer_index < tile_set->get_navigation_layers_count(); layer_index++) { @@ -1866,10 +1865,10 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_ Control *scene_as_control = Object::cast_to<Control>(scene); Node2D *scene_as_node2d = Object::cast_to<Node2D>(scene); if (scene_as_control) { - scene_as_control->set_position(map_to_world(E_cell) + scene_as_control->get_position()); + scene_as_control->set_position(map_to_local(E_cell) + scene_as_control->get_position()); } else if (scene_as_node2d) { Transform2D xform; - xform.set_origin(map_to_world(E_cell)); + xform.set_origin(map_to_local(E_cell)); scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform()); } q.scenes[E_cell] = scene->get_name(); @@ -1903,7 +1902,7 @@ void TileMap::_scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { // Draw a placeholder for scenes needing one. RenderingServer *rs = RenderingServer::get_singleton(); - Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); + Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); for (const Vector2i &E_cell : p_quadrant->cells) { const TileMapCell &c = get_cell(p_quadrant->layer, E_cell, true); @@ -1933,7 +1932,7 @@ void TileMap::_scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { // Draw a placeholder tile. Transform2D xform; - xform.set_origin(map_to_world(E_cell) - quadrant_pos); + xform.set_origin(map_to_local(E_cell) - quadrant_pos); rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color); } @@ -2822,7 +2821,7 @@ void TileMap::_build_runtime_update_tile_data(SelfList<TileMapQuadrant>::List &r while (q_list_element) { TileMapQuadrant &q = *q_list_element->self(); // Iterate over the cells of the quadrant. - for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { + for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) { TileMapCell c = get_cell(q.layer, E_cell.value, true); TileSetSource *source; @@ -2981,7 +2980,7 @@ void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { } } -Vector2 TileMap::map_to_world(const Vector2i &p_pos) const { +Vector2 TileMap::map_to_local(const Vector2i &p_pos) const { // SHOULD RETURN THE CENTER OF THE CELL ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2()); @@ -3058,10 +3057,10 @@ Vector2 TileMap::map_to_world(const Vector2i &p_pos) const { return (ret + Vector2(0.5, 0.5)) * tile_set->get_tile_size(); } -Vector2i TileMap::world_to_map(const Vector2 &p_pos) const { +Vector2i TileMap::local_to_map(const Vector2 &p_local_position) const { ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2i()); - Vector2 ret = p_pos; + Vector2 ret = p_local_position; ret /= tile_set->get_tile_size(); TileSet::TileShape tile_shape = tile_set->get_tile_shape(); @@ -3086,7 +3085,7 @@ Vector2i TileMap::world_to_map(const Vector2 &p_pos) const { ret.x /= overlapping_ratio; } - // For each half-offset shape, we check if we are in the corner of the tile, and thus should correct the world position accordingly. + // For each half-offset shape, we check if we are in the corner of the tile, and thus should correct the local position accordingly. if (tile_shape == TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE || tile_shape == TileSet::TILE_SHAPE_HEXAGON || tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) { // Technically, those 3 shapes are equivalent, as they are basically half-offset, but with different levels or overlap. // square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap @@ -3771,7 +3770,7 @@ void TileMap::draw_cells_outline(Control *p_control, RBSet<Vector2i> p_cells, Co TileSet::TileShape shape = tile_set->get_tile_shape(); for (const Vector2i &E : p_cells) { - Vector2 center = map_to_world(E); + Vector2 center = map_to_local(E); #define DRAW_SIDE_IF_NEEDED(side, polygon_index_from, polygon_index_to) \ if (!p_cells.has(get_neighbor_cell(E, side))) { \ @@ -3901,8 +3900,8 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("get_used_cells", "layer"), &TileMap::get_used_cells); ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect); - ClassDB::bind_method(D_METHOD("map_to_world", "map_position"), &TileMap::map_to_world); - ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &TileMap::world_to_map); + ClassDB::bind_method(D_METHOD("map_to_local", "map_position"), &TileMap::map_to_local); + ClassDB::bind_method(D_METHOD("local_to_map", "local_position"), &TileMap::local_to_map); ClassDB::bind_method(D_METHOD("get_neighbor_cell", "coords", "neighbor"), &TileMap::get_neighbor_cell); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index ecc6ee1d59..a819eeab71 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -40,7 +40,7 @@ class TileSetAtlasSource; struct TileMapQuadrant { struct CoordsWorldComparator { _ALWAYS_INLINE_ bool operator()(const Vector2i &p_a, const Vector2i &p_b) const { - // We sort the cells by their world coords, as it is needed by rendering. + // We sort the cells by their local coords, as it is needed by rendering. if (p_a.y == p_b.y) { return p_a.x > p_b.x; } else { @@ -49,7 +49,7 @@ struct TileMapQuadrant { } }; - // Dirty list element + // Dirty list element. SelfList<TileMapQuadrant> dirty_list_element; // Quadrant layer and coords. @@ -58,10 +58,10 @@ struct TileMapQuadrant { // TileMapCells RBSet<Vector2i> cells; - // We need those two maps to sort by world position for rendering + // We need those two maps to sort by local position for rendering // This is kind of workaround, it would be better to sort the cells directly in the "cells" set instead. - RBMap<Vector2i, Vector2i> map_to_world; - RBMap<Vector2i, Vector2i, CoordsWorldComparator> world_to_map; + RBMap<Vector2i, Vector2i> map_to_local; + RBMap<Vector2i, Vector2i, CoordsWorldComparator> local_to_map; // Debug. RID debug_canvas_item; @@ -368,8 +368,8 @@ public: virtual void set_y_sort_enabled(bool p_enable) override; - Vector2 map_to_world(const Vector2i &p_pos) const; - Vector2i world_to_map(const Vector2 &p_pos) const; + Vector2 map_to_local(const Vector2i &p_pos) const; + Vector2i local_to_map(const Vector2 &p_pos) const; bool is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const; Vector2i get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const; diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index db7c3233f6..f118080009 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -473,19 +473,19 @@ bool Area3D::is_monitoring() const { } TypedArray<Node3D> Area3D::get_overlapping_bodies() const { - ERR_FAIL_COND_V(!monitoring, Array()); - Array ret; + TypedArray<Node3D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping bodies when monitoring is off."); ret.resize(body_map.size()); int idx = 0; for (const KeyValue<ObjectID, BodyState> &E : body_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } + ret.resize(idx); return ret; } @@ -506,19 +506,18 @@ bool Area3D::is_monitorable() const { } TypedArray<Area3D> Area3D::get_overlapping_areas() const { - ERR_FAIL_COND_V(!monitoring, Array()); - Array ret; + TypedArray<Area3D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping areas when monitoring is off."); ret.resize(area_map.size()); int idx = 0; for (const KeyValue<ObjectID, AreaState> &E : area_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } - + ret.resize(idx); return ret; } @@ -728,7 +727,7 @@ void Area3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:m"), "set_gravity_point_center", "get_gravity_point_center"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_direction"), "set_gravity_direction", "get_gravity_direction"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-32,32,0.001,or_lesser,or_greater,suffix:m/s\u00B2"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-32,32,0.001,or_less,or_greater,suffix:m/s\u00B2"), "set_gravity", "get_gravity"); ADD_GROUP("Linear Damp", "linear_damp_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_linear_damp_space_override_mode", "get_linear_damp_space_override_mode"); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 0e7b71f74a..21cf3bdb3b 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -247,13 +247,18 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (autoplay && !Engine::get_singleton()->is_editor_hint()) { play(); } + set_stream_paused(false); } break; case NOTIFICATION_EXIT_TREE: { - stop(); + set_stream_paused(true); AudioServer::get_singleton()->remove_listener_changed_callback(_listener_changed_cb, this); } break; + case NOTIFICATION_PREDELETE: { + stop(); + } break; + case NOTIFICATION_PAUSED: { if (!can_process()) { // Node can't process so we start fading out to silence. diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index e14bb1aa94..d7bf76a6f6 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -1568,32 +1568,32 @@ void CPUParticles3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE); @@ -1613,8 +1613,8 @@ void CPUParticles3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 1cfd889272..24bfa7b6de 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -807,7 +807,7 @@ void GPUParticlesAttractor3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_directionality", "amount"), &GPUParticlesAttractor3D::set_directionality); ClassDB::bind_method(D_METHOD("get_directionality"), &GPUParticlesAttractor3D::get_directionality); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "-128,128,0.01,or_greater,or_lesser"), "set_strength", "get_strength"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "-128,128,0.01,or_greater,or_less"), "set_strength", "get_strength"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation", PROPERTY_HINT_EXP_EASING, "0,8,0.01"), "set_attenuation", "get_attenuation"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "directionality", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_directionality", "get_directionality"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp index d5cab6728a..7dc094062b 100644 --- a/scene/3d/joint_3d.cpp +++ b/scene/3d/joint_3d.cpp @@ -309,7 +309,7 @@ void HingeJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_RELAXATION); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "motor/enable"), "set_flag", "get_flag", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/target_velocity", PROPERTY_HINT_RANGE, "-200,200,0.01,or_greater,or_lesser,suffix:m/s"), "set_param", "get_param", PARAM_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/target_velocity", PROPERTY_HINT_RANGE, "-200,200,0.01,or_greater,or_less,suffix:m/s"), "set_param", "get_param", PARAM_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/max_impulse", PROPERTY_HINT_RANGE, "0.01,1024,0.01"), "set_param", "get_param", PARAM_MOTOR_MAX_IMPULSE); BIND_ENUM_CONSTANT(PARAM_BIAS); diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 41a537f7cb..b0bccc4571 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -105,6 +105,7 @@ void LightmapGIData::_set_light_textures_data(const Array &p_data) { Vector<Ref<Image>> images; for (int i = 0; i < p_data.size(); i++) { Ref<TextureLayered> texture = p_data[i]; + ERR_FAIL_COND_MSG(texture.is_null(), vformat("Invalid TextureLayered at index %d.", i)); for (int j = 0; j < texture->get_layers(); j++) { images.push_back(texture->get_layer_data(j)); } @@ -765,11 +766,11 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa MeshesFound &mf = meshes_found.write[m_i]; Size2i lightmap_size = mf.mesh->get_lightmap_size_hint() * mf.lightmap_scale; - Vector<RID> overrides; + TypedArray<RID> overrides; overrides.resize(mf.overrides.size()); for (int i = 0; i < mf.overrides.size(); i++) { if (mf.overrides[i].is_valid()) { - overrides.write[i] = mf.overrides[i]->get_rid(); + overrides[i] = mf.overrides[i]->get_rid(); } } TypedArray<Image> images = RS::get_singleton()->bake_render_uv2(mf.mesh->get_rid(), overrides, lightmap_size); diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index 953e52e591..9b49238333 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -37,6 +37,9 @@ void NavigationObstacle3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rid"), &NavigationObstacle3D::get_rid); + ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationObstacle3D::set_navigation_map); + ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationObstacle3D::get_navigation_map); + ClassDB::bind_method(D_METHOD("set_estimate_radius", "estimate_radius"), &NavigationObstacle3D::set_estimate_radius); ClassDB::bind_method(D_METHOD("is_radius_estimated"), &NavigationObstacle3D::is_radius_estimated); ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationObstacle3D::set_radius); @@ -56,28 +59,26 @@ void NavigationObstacle3D::_validate_property(PropertyInfo &p_property) const { void NavigationObstacle3D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - parent_node3d = Object::cast_to<Node3D>(get_parent()); - reevaluate_agent_radius(); - if (parent_node3d != nullptr) { - // place agent on navigation map first or else the RVO agent callback creation fails silently later - NavigationServer3D::get_singleton()->agent_set_map(get_rid(), parent_node3d->get_world_3d()->get_navigation_map()); - } + case NOTIFICATION_POST_ENTER_TREE: { + set_agent_parent(get_parent()); set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { - parent_node3d = nullptr; + set_agent_parent(nullptr); set_physics_process_internal(false); } break; case NOTIFICATION_PARENTED: { - parent_node3d = Object::cast_to<Node3D>(get_parent()); - reevaluate_agent_radius(); + if (is_inside_tree() && (get_parent() != parent_node3d)) { + set_agent_parent(get_parent()); + set_physics_process_internal(true); + } } break; case NOTIFICATION_UNPARENTED: { - parent_node3d = nullptr; + set_agent_parent(nullptr); + set_physics_process_internal(false); } break; case NOTIFICATION_PAUSED: { @@ -189,6 +190,35 @@ real_t NavigationObstacle3D::estimate_agent_radius() const { return 1.0; // Never a 0 radius } +void NavigationObstacle3D::set_agent_parent(Node *p_agent_parent) { + if (Object::cast_to<Node3D>(p_agent_parent) != nullptr) { + parent_node3d = Object::cast_to<Node3D>(p_agent_parent); + if (map_override.is_valid()) { + NavigationServer3D::get_singleton()->agent_set_map(get_rid(), map_override); + } else { + NavigationServer3D::get_singleton()->agent_set_map(get_rid(), parent_node3d->get_world_3d()->get_navigation_map()); + } + reevaluate_agent_radius(); + } else { + parent_node3d = nullptr; + NavigationServer3D::get_singleton()->agent_set_map(get_rid(), RID()); + } +} + +void NavigationObstacle3D::set_navigation_map(RID p_navigation_map) { + map_override = p_navigation_map; + NavigationServer3D::get_singleton()->agent_set_map(agent, map_override); +} + +RID NavigationObstacle3D::get_navigation_map() const { + if (map_override.is_valid()) { + return map_override; + } else if (parent_node3d != nullptr) { + return parent_node3d->get_world_3d()->get_navigation_map(); + } + return RID(); +} + void NavigationObstacle3D::set_estimate_radius(bool p_estimate_radius) { estimate_radius = p_estimate_radius; notify_property_list_changed(); diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index 7f6af668b6..24caf50680 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -37,8 +37,10 @@ class NavigationObstacle3D : public Node { GDCLASS(NavigationObstacle3D, Node); Node3D *parent_node3d = nullptr; + RID agent; RID map_before_pause; + RID map_override; bool estimate_radius = true; real_t radius = 1.0; @@ -56,6 +58,11 @@ public: return agent; } + void set_agent_parent(Node *p_agent_parent); + + void set_navigation_map(RID p_navigation_map); + RID get_navigation_map() const; + void set_estimate_radius(bool p_estimate_radius); bool is_radius_estimated() const { return estimate_radius; diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 29ad1ba93d..049ca4c8a0 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -539,6 +539,7 @@ void NavigationRegion3D::_update_debug_edge_connections_mesh() { } Vector<Vector3> vertex_array; + vertex_array.resize(connections_count * 6); for (int i = 0; i < connections_count; i++) { Vector3 connection_pathway_start = NavigationServer3D::get_singleton()->region_get_connection_pathway_start(region, i); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 426a8c1684..59ec036558 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -792,8 +792,8 @@ void Node3D::look_at(const Vector3 &p_target, const Vector3 &p_up) { void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up) { ERR_FAIL_COND_MSG(p_pos.is_equal_approx(p_target), "Node origin and target are in the same position, look_at() failed."); - ERR_FAIL_COND_MSG(p_up.is_equal_approx(Vector3()), "The up vector can't be zero, look_at() failed."); - ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos).is_equal_approx(Vector3()), "Up vector and direction between node origin and target are aligned, look_at() failed."); + ERR_FAIL_COND_MSG(p_up.is_zero_approx(), "The up vector can't be zero, look_at() failed."); + ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos).is_zero_approx(), "Up vector and direction between node origin and target are aligned, look_at() failed."); Transform3D lookat = Transform3D(Basis::looking_at(p_target - p_pos, p_up), p_pos); Vector3 original_scale = get_scale(); @@ -1052,8 +1052,8 @@ void Node3D::_bind_methods() { ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_greater,or_lesser,no_slider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_greater,or_less,no_slider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "quaternion", PROPERTY_HINT_HIDE_QUATERNION_EDIT, "", PROPERTY_USAGE_EDITOR), "set_quaternion", "get_quaternion"); ADD_PROPERTY(PropertyInfo(Variant::BASIS, "basis", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_basis", "get_basis"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_LINK, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale"); diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 3d23206e6b..2d1f4a579b 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -337,7 +337,7 @@ void PathFollow3D::_validate_property(PropertyInfo &p_property) const { max = path->get_curve()->get_baked_length(); } - p_property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater"; + p_property.hint_string = "0," + rtos(max) + ",0.01,or_less,or_greater"; } } @@ -380,8 +380,8 @@ void PathFollow3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop", "loop"), &PathFollow3D::set_loop); ClassDB::bind_method(D_METHOD("has_loop"), &PathFollow3D::has_loop); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater,suffix:m"), "set_progress", "get_progress"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_less,or_greater,suffix:m"), "set_progress", "get_progress"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_less,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ,Oriented"), "set_rotation_mode", "get_rotation_mode"); diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 5534bc28f1..8888aa183a 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -1088,7 +1088,7 @@ void RigidBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,1000,0.01,or_greater,exp,suffix:kg"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "inertia", PROPERTY_HINT_RANGE, U"0,1000,0.01,or_greater,exp,suffix:kg\u22C5m\u00B2"), "set_inertia", "get_inertia"); ADD_PROPERTY(PropertyInfo(Variant::INT, "center_of_mass_mode", PROPERTY_HINT_ENUM, "Auto,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_center_of_mass_mode", "get_center_of_mass_mode"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_lesser,or_greater,suffix:m"), "set_center_of_mass", "get_center_of_mass"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_less,or_greater,suffix:m"), "set_center_of_mass", "get_center_of_mass"); ADD_LINKED_PROPERTY("center_of_mass_mode", "center_of_mass"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); @@ -1208,7 +1208,7 @@ bool CharacterBody3D::move_and_slide() { last_motion = Vector3(); - if (!current_platform_velocity.is_equal_approx(Vector3())) { + if (!current_platform_velocity.is_zero_approx()) { PhysicsServer3D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin); parameters.recovery_as_collision = true; // Also report collisions generated only from recovery. @@ -1315,7 +1315,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo break; } - if (result.remainder.is_equal_approx(Vector3())) { + if (result.remainder.is_zero_approx()) { motion = Vector3(); break; } @@ -1428,7 +1428,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo const PhysicsServer3D::MotionCollision &collision = result.collisions[0]; Vector3 slide_motion = result.remainder.slide(collision.normal); - if (collision_state.floor && !collision_state.wall && !motion_slide_up.is_equal_approx(Vector3())) { + if (collision_state.floor && !collision_state.wall && !motion_slide_up.is_zero_approx()) { // Slide using the intersection between the motion plane and the floor plane, // in order to keep the direction intact. real_t motion_length = slide_motion.length(); @@ -1469,7 +1469,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo total_travel += result.travel; // Apply Constant Speed. - if (p_was_on_floor && floor_constant_speed && can_apply_constant_speed && collision_state.floor && !motion.is_equal_approx(Vector3())) { + if (p_was_on_floor && floor_constant_speed && can_apply_constant_speed && collision_state.floor && !motion.is_zero_approx()) { Vector3 travel_slide_up = total_travel.slide(up_direction); motion = motion.normalized() * MAX(0, (motion_slide_up.length() - travel_slide_up.length())); } @@ -1492,7 +1492,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo collided = true; } - if (!collided || motion.is_equal_approx(Vector3())) { + if (!collided || motion.is_zero_approx()) { break; } @@ -1533,7 +1533,7 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) { CollisionState result_state; _set_collision_direction(result, result_state); - if (result.remainder.is_equal_approx(Vector3())) { + if (result.remainder.is_zero_approx()) { motion = Vector3(); break; } @@ -1557,7 +1557,7 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) { } } - if (!collided || motion.is_equal_approx(Vector3())) { + if (!collided || motion.is_zero_approx()) { break; } @@ -2346,7 +2346,7 @@ void PhysicalBone3D::ConeJointData::_get_property_list(List<PropertyInfo> *p_lis JointData::_get_property_list(p_list); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/swing_span"), PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/twist_span"), PROPERTY_HINT_RANGE, "-40000,40000,0.1,or_lesser,or_greater")); + p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/twist_span"), PROPERTY_HINT_RANGE, "-40000,40000,0.1,or_less,or_greater")); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/bias"), PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/softness"), PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/relaxation"), PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); @@ -2997,7 +2997,7 @@ void PhysicalBone3D::_bind_methods() { ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_joint_offset", "get_joint_offset"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_RANGE, "-360,360,0.01,or_lesser,or_greater,radians"), "set_joint_rotation", "get_joint_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_RANGE, "-360,360,0.01,or_less,or_greater,radians"), "set_joint_rotation", "get_joint_rotation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "body_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_body_offset", "get_body_offset"); diff --git a/scene/3d/shape_cast_3d.cpp b/scene/3d/shape_cast_3d.cpp index d324e09df5..a2fecf9c31 100644 --- a/scene/3d/shape_cast_3d.cpp +++ b/scene/3d/shape_cast_3d.cpp @@ -205,7 +205,7 @@ bool ShapeCast3D::is_enabled() const { void ShapeCast3D::set_target_position(const Vector3 &p_point) { target_position = p_point; - if (is_inside_tree()) { + if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) { _update_debug_shape(); } update_gizmos(); @@ -306,7 +306,7 @@ real_t ShapeCast3D::get_closest_collision_unsafe_fraction() const { } void ShapeCast3D::resource_changed(Ref<Resource> p_res) { - if (is_inside_tree()) { + if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) { _update_debug_shape(); } update_gizmos(); @@ -327,7 +327,7 @@ void ShapeCast3D::set_shape(const Ref<Shape3D> &p_shape) { shape_rid = shape->get_rid(); } - if (is_inside_tree()) { + if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) { _update_debug_shape(); } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 5af06cff29..db9f68544b 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -242,7 +242,7 @@ const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringNa bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { const StringName *r = _instance_uniform_get_remap(p_name); if (r) { - set_instance_shader_uniform(*r, p_value); + set_instance_shader_parameter(*r, p_value); return true; } #ifndef DISABLE_DEPRECATED @@ -262,7 +262,7 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { const StringName *r = _instance_uniform_get_remap(p_name); if (r) { - r_ret = get_instance_shader_uniform(*r); + r_ret = get_instance_shader_parameter(*r); return true; } @@ -271,10 +271,10 @@ bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> pinfo; - RS::get_singleton()->instance_geometry_get_shader_uniform_list(get_instance(), &pinfo); + RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); for (PropertyInfo &pi : pinfo) { bool has_def_value = false; - Variant def_value = RS::get_singleton()->instance_geometry_get_shader_uniform_default_value(get_instance(), pi.name); + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); if (def_value.get_type() != Variant::NIL) { has_def_value = true; } @@ -319,24 +319,24 @@ float GeometryInstance3D::get_lod_bias() const { return lod_bias; } -void GeometryInstance3D::set_instance_shader_uniform(const StringName &p_uniform, const Variant &p_value) { +void GeometryInstance3D::set_instance_shader_parameter(const StringName &p_name, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { - Variant def_value = RS::get_singleton()->instance_geometry_get_shader_uniform_default_value(get_instance(), p_uniform); - RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, def_value); + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_name); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, def_value); instance_uniforms.erase(p_value); } else { - instance_uniforms[p_uniform] = p_value; + instance_uniforms[p_name] = p_value; if (p_value.get_type() == Variant::OBJECT) { RID tex_id = p_value; - RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, tex_id); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, tex_id); } else { - RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, p_value); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, p_value); } } } -Variant GeometryInstance3D::get_instance_shader_uniform(const StringName &p_uniform) const { - return RS::get_singleton()->instance_geometry_get_shader_uniform(get_instance(), p_uniform); +Variant GeometryInstance3D::get_instance_shader_parameter(const StringName &p_name) const { + return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_name); } void GeometryInstance3D::set_custom_aabb(AABB aabb) { @@ -434,8 +434,8 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_visibility_range_fade_mode", "mode"), &GeometryInstance3D::set_visibility_range_fade_mode); ClassDB::bind_method(D_METHOD("get_visibility_range_fade_mode"), &GeometryInstance3D::get_visibility_range_fade_mode); - ClassDB::bind_method(D_METHOD("set_instance_shader_uniform", "uniform", "value"), &GeometryInstance3D::set_instance_shader_uniform); - ClassDB::bind_method(D_METHOD("get_instance_shader_uniform", "uniform"), &GeometryInstance3D::get_instance_shader_uniform); + ClassDB::bind_method(D_METHOD("set_instance_shader_parameter", "name", "value"), &GeometryInstance3D::set_instance_shader_parameter); + ClassDB::bind_method(D_METHOD("get_instance_shader_parameter", "name"), &GeometryInstance3D::get_instance_shader_parameter); ClassDB::bind_method(D_METHOD("set_extra_cull_margin", "margin"), &GeometryInstance3D::set_extra_cull_margin); ClassDB::bind_method(D_METHOD("get_extra_cull_margin"), &GeometryInstance3D::get_extra_cull_margin); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index f7cdcbf411..100d8d8836 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -178,8 +178,8 @@ public: void set_lightmap_scale(LightmapScale p_scale); LightmapScale get_lightmap_scale() const; - void set_instance_shader_uniform(const StringName &p_uniform, const Variant &p_value); - Variant get_instance_shader_uniform(const StringName &p_uniform) const; + void set_instance_shader_parameter(const StringName &p_name, const Variant &p_value); + Variant get_instance_shader_parameter(const StringName &p_name) const; void set_custom_aabb(AABB aabb); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 3d81b6b9e8..99f17a1eef 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -542,7 +542,7 @@ AnimationNodeBlend3::AnimationNodeBlend3() { ///////////////////////////////// void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "-32,32,0.01,or_lesser,or_greater")); + r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "-32,32,0.01,or_less,or_greater")); } Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 073f61bfdd..096f4edee2 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -323,7 +323,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov #endif // _3D_DISABLED if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) { - child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed).bind(child), CONNECT_ONESHOT); + child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed).bind(child), CONNECT_ONE_SHOT); } TrackNodeCacheKey key; diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 04feb0dc6f..03115e765f 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -40,6 +40,7 @@ void AudioStreamPlayer::_notification(int p_what) { if (autoplay && !Engine::get_singleton()->is_editor_hint()) { play(); } + set_stream_paused(false); } break; case NOTIFICATION_INTERNAL_PROCESS: { @@ -64,6 +65,10 @@ void AudioStreamPlayer::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { + set_stream_paused(true); + } break; + + case NOTIFICATION_PREDELETE: { for (Ref<AudioStreamPlayback> &playback : stream_playbacks) { AudioServer::get_singleton()->stop_playback_stream(playback); } diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index 22c8f2cd4e..151b0b93d4 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -291,7 +291,7 @@ Size2 BoxContainer::get_minimum_size() const { void BoxContainer::_update_theme_item_cache() { Container::_update_theme_item_cache(); - theme_cache.separation = get_theme_constant(SNAME("separation")); //,vertical?"VBoxContainer":"HBoxContainer"); + theme_cache.separation = get_theme_constant(SNAME("separation")); } void BoxContainer::_notification(int p_what) { @@ -311,6 +311,12 @@ void BoxContainer::_notification(int p_what) { } } +void BoxContainer::_validate_property(PropertyInfo &p_property) const { + if (is_fixed && p_property.name == "vertical") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + void BoxContainer::set_alignment(AlignmentMode p_alignment) { if (alignment == p_alignment) { return; @@ -323,6 +329,17 @@ BoxContainer::AlignmentMode BoxContainer::get_alignment() const { return alignment; } +void BoxContainer::set_vertical(bool p_vertical) { + ERR_FAIL_COND_MSG(is_fixed, "Can't change orientation of " + get_class() + "."); + vertical = p_vertical; + update_minimum_size(); + _resort(); +} + +bool BoxContainer::is_vertical() const { + return vertical; +} + Control *BoxContainer::add_spacer(bool p_begin) { Control *c = memnew(Control); c->set_mouse_filter(MOUSE_FILTER_PASS); //allow spacer to pass mouse events @@ -371,14 +388,17 @@ BoxContainer::BoxContainer(bool p_vertical) { void BoxContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("add_spacer", "begin"), &BoxContainer::add_spacer); - ClassDB::bind_method(D_METHOD("get_alignment"), &BoxContainer::get_alignment); ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &BoxContainer::set_alignment); + ClassDB::bind_method(D_METHOD("get_alignment"), &BoxContainer::get_alignment); + ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &BoxContainer::set_vertical); + ClassDB::bind_method(D_METHOD("is_vertical"), &BoxContainer::is_vertical); BIND_ENUM_CONSTANT(ALIGNMENT_BEGIN); BIND_ENUM_CONSTANT(ALIGNMENT_CENTER); BIND_ENUM_CONSTANT(ALIGNMENT_END); ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment", "get_alignment"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); } MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control *p_control, bool p_expand) { diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h index 55dfb2ada7..0ee5bd1772 100644 --- a/scene/gui/box_container.h +++ b/scene/gui/box_container.h @@ -54,9 +54,12 @@ private: void _resort(); protected: + bool is_fixed = false; + virtual void _update_theme_item_cache() override; void _notification(int p_what); + void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); public: @@ -65,6 +68,9 @@ public: void set_alignment(AlignmentMode p_alignment); AlignmentMode get_alignment() const; + void set_vertical(bool p_vertical); + bool is_vertical() const; + virtual Size2 get_minimum_size() const override; virtual Vector<int> get_allowed_size_flags_horizontal() const override; @@ -78,7 +84,7 @@ class HBoxContainer : public BoxContainer { public: HBoxContainer() : - BoxContainer(false) {} + BoxContainer(false) { is_fixed = true; } }; class MarginContainer; @@ -89,7 +95,7 @@ public: MarginContainer *add_margin_child(const String &p_label, Control *p_control, bool p_expand = false); VBoxContainer() : - BoxContainer(true) {} + BoxContainer(true) { is_fixed = true; } }; VARIANT_ENUM_CAST(BoxContainer::AlignmentMode); diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 37db7d53f0..f5eb0b957f 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -77,7 +77,7 @@ void CheckBox::_update_theme_item_cache() { Button::_update_theme_item_cache(); theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); - theme_cache.check_v_adjust = get_theme_constant(SNAME("check_v_adjust")); + theme_cache.check_v_offset = get_theme_constant(SNAME("check_v_offset")); theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); theme_cache.checked = get_theme_icon(SNAME("checked")); @@ -134,7 +134,7 @@ void CheckBox::_notification(int p_what) { } else { ofs.x = theme_cache.normal_style->get_margin(SIDE_LEFT); } - ofs.y = int((get_size().height - get_icon_size().height) / 2) + theme_cache.check_v_adjust; + ofs.y = int((get_size().height - get_icon_size().height) / 2) + theme_cache.check_v_offset; if (is_pressed()) { on_tex->draw(ci, ofs); diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h index beafece3dc..8438d0e589 100644 --- a/scene/gui/check_box.h +++ b/scene/gui/check_box.h @@ -38,7 +38,7 @@ class CheckBox : public Button { struct ThemeCache { int h_separation = 0; - int check_v_adjust = 0; + int check_v_offset = 0; Ref<StyleBox> normal_style; Ref<Texture2D> checked; diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index b01081e31b..9466512699 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -82,17 +82,17 @@ void CheckButton::_update_theme_item_cache() { Button::_update_theme_item_cache(); theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); - theme_cache.check_v_adjust = get_theme_constant(SNAME("check_v_adjust")); + theme_cache.check_v_offset = get_theme_constant(SNAME("check_v_offset")); theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); - theme_cache.checked = get_theme_icon(SNAME("on")); - theme_cache.unchecked = get_theme_icon(SNAME("off")); - theme_cache.checked_disabled = get_theme_icon(SNAME("on_disabled")); - theme_cache.unchecked_disabled = get_theme_icon(SNAME("off_disabled")); - theme_cache.checked_mirrored = get_theme_icon(SNAME("on_mirrored")); - theme_cache.unchecked_mirrored = get_theme_icon(SNAME("off_mirrored")); - theme_cache.checked_disabled_mirrored = get_theme_icon(SNAME("on_disabled_mirrored")); - theme_cache.unchecked_disabled_mirrored = get_theme_icon(SNAME("off_disabled_mirrored")); + theme_cache.checked = get_theme_icon(SNAME("checked")); + theme_cache.unchecked = get_theme_icon(SNAME("unchecked")); + theme_cache.checked_disabled = get_theme_icon(SNAME("checked_disabled")); + theme_cache.unchecked_disabled = get_theme_icon(SNAME("unchecked_disabled")); + theme_cache.checked_mirrored = get_theme_icon(SNAME("checked_mirrored")); + theme_cache.unchecked_mirrored = get_theme_icon(SNAME("unchecked_mirrored")); + theme_cache.checked_disabled_mirrored = get_theme_icon(SNAME("checked_disabled_mirrored")); + theme_cache.unchecked_disabled_mirrored = get_theme_icon(SNAME("unchecked_disabled_mirrored")); } void CheckButton::_notification(int p_what) { @@ -142,7 +142,7 @@ void CheckButton::_notification(int p_what) { } else { ofs.x = get_size().width - (tex_size.width + theme_cache.normal_style->get_margin(SIDE_RIGHT)); } - ofs.y = (get_size().height - tex_size.height) / 2 + theme_cache.check_v_adjust; + ofs.y = (get_size().height - tex_size.height) / 2 + theme_cache.check_v_offset; if (is_pressed()) { on_tex->draw(ci, ofs); diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h index e71472c870..3878c9628a 100644 --- a/scene/gui/check_button.h +++ b/scene/gui/check_button.h @@ -38,7 +38,7 @@ class CheckButton : public Button { struct ThemeCache { int h_separation = 0; - int check_v_adjust = 0; + int check_v_offset = 0; Ref<StyleBox> normal_style; Ref<Texture2D> checked; diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 1ef1801457..f6e0e4216d 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -344,7 +344,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } } else { if (mb->get_button_index() == MouseButton::LEFT) { - if (mb->is_command_pressed() && !symbol_lookup_word.is_empty()) { + if (mb->is_command_or_control_pressed() && !symbol_lookup_word.is_empty()) { Vector2i mpos = mb->get_position(); if (is_layout_rtl()) { mpos.x = get_size().x - mpos.x; @@ -371,7 +371,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } if (symbol_lookup_on_click_enabled) { - if (mm->is_command_pressed() && mm->get_button_mask() == MouseButton::NONE && !is_dragging_cursor()) { + if (mm->is_command_or_control_pressed() && mm->get_button_mask() == MouseButton::NONE && !is_dragging_cursor()) { symbol_lookup_new_word = get_word_at_pos(mpos); if (symbol_lookup_new_word != symbol_lookup_word) { emit_signal(SNAME("symbol_validate"), symbol_lookup_new_word); @@ -432,7 +432,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { /* Allow unicode handling if: */ /* No Modifiers are pressed (except shift) */ - bool allow_unicode_handling = !(k->is_command_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); + bool allow_unicode_handling = !(k->is_command_or_control_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); /* AUTO-COMPLETE */ if (code_completion_enabled && k->is_action("ui_text_completion_query", true)) { diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 3030fdff8d..4a1f2ab7c6 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -853,7 +853,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) { } else if (p_which == 2) { c->draw_rect(Rect2(Point2(), c->get_size()), Color(1, 1, 1)); if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) { - circle_mat->set_shader_uniform("v", v); + circle_mat->set_shader_parameter("v", v); } } } @@ -1086,7 +1086,7 @@ void ColorPicker::_screen_pick_pressed() { } else { screen->show(); } - screen->raise(); + screen->move_to_front(); #ifndef _MSC_VER #warning show modal no longer works, needs to be converted to a popup #endif diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 06819283fa..347fe9aa11 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -44,6 +44,7 @@ #include "scene/main/window.h" #include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" +#include "scene/theme/theme_owner.h" #include "servers/rendering_server.h" #include "servers/text_server.h" @@ -1563,7 +1564,7 @@ Size2 Control::get_minimum_size() const { return Vector2(); } -void Control::set_custom_minimum_size(const Size2 &p_custom) { +void Control::set_custom_minimum_size(const Size2i &p_custom) { if (p_custom == data.custom_minimum_size) { return; } @@ -1571,7 +1572,7 @@ void Control::set_custom_minimum_size(const Size2 &p_custom) { update_minimum_size(); } -Size2 Control::get_custom_minimum_size() const { +Size2i Control::get_custom_minimum_size() const { return data.custom_minimum_size; } @@ -2261,57 +2262,9 @@ bool Control::is_clipping_contents() { // Theming. -void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_notify, bool p_assign) { - Control *c = Object::cast_to<Control>(p_at); - Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr; - - if (!c && !w) { - // Theme inheritance chains are broken by nodes that aren't Control or Window. - return; - } - - bool assign = p_assign; - if (c) { - if (c != p_owner && c->data.theme.is_valid()) { - // Has a theme, so we don't want to change the theme owner, - // but we still want to propagate in case this child has theme items - // it inherits from the theme this node uses. - // See https://github.com/godotengine/godot/issues/62844. - assign = false; - } - - if (assign) { - c->data.theme_owner = p_owner; - c->data.theme_owner_window = p_owner_window; - } - - if (p_notify) { - c->notification(Control::NOTIFICATION_THEME_CHANGED); - } - } else if (w) { - if (w != p_owner_window && w->theme.is_valid()) { - // Same as above. - assign = false; - } - - if (assign) { - w->theme_owner = p_owner; - w->theme_owner_window = p_owner_window; - } - - if (p_notify) { - w->notification(Window::NOTIFICATION_THEME_CHANGED); - } - } - - for (int i = 0; i < p_at->get_child_count(); i++) { - _propagate_theme_changed(p_at->get_child(i), p_owner, p_owner_window, p_notify, assign); - } -} - void Control::_theme_changed() { if (is_inside_tree()) { - _propagate_theme_changed(this, this, nullptr, true, false); + data.theme_owner->propagate_theme_changed(this, this, true, false); } } @@ -2333,6 +2286,18 @@ void Control::_invalidate_theme_cache() { void Control::_update_theme_item_cache() { } +void Control::set_theme_owner_node(Node *p_node) { + data.theme_owner->set_owner_node(p_node); +} + +Node *Control::get_theme_owner_node() const { + return data.theme_owner->get_owner_node(); +} + +bool Control::has_theme_owner_node() const { + return data.theme_owner->has_owner_node(); +} + void Control::set_theme(const Ref<Theme> &p_theme) { if (data.theme == p_theme) { return; @@ -2344,24 +2309,24 @@ void Control::set_theme(const Ref<Theme> &p_theme) { data.theme = p_theme; if (data.theme.is_valid()) { - _propagate_theme_changed(this, this, nullptr, is_inside_tree(), true); + data.theme_owner->propagate_theme_changed(this, this, is_inside_tree(), true); data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), CONNECT_DEFERRED); return; } Control *parent_c = Object::cast_to<Control>(get_parent()); - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - _propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window, is_inside_tree(), true); + if (parent_c && parent_c->has_theme_owner_node()) { + data.theme_owner->propagate_theme_changed(this, parent_c->get_theme_owner_node(), is_inside_tree(), true); return; } Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - _propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window, is_inside_tree(), true); + if (parent_w && parent_w->has_theme_owner_node()) { + data.theme_owner->propagate_theme_changed(this, parent_w->get_theme_owner_node(), is_inside_tree(), true); return; } - _propagate_theme_changed(this, nullptr, nullptr, is_inside_tree(), true); + data.theme_owner->propagate_theme_changed(this, nullptr, is_inside_tree(), true); } Ref<Theme> Control::get_theme() const { @@ -2384,130 +2349,6 @@ StringName Control::get_theme_type_variation() const { /// Theme property lookup. -template <class T> -T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { - return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(p_data_type, p_name, E); - } - } - } - - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { - return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, E); - } - } - // If they don't exist, use any type to return the default/empty value. - return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, p_theme_types[0]); -} - -bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - } - - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - return false; -} - -void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(data.theme_type_variation) != StringName()) { - ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); - } - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list); - } -} - Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); @@ -2521,8 +2362,8 @@ Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringNam } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<Texture2D> icon = get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Texture2D> icon = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); data.theme_icon_cache[p_theme_type][p_name] = icon; return icon; } @@ -2540,8 +2381,8 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<StyleBox> style = get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<StyleBox> style = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); data.theme_style_cache[p_theme_type][p_name] = style; return style; } @@ -2559,8 +2400,8 @@ Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_ } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<Font> font = get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Font> font = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); data.theme_font_cache[p_theme_type][p_name] = font; return font; } @@ -2578,8 +2419,8 @@ int Control::get_theme_font_size(const StringName &p_name, const StringName &p_t } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - int font_size = get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int font_size = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); data.theme_font_size_cache[p_theme_type][p_name] = font_size; return font_size; } @@ -2597,8 +2438,8 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_the } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Color color = get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Color color = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); data.theme_color_cache[p_theme_type][p_name] = color; return color; } @@ -2616,8 +2457,8 @@ int Control::get_theme_constant(const StringName &p_name, const StringName &p_th } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - int constant = get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int constant = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); data.theme_constant_cache[p_theme_type][p_name] = constant; return constant; } @@ -2630,8 +2471,8 @@ bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); } bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { @@ -2642,8 +2483,8 @@ bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_t } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { @@ -2654,8 +2495,8 @@ bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); } bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { @@ -2666,8 +2507,8 @@ bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_ } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { @@ -2678,8 +2519,8 @@ bool Control::has_theme_color(const StringName &p_name, const StringName &p_them } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); } bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { @@ -2690,8 +2531,8 @@ bool Control::has_theme_constant(const StringName &p_name, const StringName &p_t } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } /// Local property overrides. @@ -2821,157 +2662,16 @@ bool Control::has_theme_constant_override(const StringName &p_name) const { /// Default theme properties. -float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_base_scale()) { - return theme_owner->data.theme->get_default_base_scale(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) { - return theme_owner_window->theme->get_default_base_scale(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - if (ThemeDB::get_singleton()->get_project_theme()->has_default_base_scale()) { - return ThemeDB::get_singleton()->get_project_theme()->get_default_base_scale(); - } - } - - // Lastly, fall back on the default Theme. - if (ThemeDB::get_singleton()->get_default_theme()->has_default_base_scale()) { - return ThemeDB::get_singleton()->get_default_theme()->get_default_base_scale(); - } - return ThemeDB::get_singleton()->get_fallback_base_scale(); -} - float Control::get_theme_default_base_scale() const { - return fetch_theme_default_base_scale(data.theme_owner, data.theme_owner_window); -} - -Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font()) { - return theme_owner->data.theme->get_default_font(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font()) { - return theme_owner_window->theme->get_default_font(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - if (ThemeDB::get_singleton()->get_project_theme()->has_default_font()) { - return ThemeDB::get_singleton()->get_project_theme()->get_default_font(); - } - } - - // Lastly, fall back on the default Theme. - if (ThemeDB::get_singleton()->get_default_theme()->has_default_font()) { - return ThemeDB::get_singleton()->get_default_theme()->get_default_font(); - } - return ThemeDB::get_singleton()->get_fallback_font(); + return data.theme_owner->get_theme_default_base_scale(); } Ref<Font> Control::get_theme_default_font() const { - return fetch_theme_default_font(data.theme_owner, data.theme_owner_window); -} - -int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font_size()) { - return theme_owner->data.theme->get_default_font_size(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) { - return theme_owner_window->theme->get_default_font_size(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - if (ThemeDB::get_singleton()->get_project_theme()->has_default_font_size()) { - return ThemeDB::get_singleton()->get_project_theme()->get_default_font_size(); - } - } - - // Lastly, fall back on the default Theme. - if (ThemeDB::get_singleton()->get_default_theme()->has_default_font_size()) { - return ThemeDB::get_singleton()->get_default_theme()->get_default_font_size(); - } - return ThemeDB::get_singleton()->get_fallback_font_size(); + return data.theme_owner->get_theme_default_font(); } int Control::get_theme_default_font_size() const { - return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window); + return data.theme_owner->get_theme_default_font_size(); } /// Bulk actions. @@ -3089,21 +2789,6 @@ Control *Control::make_custom_tooltip(const String &p_text) const { // Base object overrides. -void Control::add_child_notify(Node *p_child) { - // We propagate when this node uses a custom theme, so it can pass it on to its children. - if (data.theme_owner || data.theme_owner_window) { - // `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`. - _propagate_theme_changed(p_child, data.theme_owner, data.theme_owner_window, false, true); - } -} - -void Control::remove_child_notify(Node *p_child) { - // If the removed child isn't inheriting any theme items through this node, then there's no need to propagate. - if (data.theme_owner || data.theme_owner_window) { - _propagate_theme_changed(p_child, nullptr, nullptr, false, true); - } -} - void Control::_notification(int p_notification) { switch (p_notification) { case NOTIFICATION_POSTINITIALIZE: { @@ -3111,10 +2796,16 @@ void Control::_notification(int p_notification) { _update_theme_item_cache(); } break; + case NOTIFICATION_PARENTED: { + data.theme_owner->assign_theme_on_parented(this); + } break; + + case NOTIFICATION_UNPARENTED: { + data.theme_owner->clear_theme_on_unparented(this); + } break; + case NOTIFICATION_ENTER_TREE: { - // Need to defer here, because theme owner information might be set in - // add_child_notify, which doesn't get called until right after this. - call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED); + notification(NOTIFICATION_THEME_CHANGED); } break; case NOTIFICATION_POST_ENTER_TREE: { @@ -3130,7 +2821,7 @@ void Control::_notification(int p_notification) { case NOTIFICATION_READY: { #ifdef DEBUG_ENABLED - connect("ready", callable_mp(this, &Control::_clear_size_warning), CONNECT_DEFERRED | CONNECT_ONESHOT); + connect("ready", callable_mp(this, &Control::_clear_size_warning), CONNECT_DEFERRED | CONNECT_ONE_SHOT); #endif } break; @@ -3441,7 +3132,7 @@ void Control::_bind_methods() { ADD_GROUP("Layout", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_contents"), "set_clip_contents", "is_clipping_contents"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode"); ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION); @@ -3455,10 +3146,10 @@ void Control::_bind_methods() { ADD_PROPERTY_DEFAULT("anchors_preset", -1); ADD_SUBGROUP_INDENT("Anchor Points", "anchor_", 1); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_BOTTOM); ADD_SUBGROUP_INDENT("Anchor Offsets", "offset_", 1); ADD_PROPERTYI(PropertyInfo(Variant::INT, "offset_left", PROPERTY_HINT_RANGE, "-4096,4096,suffix:px"), "set_offset", "get_offset", SIDE_LEFT); @@ -3474,7 +3165,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "_set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_NONE), "_set_global_position", "get_global_position"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pivot_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_pivot_offset", "get_pivot_offset"); @@ -3611,7 +3302,13 @@ void Control::_bind_methods() { GDVIRTUAL_BIND(_gui_input, "event"); } +Control::Control() { + data.theme_owner = memnew(ThemeOwner); +} + Control::~Control() { + memdelete(data.theme_owner); + // Resources need to be disconnected. for (KeyValue<StringName, Ref<Texture2D>> &E : data.icon_override) { E.value->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); diff --git a/scene/gui/control.h b/scene/gui/control.h index ac5d481f3a..38cafd835a 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -41,6 +41,7 @@ class Viewport; class Label; class Panel; +class ThemeOwner; class Control : public CanvasItem { GDCLASS(Control, CanvasItem); @@ -199,7 +200,7 @@ private: int h_size_flags = SIZE_FILL; int v_size_flags = SIZE_FILL; real_t expand = 1.0; - Point2 custom_minimum_size; + Point2i custom_minimum_size; // Input events and rendering. @@ -219,9 +220,8 @@ private: // Theming. + ThemeOwner *theme_owner = nullptr; Ref<Theme> theme; - Control *theme_owner = nullptr; - Window *theme_owner_window = nullptr; StringName theme_type_variation; bool bulk_theme_override = false; @@ -261,7 +261,6 @@ private: // Global relations. friend class Viewport; - friend class Window; // Positioning and sizing. @@ -303,13 +302,6 @@ private: void _notify_theme_override_changed(); void _invalidate_theme_cache(); - static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_notify, bool p_assign); - - template <class T> - static T get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); - static bool has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); - _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; - // Extra properties. String get_tooltip_text() const; @@ -335,9 +327,6 @@ protected: // Base object overrides. - virtual void add_child_notify(Node *p_child) override; - virtual void remove_child_notify(Node *p_child) override; - void _notification(int p_notification); static void _bind_methods(); @@ -471,8 +460,8 @@ public: virtual Size2 get_minimum_size() const; virtual Size2 get_combined_minimum_size() const; - void set_custom_minimum_size(const Size2 &p_custom); - Size2 get_custom_minimum_size() const; + void set_custom_minimum_size(const Size2i &p_custom); + Size2i get_custom_minimum_size() const; // Container sizing. @@ -542,6 +531,10 @@ public: // Theming. + void set_theme_owner_node(Node *p_node); + Node *get_theme_owner_node() const; + bool has_theme_owner_node() const; + void set_theme(const Ref<Theme> &p_theme); Ref<Theme> get_theme() const; @@ -586,10 +579,6 @@ public: bool has_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const; bool has_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const; - static float fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window); - static Ref<Font> fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window); - static int fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window); - float get_theme_default_base_scale() const; Ref<Font> get_theme_default_font() const; int get_theme_default_font_size() const; @@ -612,7 +601,7 @@ public: virtual String get_tooltip(const Point2 &p_pos) const; virtual Control *make_custom_tooltip(const String &p_text) const; - Control() {} + Control(); ~Control(); }; diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 0a1aeeda71..f5edaf02d8 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -54,16 +54,23 @@ void AcceptDialog::_update_theme_item_cache() { Window::_update_theme_item_cache(); theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); - theme_cache.margin = get_theme_constant(SNAME("margin")); - theme_cache.button_margin = get_theme_constant(SNAME("button_margin")); + theme_cache.buttons_separation = get_theme_constant(SNAME("buttons_separation")); } void AcceptDialog::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_VISIBILITY_CHANGED: { + case NOTIFICATION_POST_ENTER_TREE: { if (is_visible()) { get_ok_button()->grab_focus(); + } + } break; + case NOTIFICATION_VISIBILITY_CHANGED: { + if (is_visible()) { + if (get_ok_button()->is_inside_tree()) { + get_ok_button()->grab_focus(); + } _update_child_rects(); + parent_visible = get_parent_visible_window(); if (parent_visible) { parent_visible->connect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused)); @@ -77,10 +84,12 @@ void AcceptDialog::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - bg->add_theme_style_override("panel", theme_cache.panel_style); + bg_panel->add_theme_style_override("panel", theme_cache.panel_style); - label->set_begin(Point2(theme_cache.margin, theme_cache.margin)); - label->set_end(Point2(-theme_cache.margin, -theme_cache.button_margin - 10)); + child_controls_changed(); + if (is_visible()) { + _update_child_rects(); + } } break; case NOTIFICATION_EXIT_TREE: { @@ -137,14 +146,16 @@ void AcceptDialog::_cancel_pressed() { } String AcceptDialog::get_text() const { - return label->get_text(); + return message_label->get_text(); } void AcceptDialog::set_text(String p_text) { - if (label->get_text() == p_text) { + if (message_label->get_text() == p_text) { return; } - label->set_text(p_text); + + message_label->set_text(p_text); + child_controls_changed(); if (is_visible()) { _update_child_rects(); @@ -168,19 +179,24 @@ bool AcceptDialog::get_close_on_escape() const { } void AcceptDialog::set_autowrap(bool p_autowrap) { - label->set_autowrap_mode(p_autowrap ? TextServer::AUTOWRAP_WORD : TextServer::AUTOWRAP_OFF); + message_label->set_autowrap_mode(p_autowrap ? TextServer::AUTOWRAP_WORD : TextServer::AUTOWRAP_OFF); } bool AcceptDialog::has_autowrap() { - return label->get_autowrap_mode() != TextServer::AUTOWRAP_OFF; + return message_label->get_autowrap_mode() != TextServer::AUTOWRAP_OFF; } void AcceptDialog::set_ok_button_text(String p_ok_button_text) { - ok->set_text(p_ok_button_text); + ok_button->set_text(p_ok_button_text); + + child_controls_changed(); + if (is_visible()) { + _update_child_rects(); + } } String AcceptDialog::get_ok_button_text() const { - return ok->get_text(); + return ok_button->get_text(); } void AcceptDialog::register_text_enter(Control *p_line_edit) { @@ -192,68 +208,79 @@ void AcceptDialog::register_text_enter(Control *p_line_edit) { } void AcceptDialog::_update_child_rects() { - Size2 label_size = label->get_minimum_size(); - if (label->get_text().is_empty()) { - label_size.height = 0; - } - Size2 size = get_size(); - Size2 hminsize = hbc->get_combined_minimum_size(); + float h_margins = theme_cache.panel_style->get_margin(SIDE_LEFT) + theme_cache.panel_style->get_margin(SIDE_RIGHT); + float v_margins = theme_cache.panel_style->get_margin(SIDE_TOP) + theme_cache.panel_style->get_margin(SIDE_BOTTOM); - Vector2 cpos(theme_cache.margin, theme_cache.margin + label_size.height); - Vector2 csize(size.x - theme_cache.margin * 2, size.y - theme_cache.margin * 3 - hminsize.y - label_size.height); + // Fill the entire size of the window with the background. + bg_panel->set_position(Point2()); + bg_panel->set_size(size); + + // Place the buttons from the bottom edge to their minimum required size. + Size2 buttons_minsize = buttons_hbox->get_combined_minimum_size(); + Size2 buttons_size = Size2(size.x - h_margins, buttons_minsize.y); + Point2 buttons_position = Point2(theme_cache.panel_style->get_margin(SIDE_LEFT), size.y - theme_cache.panel_style->get_margin(SIDE_BOTTOM) - buttons_size.y); + buttons_hbox->set_position(buttons_position); + buttons_hbox->set_size(buttons_size); + + // Place the content from the top to fill the rest of the space (minus the separation). + Point2 content_position = Point2(theme_cache.panel_style->get_margin(SIDE_LEFT), theme_cache.panel_style->get_margin(SIDE_TOP)); + Size2 content_size = Size2(size.x - h_margins, size.y - v_margins - buttons_size.y - theme_cache.buttons_separation); for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); if (!c) { continue; } - - if (c == hbc || c == label || c == bg || c->is_set_as_top_level()) { + if (c == buttons_hbox || c == bg_panel || c->is_set_as_top_level()) { continue; } - c->set_position(cpos); - c->set_size(csize); + c->set_position(content_position); + c->set_size(content_size); } - - cpos.y += csize.y + theme_cache.margin; - csize.y = hminsize.y; - - hbc->set_position(cpos); - hbc->set_size(csize); - - bg->set_position(Point2()); - bg->set_size(size); } Size2 AcceptDialog::_get_contents_minimum_size() const { - Size2 minsize = label->get_combined_minimum_size(); - + // First, we then iterate over the label and any other custom controls + // to try and find the size that encompasses all content. + Size2 content_minsize; for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); if (!c) { continue; } - if (c == hbc || c == label || c->is_set_as_top_level()) { + // Buttons will be included afterwards. + // The panel only displays the stylebox and doesn't contribute to the size. + if (c == buttons_hbox || c == bg_panel || c->is_set_as_top_level()) { continue; } - Size2 cminsize = c->get_combined_minimum_size(); - minsize.x = MAX(cminsize.x, minsize.x); - minsize.y = MAX(cminsize.y, minsize.y); + Size2 child_minsize = c->get_combined_minimum_size(); + content_minsize.x = MAX(child_minsize.x, content_minsize.x); + content_minsize.y = MAX(child_minsize.y, content_minsize.y); + } + + // Then we take the background panel as it provides the offsets, + // which are always added to the minimum size. + if (theme_cache.panel_style.is_valid()) { + content_minsize += theme_cache.panel_style->get_minimum_size(); } - Size2 hminsize = hbc->get_combined_minimum_size(); - minsize.x = MAX(hminsize.x, minsize.x); - minsize.y += hminsize.y; - minsize.x += theme_cache.margin * 2; - minsize.y += theme_cache.margin * 3; //one as separation between hbc and child + // Then we add buttons. Horizontally we're interested in whichever + // value is the biggest. Vertically buttons add to the overall size. + Size2 buttons_minsize = buttons_hbox->get_combined_minimum_size(); + content_minsize.x = MAX(buttons_minsize.x, content_minsize.x); + content_minsize.y += buttons_minsize.y; + // Plus there is a separation size added on top. + content_minsize.y += theme_cache.buttons_separation; - Size2 wmsize = get_min_size(); - minsize.x = MAX(wmsize.x, minsize.x); - return minsize; + // Last, we make sure that we aren't below the minimum window size. + Size2 window_minsize = get_min_size(); + content_minsize.x = MAX(window_minsize.x, content_minsize.x); + content_minsize.y = MAX(window_minsize.y, content_minsize.y); + return content_minsize; } void AcceptDialog::_custom_action(const String &p_action) { @@ -264,13 +291,19 @@ void AcceptDialog::_custom_action(const String &p_action) { Button *AcceptDialog::add_button(const String &p_text, bool p_right, const String &p_action) { Button *button = memnew(Button); button->set_text(p_text); + if (p_right) { - hbc->add_child(button); - hbc->add_spacer(); + buttons_hbox->add_child(button); + buttons_hbox->add_spacer(); } else { - hbc->add_child(button); - hbc->move_child(button, 0); - hbc->add_spacer(true); + buttons_hbox->add_child(button); + buttons_hbox->move_child(button, 0); + buttons_hbox->add_spacer(true); + } + + child_controls_changed(); + if (is_visible()) { + _update_child_rects(); } if (!p_action.is_empty()) { @@ -285,24 +318,19 @@ Button *AcceptDialog::add_cancel_button(const String &p_cancel) { if (p_cancel.is_empty()) { c = "Cancel"; } + Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c); + b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed)); + return b; } void AcceptDialog::remove_button(Control *p_button) { Button *button = Object::cast_to<Button>(p_button); ERR_FAIL_NULL(button); - ERR_FAIL_COND_MSG(button->get_parent() != hbc, vformat("Cannot remove button %s as it does not belong to this dialog.", button->get_name())); - ERR_FAIL_COND_MSG(button == ok, "Cannot remove dialog's OK button."); - - Node *right_spacer = hbc->get_child(button->get_index() + 1); - // Should always be valid but let's avoid crashing - if (right_spacer) { - hbc->remove_child(right_spacer); - memdelete(right_spacer); - } - hbc->remove_child(button); + ERR_FAIL_COND_MSG(button->get_parent() != buttons_hbox, vformat("Cannot remove button %s as it does not belong to this dialog.", button->get_name())); + ERR_FAIL_COND_MSG(button == ok_button, "Cannot remove dialog's OK button."); if (button->is_connected("pressed", callable_mp(this, &AcceptDialog::_custom_action))) { button->disconnect("pressed", callable_mp(this, &AcceptDialog::_custom_action)); @@ -310,6 +338,19 @@ void AcceptDialog::remove_button(Control *p_button) { if (button->is_connected("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed))) { button->disconnect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed)); } + + Node *right_spacer = buttons_hbox->get_child(button->get_index() + 1); + // Should always be valid but let's avoid crashing. + if (right_spacer) { + buttons_hbox->remove_child(right_spacer); + memdelete(right_spacer); + } + buttons_hbox->remove_child(button); + + child_controls_changed(); + if (is_visible()) { + _update_child_rects(); + } } void AcceptDialog::_bind_methods() { @@ -355,25 +396,25 @@ AcceptDialog::AcceptDialog() { set_exclusive(true); set_clamp_to_embedder(true); - bg = memnew(Panel); - add_child(bg, false, INTERNAL_MODE_FRONT); + bg_panel = memnew(Panel); + add_child(bg_panel, false, INTERNAL_MODE_FRONT); - hbc = memnew(HBoxContainer); + buttons_hbox = memnew(HBoxContainer); - label = memnew(Label); - label->set_anchor(SIDE_RIGHT, Control::ANCHOR_END); - label->set_anchor(SIDE_BOTTOM, Control::ANCHOR_END); - add_child(label, false, INTERNAL_MODE_FRONT); + message_label = memnew(Label); + message_label->set_anchor(SIDE_RIGHT, Control::ANCHOR_END); + message_label->set_anchor(SIDE_BOTTOM, Control::ANCHOR_END); + add_child(message_label, false, INTERNAL_MODE_FRONT); - add_child(hbc, false, INTERNAL_MODE_FRONT); + add_child(buttons_hbox, false, INTERNAL_MODE_FRONT); - hbc->add_spacer(); - ok = memnew(Button); - ok->set_text("OK"); - hbc->add_child(ok); - hbc->add_spacer(); + buttons_hbox->add_spacer(); + ok_button = memnew(Button); + ok_button->set_text("OK"); + buttons_hbox->add_child(ok_button); + buttons_hbox->add_spacer(); - ok->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed)); + ok_button->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed)); set_title(TTRC("Alert!")); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 8ba9c93861..81e82d851e 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -45,17 +45,18 @@ class AcceptDialog : public Window { GDCLASS(AcceptDialog, Window); Window *parent_visible = nullptr; - Panel *bg = nullptr; - HBoxContainer *hbc = nullptr; - Label *label = nullptr; - Button *ok = nullptr; + + Panel *bg_panel = nullptr; + Label *message_label = nullptr; + HBoxContainer *buttons_hbox = nullptr; + Button *ok_button = nullptr; + bool hide_on_ok = true; bool close_on_escape = true; struct ThemeCache { Ref<StyleBox> panel_style; - int margin = 0; - int button_margin = 0; + int buttons_separation = 0; } theme_cache; void _custom_action(const String &p_action); @@ -82,12 +83,12 @@ protected: void _cancel_pressed(); public: - Label *get_label() { return label; } + Label *get_label() { return message_label; } static void set_swap_cancel_ok(bool p_swap); void register_text_enter(Control *p_line_edit); - Button *get_ok_button() { return ok; } + Button *get_ok_button() { return ok_button; } Button *add_button(const String &p_text, bool p_right = false, const String &p_action = ""); Button *add_cancel_button(const String &p_cancel = ""); void remove_button(Control *p_button); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index a0cf5f5970..57f27e299f 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -70,9 +70,9 @@ void FileDialog::_update_theme_item_cache() { theme_cache.folder = get_theme_icon(SNAME("folder")); theme_cache.file = get_theme_icon(SNAME("file")); - theme_cache.folder_icon_modulate = get_theme_color(SNAME("folder_icon_modulate")); - theme_cache.file_icon_modulate = get_theme_color(SNAME("file_icon_modulate")); - theme_cache.files_disabled = get_theme_color(SNAME("files_disabled")); + theme_cache.folder_icon_color = get_theme_color(SNAME("folder_icon_color")); + theme_cache.file_icon_color = get_theme_color(SNAME("file_icon_color")); + theme_cache.file_disabled_color = get_theme_color(SNAME("file_disabled_color")); // TODO: Define own colors? theme_cache.icon_normal_color = get_theme_color(SNAME("font_color"), SNAME("Button")); @@ -87,6 +87,8 @@ void FileDialog::_notification(int p_what) { if (!is_visible()) { set_process_shortcut_input(false); } + + invalidate(); // Put it here to preview in the editor. } break; case NOTIFICATION_THEME_CHANGED: { @@ -143,7 +145,7 @@ void FileDialog::shortcut_input(const Ref<InputEvent> &p_event) { switch (k->get_keycode()) { case Key::H: { - if (k->is_command_pressed()) { + if (k->is_command_or_control_pressed()) { set_show_hidden_files(!show_hidden_files); } else { handled = false; @@ -223,10 +225,6 @@ void FileDialog::_save_confirm_pressed() { void FileDialog::_post_popup() { ConfirmationDialog::_post_popup(); - if (invalidated) { - update_file_list(); - invalidated = false; - } if (mode == FILE_MODE_SAVE_FILE) { file->grab_focus(); } else { @@ -552,7 +550,7 @@ void FileDialog::update_file_list() { TreeItem *ti = tree->create_item(root); ti->set_text(0, dir_name); ti->set_icon(0, theme_cache.folder); - ti->set_icon_modulate(0, theme_cache.folder_icon_modulate); + ti->set_icon_modulate(0, theme_cache.folder_icon_color); Dictionary d; d["name"] = dir_name; @@ -613,10 +611,10 @@ void FileDialog::update_file_list() { } else { ti->set_icon(0, theme_cache.file); } - ti->set_icon_modulate(0, theme_cache.file_icon_modulate); + ti->set_icon_modulate(0, theme_cache.file_icon_color); if (mode == FILE_MODE_OPEN_DIR) { - ti->set_custom_color(0, theme_cache.files_disabled); + ti->set_custom_color(0, theme_cache.file_disabled_color); ti->set_selectable(0, false); } Dictionary d; diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 5c892288b5..1add0a9cf5 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -118,9 +118,9 @@ private: Ref<Texture2D> folder; Ref<Texture2D> file; - Color folder_icon_modulate; - Color file_icon_modulate; - Color files_disabled; + Color folder_icon_color; + Color file_icon_color; + Color file_disabled_color; Color icon_normal_color; Color icon_hover_color; diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp index ca230b8e81..b0d15aa7f4 100644 --- a/scene/gui/flow_container.cpp +++ b/scene/gui/flow_container.cpp @@ -272,14 +272,36 @@ void FlowContainer::_notification(int p_what) { } } +void FlowContainer::_validate_property(PropertyInfo &p_property) const { + if (is_fixed && p_property.name == "vertical") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + int FlowContainer::get_line_count() const { return cached_line_count; } +void FlowContainer::set_vertical(bool p_vertical) { + ERR_FAIL_COND_MSG(is_fixed, "Can't change orientation of " + get_class() + "."); + vertical = p_vertical; + update_minimum_size(); + _resort(); +} + +bool FlowContainer::is_vertical() const { + return vertical; +} + FlowContainer::FlowContainer(bool p_vertical) { vertical = p_vertical; } void FlowContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_line_count"), &FlowContainer::get_line_count); + + ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &FlowContainer::set_vertical); + ClassDB::bind_method(D_METHOD("is_vertical"), &FlowContainer::is_vertical); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); } diff --git a/scene/gui/flow_container.h b/scene/gui/flow_container.h index 2cdf7d7c37..536df27ad6 100644 --- a/scene/gui/flow_container.h +++ b/scene/gui/flow_container.h @@ -50,14 +50,20 @@ private: void _resort(); protected: + bool is_fixed = false; + virtual void _update_theme_item_cache() override; void _notification(int p_what); + void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); public: int get_line_count() const; + void set_vertical(bool p_vertical); + bool is_vertical() const; + virtual Size2 get_minimum_size() const override; virtual Vector<int> get_allowed_size_flags_horizontal() const override; @@ -71,7 +77,7 @@ class HFlowContainer : public FlowContainer { public: HFlowContainer() : - FlowContainer(false) {} + FlowContainer(false) { is_fixed = true; } }; class VFlowContainer : public FlowContainer { @@ -79,7 +85,7 @@ class VFlowContainer : public FlowContainer { public: VFlowContainer() : - FlowContainer(true) {} + FlowContainer(true) { is_fixed = true; } }; #endif // FLOW_CONTAINER_H diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 8c16f8ca26..69512903b4 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -351,9 +351,22 @@ void GraphEdit::_graph_node_raised(Node *p_gn) { if (gn->is_comment()) { move_child(gn, 0); } else { - gn->raise(); + gn->move_to_front(); } - emit_signal(SNAME("node_selected"), p_gn); +} + +void GraphEdit::_graph_node_selected(Node *p_gn) { + GraphNode *gn = Object::cast_to<GraphNode>(p_gn); + ERR_FAIL_COND(!gn); + + emit_signal(SNAME("node_selected"), gn); +} + +void GraphEdit::_graph_node_deselected(Node *p_gn) { + GraphNode *gn = Object::cast_to<GraphNode>(p_gn); + ERR_FAIL_COND(!gn); + + emit_signal(SNAME("node_deselected"), gn); } void GraphEdit::_graph_node_moved(Node *p_gn) { @@ -383,6 +396,8 @@ void GraphEdit::add_child_notify(Node *p_child) { if (gn) { gn->set_scale(Vector2(zoom, zoom)); gn->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved).bind(gn)); + gn->connect("selected", callable_mp(this, &GraphEdit::_graph_node_selected).bind(gn)); + gn->connect("deselected", callable_mp(this, &GraphEdit::_graph_node_deselected).bind(gn)); gn->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated).bind(gn)); gn->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised).bind(gn)); gn->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw)); @@ -409,6 +424,8 @@ void GraphEdit::remove_child_notify(Node *p_child) { GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { gn->disconnect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved)); + gn->disconnect("selected", callable_mp(this, &GraphEdit::_graph_node_selected)); + gn->disconnect("deselected", callable_mp(this, &GraphEdit::_graph_node_deselected)); gn->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated)); gn->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised)); @@ -756,25 +773,25 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { if (connecting_valid) { if (connecting && connecting_target) { String from = connecting_from; - int from_slot = connecting_index; + int from_port = connecting_index; String to = connecting_target_to; - int to_slot = connecting_target_index; + int to_port = connecting_target_index; if (!connecting_out) { SWAP(from, to); - SWAP(from_slot, to_slot); + SWAP(from_port, to_port); } - emit_signal(SNAME("connection_request"), from, from_slot, to, to_slot); + emit_signal(SNAME("connection_request"), from, from_port, to, to_port); } else if (!just_disconnected) { String from = connecting_from; - int from_slot = connecting_index; + int from_port = connecting_index; Vector2 ofs = mb->get_position(); if (!connecting_out) { - emit_signal(SNAME("connection_from_empty"), from, from_slot, ofs); + emit_signal(SNAME("connection_from_empty"), from, from_port, ofs); } else { - emit_signal(SNAME("connection_to_empty"), from, from_slot, ofs); + emit_signal(SNAME("connection_to_empty"), from, from_port, ofs); } } } @@ -813,22 +830,22 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &mpos } } -bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { +bool GraphEdit::is_in_input_hotzone(GraphNode *p_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { bool success; - if (GDVIRTUAL_CALL(_is_in_input_hotzone, p_graph_node, p_slot_index, p_mouse_pos, success)) { + if (GDVIRTUAL_CALL(_is_in_input_hotzone, p_node, p_port, p_mouse_pos, success)) { return success; } else { - Vector2 pos = p_graph_node->get_connection_input_position(p_slot_index) + p_graph_node->get_position(); + Vector2 pos = p_node->get_connection_input_position(p_port) + p_node->get_position(); return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, true); } } -bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { +bool GraphEdit::is_in_output_hotzone(GraphNode *p_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { bool success; - if (GDVIRTUAL_CALL(_is_in_output_hotzone, p_graph_node, p_slot_index, p_mouse_pos, success)) { + if (GDVIRTUAL_CALL(_is_in_output_hotzone, p_node, p_port, p_mouse_pos, success)) { return success; } else { - Vector2 pos = p_graph_node->get_connection_output_position(p_slot_index) + p_graph_node->get_position(); + Vector2 pos = p_node->get_connection_output_position(p_port) + p_node->get_position(); return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, false); } } @@ -1083,11 +1100,11 @@ void GraphEdit::_minimap_draw() { continue; } - Vector2 from_slot_position = gfrom->get_position_offset() * zoom + gfrom->get_connection_output_position(E.from_port); - Vector2 from_position = minimap->_convert_from_graph_position(from_slot_position - graph_offset) + minimap_offset; + Vector2 from_port_position = gfrom->get_position_offset() * zoom + gfrom->get_connection_output_position(E.from_port); + Vector2 from_position = minimap->_convert_from_graph_position(from_port_position - graph_offset) + minimap_offset; Color from_color = gfrom->get_connection_output_color(E.from_port); - Vector2 to_slot_position = gto->get_position_offset() * zoom + gto->get_connection_input_position(E.to_port); - Vector2 to_position = minimap->_convert_from_graph_position(to_slot_position - graph_offset) + minimap_offset; + Vector2 to_port_position = gto->get_position_offset() * zoom + gto->get_connection_input_position(E.to_port); + Vector2 to_position = minimap->_convert_from_graph_position(to_port_position - graph_offset) + minimap_offset; Color to_color = gto->get_connection_input_color(E.to_port); if (E.activity > 0) { @@ -1170,24 +1187,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { bool in_box = r.intersects(box_selecting_rect); if (in_box) { - if (!gn->is_selected() && box_selection_mode_additive) { - emit_signal(SNAME("node_selected"), gn); - } else if (gn->is_selected() && !box_selection_mode_additive) { - emit_signal(SNAME("node_deselected"), gn); - } - if (gn->is_selectable()) { - gn->set_selected(box_selection_mode_additive); - } + gn->set_selected(box_selection_mode_additive); } else { - bool select = (previous_selected.find(gn) != nullptr); - if (gn->is_selected() && !select) { - emit_signal(SNAME("node_deselected"), gn); - } else if (!gn->is_selected() && select) { - emit_signal(SNAME("node_selected"), gn); - } - if (gn->is_selectable()) { - gn->set_selected(select); - } + gn->set_selected(previous_selected.find(gn) != nullptr); } } @@ -1206,13 +1208,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { continue; } - bool select = (gn->is_selectable() && previous_selected.find(gn) != nullptr); - if (gn->is_selected() && !select) { - emit_signal(SNAME("node_deselected"), gn); - } else if (!gn->is_selected() && select) { - emit_signal(SNAME("node_selected"), gn); - } - gn->set_selected(select); + gn->set_selected(previous_selected.find(gn) != nullptr); } top_layer->queue_redraw(); minimap->queue_redraw(); @@ -1235,7 +1231,6 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { Rect2 r = gn->get_rect(); r.size *= zoom; if (r.has_point(b->get_position())) { - emit_signal(SNAME("node_deselected"), gn); gn->set_selected(false); } } @@ -1270,18 +1265,21 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { if (b->get_button_index() == MouseButton::LEFT && b->is_pressed()) { GraphNode *gn = nullptr; + // Find node which was clicked on. for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn_selected = Object::cast_to<GraphNode>(get_child(i)); - if (gn_selected) { - if (gn_selected->is_resizing()) { - continue; - } + if (!gn_selected) { + continue; + } - if (gn_selected->has_point((b->get_position() - gn_selected->get_position()) / zoom)) { - gn = gn_selected; - break; - } + if (gn_selected->is_resizing()) { + continue; + } + + if (gn_selected->has_point((b->get_position() - gn_selected->get_position()) / zoom)) { + gn = gn_selected; + break; } } @@ -1290,26 +1288,22 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { return; } + // Left-clicked on a node, select it. dragging = true; drag_accum = Vector2(); just_selected = !gn->is_selected(); if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); - if (o_gn) { - if (o_gn == gn) { - o_gn->set_selected(o_gn->is_selectable()); - } else { - if (o_gn->is_selected()) { - emit_signal(SNAME("node_deselected"), o_gn); - } - o_gn->set_selected(false); - } + if (!o_gn) { + continue; } + + o_gn->set_selected(o_gn == gn); } } - gn->set_selected(gn->is_selectable()); + gn->set_selected(true); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (!o_gn) { @@ -1332,6 +1326,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { return; } + // Left-clicked on empty space, start box select. box_selecting = true; box_selecting_from = b->get_position(); if (b->is_ctrl_pressed()) { @@ -1364,9 +1359,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { if (!gn2) { continue; } - if (gn2->is_selected()) { - emit_signal(SNAME("node_deselected"), gn2); - } + gn2->set_selected(false); } } @@ -1374,6 +1367,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { } if (b->get_button_index() == MouseButton::LEFT && !b->is_pressed() && box_selecting) { + // Box selection ended. Nodes were selected during mouse movement. box_selecting = false; box_selecting_rect = Rect2(); previous_selected.clear(); @@ -2309,10 +2303,10 @@ void GraphEdit::arrange_nodes() { } void GraphEdit::_bind_methods() { - ClassDB::bind_method(D_METHOD("connect_node", "from", "from_port", "to", "to_port"), &GraphEdit::connect_node); - ClassDB::bind_method(D_METHOD("is_node_connected", "from", "from_port", "to", "to_port"), &GraphEdit::is_node_connected); - ClassDB::bind_method(D_METHOD("disconnect_node", "from", "from_port", "to", "to_port"), &GraphEdit::disconnect_node); - ClassDB::bind_method(D_METHOD("set_connection_activity", "from", "from_port", "to", "to_port", "amount"), &GraphEdit::set_connection_activity); + ClassDB::bind_method(D_METHOD("connect_node", "from_node", "from_port", "to_node", "to_port"), &GraphEdit::connect_node); + ClassDB::bind_method(D_METHOD("is_node_connected", "from_node", "from_port", "to_node", "to_port"), &GraphEdit::is_node_connected); + ClassDB::bind_method(D_METHOD("disconnect_node", "from_node", "from_port", "to_node", "to_port"), &GraphEdit::disconnect_node); + ClassDB::bind_method(D_METHOD("set_connection_activity", "from_node", "from_port", "to_node", "to_port", "amount"), &GraphEdit::set_connection_activity); ClassDB::bind_method(D_METHOD("get_connection_list"), &GraphEdit::_get_connection_list); ClassDB::bind_method(D_METHOD("clear_connections"), &GraphEdit::clear_connections); ClassDB::bind_method(D_METHOD("force_connection_drag_end"), &GraphEdit::force_connection_drag_end); @@ -2326,7 +2320,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("add_valid_connection_type", "from_type", "to_type"), &GraphEdit::add_valid_connection_type); ClassDB::bind_method(D_METHOD("remove_valid_connection_type", "from_type", "to_type"), &GraphEdit::remove_valid_connection_type); ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type); - ClassDB::bind_method(D_METHOD("get_connection_line", "from", "to"), &GraphEdit::get_connection_line); + ClassDB::bind_method(D_METHOD("get_connection_line", "from_node", "to_node"), &GraphEdit::get_connection_line); ClassDB::bind_method(D_METHOD("set_panning_scheme", "scheme"), &GraphEdit::set_panning_scheme); ClassDB::bind_method(D_METHOD("get_panning_scheme"), &GraphEdit::get_panning_scheme); @@ -2376,8 +2370,8 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_right_disconnects_enabled"), &GraphEdit::is_right_disconnects_enabled); ClassDB::bind_method(D_METHOD("_update_scroll_offset"), &GraphEdit::_update_scroll_offset); - GDVIRTUAL_BIND(_is_in_input_hotzone, "graph_node", "slot_index", "mouse_position"); - GDVIRTUAL_BIND(_is_in_output_hotzone, "graph_node", "slot_index", "mouse_position"); + GDVIRTUAL_BIND(_is_in_input_hotzone, "in_node", "in_port", "mouse_position"); + GDVIRTUAL_BIND(_is_in_output_hotzone, "in_node", "in_port", "mouse_position"); ClassDB::bind_method(D_METHOD("get_zoom_hbox"), &GraphEdit::get_zoom_hbox); @@ -2385,8 +2379,8 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_selected", "node"), &GraphEdit::set_selected); - GDVIRTUAL_BIND(_get_connection_line, "from", "to") - GDVIRTUAL_BIND(_is_node_hover_valid, "from", "from_slot", "to", "to_slot"); + GDVIRTUAL_BIND(_get_connection_line, "from_position", "to_position") + GDVIRTUAL_BIND(_is_node_hover_valid, "from_node", "from_port", "to_node", "to_port"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "right_disconnects"), "set_right_disconnects", "is_right_disconnects_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_scroll_ofs", "get_scroll_ofs"); @@ -2414,21 +2408,21 @@ void GraphEdit::_bind_methods() { ADD_GROUP("UI", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arrange_nodes_button_hidden"), "set_arrange_nodes_button_hidden", "is_arrange_nodes_button_hidden"); - ADD_SIGNAL(MethodInfo("connection_request", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"))); - ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"))); + ADD_SIGNAL(MethodInfo("connection_request", PropertyInfo(Variant::STRING_NAME, "from_node"), PropertyInfo(Variant::INT, "from_port"), PropertyInfo(Variant::STRING_NAME, "to_node"), PropertyInfo(Variant::INT, "to_port"))); + ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING_NAME, "from_node"), PropertyInfo(Variant::INT, "from_port"), PropertyInfo(Variant::STRING_NAME, "to_node"), PropertyInfo(Variant::INT, "to_port"))); ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "position"))); ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); ADD_SIGNAL(MethodInfo("copy_nodes_request")); ADD_SIGNAL(MethodInfo("paste_nodes_request")); ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_deselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); - ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); - ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); + ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from_node"), PropertyInfo(Variant::INT, "from_port"), PropertyInfo(Variant::VECTOR2, "release_position"))); + ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to_node"), PropertyInfo(Variant::INT, "to_port"), PropertyInfo(Variant::VECTOR2, "release_position"))); ADD_SIGNAL(MethodInfo("delete_nodes_request", PropertyInfo(Variant::ARRAY, "nodes", PROPERTY_HINT_ARRAY_TYPE, "StringName"))); ADD_SIGNAL(MethodInfo("begin_node_move")); ADD_SIGNAL(MethodInfo("end_node_move")); ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "offset"))); - ADD_SIGNAL(MethodInfo("connection_drag_started", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "slot"), PropertyInfo(Variant::BOOL, "is_output"))); + ADD_SIGNAL(MethodInfo("connection_drag_started", PropertyInfo(Variant::STRING, "from_node"), PropertyInfo(Variant::INT, "from_port"), PropertyInfo(Variant::BOOL, "is_output"))); ADD_SIGNAL(MethodInfo("connection_drag_ended")); BIND_ENUM_CONSTANT(SCROLL_ZOOMS); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 0a0676699f..9371ed3df4 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -186,6 +186,8 @@ private: PackedVector2Array get_connection_line(const Vector2 &p_from, const Vector2 &p_to); void _draw_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_zoom); + void _graph_node_selected(Node *p_gn); + void _graph_node_deselected(Node *p_gn); void _graph_node_raised(Node *p_gn); void _graph_node_moved(Node *p_gn); void _graph_node_slot_updated(int p_index, Node *p_gn); @@ -199,8 +201,8 @@ private: GraphEditMinimap *minimap = nullptr; void _top_layer_input(const Ref<InputEvent> &p_ev); - bool is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); - bool is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); + bool is_in_input_hotzone(GraphNode *p_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); + bool is_in_output_hotzone(GraphNode *p_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); bool is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left); void _top_layer_draw(); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 5976d9fc37..21c0b5a842 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -736,11 +736,12 @@ Vector2 GraphNode::get_position_offset() const { } void GraphNode::set_selected(bool p_selected) { - if (selected == p_selected) { + if (!is_selectable() || selected == p_selected) { return; } selected = p_selected; + emit_signal(p_selected ? SNAME("selected") : SNAME("deselected")); queue_redraw(); } @@ -778,8 +779,8 @@ void GraphNode::_connpos_update() { int sep = get_theme_constant(SNAME("separation")); Ref<StyleBox> sb = get_theme_stylebox(SNAME("frame")); - conn_input_cache.clear(); - conn_output_cache.clear(); + left_port_cache.clear(); + right_port_cache.clear(); int vofs = 0; int idx = 0; @@ -800,20 +801,26 @@ void GraphNode::_connpos_update() { if (slot_info.has(idx)) { if (slot_info[idx].enable_left) { - ConnCache cc; - cc.pos = Point2i(edgeofs, y + h / 2); + PortCache cc; + cc.position = Point2i(edgeofs, y + h / 2); + cc.height = size.height; + + cc.slot_idx = idx; cc.type = slot_info[idx].type_left; cc.color = slot_info[idx].color_left; - cc.height = size.height; - conn_input_cache.push_back(cc); + + left_port_cache.push_back(cc); } if (slot_info[idx].enable_right) { - ConnCache cc; - cc.pos = Point2i(get_size().width - edgeofs, y + h / 2); + PortCache cc; + cc.position = Point2i(get_size().width - edgeofs, y + h / 2); + cc.height = size.height; + + cc.slot_idx = idx; cc.type = slot_info[idx].type_right; cc.color = slot_info[idx].color_right; - cc.height = size.height; - conn_output_cache.push_back(cc); + + right_port_cache.push_back(cc); } } @@ -830,46 +837,55 @@ int GraphNode::get_connection_input_count() { _connpos_update(); } - return conn_input_cache.size(); + return left_port_cache.size(); } -int GraphNode::get_connection_input_height(int p_idx) { +int GraphNode::get_connection_input_height(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), 0); - return conn_input_cache[p_idx].height; + ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), 0); + return left_port_cache[p_port].height; } -Vector2 GraphNode::get_connection_input_position(int p_idx) { +Vector2 GraphNode::get_connection_input_position(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), Vector2()); - Vector2 pos = conn_input_cache[p_idx].pos; + ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), Vector2()); + Vector2 pos = left_port_cache[p_port].position; pos.x *= get_scale().x; pos.y *= get_scale().y; return pos; } -int GraphNode::get_connection_input_type(int p_idx) { +int GraphNode::get_connection_input_type(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), 0); - return conn_input_cache[p_idx].type; + ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), 0); + return left_port_cache[p_port].type; } -Color GraphNode::get_connection_input_color(int p_idx) { +Color GraphNode::get_connection_input_color(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), Color()); - return conn_input_cache[p_idx].color; + ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), Color()); + return left_port_cache[p_port].color; +} + +int GraphNode::get_connection_input_slot(int p_port) { + if (connpos_dirty) { + _connpos_update(); + } + + ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), -1); + return left_port_cache[p_port].slot_idx; } int GraphNode::get_connection_output_count() { @@ -877,46 +893,55 @@ int GraphNode::get_connection_output_count() { _connpos_update(); } - return conn_output_cache.size(); + return right_port_cache.size(); } -int GraphNode::get_connection_output_height(int p_idx) { +int GraphNode::get_connection_output_height(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), 0); - return conn_output_cache[p_idx].height; + ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), 0); + return right_port_cache[p_port].height; } -Vector2 GraphNode::get_connection_output_position(int p_idx) { +Vector2 GraphNode::get_connection_output_position(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), Vector2()); - Vector2 pos = conn_output_cache[p_idx].pos; + ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), Vector2()); + Vector2 pos = right_port_cache[p_port].position; pos.x *= get_scale().x; pos.y *= get_scale().y; return pos; } -int GraphNode::get_connection_output_type(int p_idx) { +int GraphNode::get_connection_output_type(int p_port) { + if (connpos_dirty) { + _connpos_update(); + } + + ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), 0); + return right_port_cache[p_port].type; +} + +Color GraphNode::get_connection_output_color(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), 0); - return conn_output_cache[p_idx].type; + ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), Color()); + return right_port_cache[p_port].color; } -Color GraphNode::get_connection_output_color(int p_idx) { +int GraphNode::get_connection_output_slot(int p_port) { if (connpos_dirty) { _connpos_update(); } - ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), Color()); - return conn_output_cache[p_idx].color; + ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), -1); + return right_port_cache[p_port].slot_idx; } void GraphNode::gui_input(const Ref<InputEvent> &p_ev) { @@ -1012,6 +1037,9 @@ bool GraphNode::is_draggable() { } void GraphNode::set_selectable(bool p_selectable) { + if (!p_selectable) { + set_selected(false); + } selectable = p_selectable; } @@ -1046,30 +1074,30 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_language", "language"), &GraphNode::set_language); ClassDB::bind_method(D_METHOD("get_language"), &GraphNode::get_language); - ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right", "enable"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("clear_slot", "idx"), &GraphNode::clear_slot); + ClassDB::bind_method(D_METHOD("set_slot", "slot_index", "enable_left_port", "type_left", "color_left", "enable_right_port", "type_right", "color_right", "custom_icon_left", "custom_icon_right", "draw_stylebox"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("clear_slot", "slot_index"), &GraphNode::clear_slot); ClassDB::bind_method(D_METHOD("clear_all_slots"), &GraphNode::clear_all_slots); - ClassDB::bind_method(D_METHOD("is_slot_enabled_left", "idx"), &GraphNode::is_slot_enabled_left); - ClassDB::bind_method(D_METHOD("set_slot_enabled_left", "idx", "enable_left"), &GraphNode::set_slot_enabled_left); + ClassDB::bind_method(D_METHOD("set_slot_enabled_left", "slot_index", "enable"), &GraphNode::set_slot_enabled_left); + ClassDB::bind_method(D_METHOD("is_slot_enabled_left", "slot_index"), &GraphNode::is_slot_enabled_left); - ClassDB::bind_method(D_METHOD("set_slot_type_left", "idx", "type_left"), &GraphNode::set_slot_type_left); - ClassDB::bind_method(D_METHOD("get_slot_type_left", "idx"), &GraphNode::get_slot_type_left); + ClassDB::bind_method(D_METHOD("set_slot_type_left", "slot_index", "type"), &GraphNode::set_slot_type_left); + ClassDB::bind_method(D_METHOD("get_slot_type_left", "slot_index"), &GraphNode::get_slot_type_left); - ClassDB::bind_method(D_METHOD("set_slot_color_left", "idx", "color_left"), &GraphNode::set_slot_color_left); - ClassDB::bind_method(D_METHOD("get_slot_color_left", "idx"), &GraphNode::get_slot_color_left); + ClassDB::bind_method(D_METHOD("set_slot_color_left", "slot_index", "color"), &GraphNode::set_slot_color_left); + ClassDB::bind_method(D_METHOD("get_slot_color_left", "slot_index"), &GraphNode::get_slot_color_left); - ClassDB::bind_method(D_METHOD("is_slot_enabled_right", "idx"), &GraphNode::is_slot_enabled_right); - ClassDB::bind_method(D_METHOD("set_slot_enabled_right", "idx", "enable_right"), &GraphNode::set_slot_enabled_right); + ClassDB::bind_method(D_METHOD("set_slot_enabled_right", "slot_index", "enable"), &GraphNode::set_slot_enabled_right); + ClassDB::bind_method(D_METHOD("is_slot_enabled_right", "slot_index"), &GraphNode::is_slot_enabled_right); - ClassDB::bind_method(D_METHOD("set_slot_type_right", "idx", "type_right"), &GraphNode::set_slot_type_right); - ClassDB::bind_method(D_METHOD("get_slot_type_right", "idx"), &GraphNode::get_slot_type_right); + ClassDB::bind_method(D_METHOD("set_slot_type_right", "slot_index", "type"), &GraphNode::set_slot_type_right); + ClassDB::bind_method(D_METHOD("get_slot_type_right", "slot_index"), &GraphNode::get_slot_type_right); - ClassDB::bind_method(D_METHOD("set_slot_color_right", "idx", "color_right"), &GraphNode::set_slot_color_right); - ClassDB::bind_method(D_METHOD("get_slot_color_right", "idx"), &GraphNode::get_slot_color_right); + ClassDB::bind_method(D_METHOD("set_slot_color_right", "slot_index", "color"), &GraphNode::set_slot_color_right); + ClassDB::bind_method(D_METHOD("get_slot_color_right", "slot_index"), &GraphNode::get_slot_color_right); - ClassDB::bind_method(D_METHOD("is_slot_draw_stylebox", "idx"), &GraphNode::is_slot_draw_stylebox); - ClassDB::bind_method(D_METHOD("set_slot_draw_stylebox", "idx", "draw_stylebox"), &GraphNode::set_slot_draw_stylebox); + ClassDB::bind_method(D_METHOD("is_slot_draw_stylebox", "slot_index"), &GraphNode::is_slot_draw_stylebox); + ClassDB::bind_method(D_METHOD("set_slot_draw_stylebox", "slot_index", "enable"), &GraphNode::set_slot_draw_stylebox); ClassDB::bind_method(D_METHOD("set_position_offset", "offset"), &GraphNode::set_position_offset); ClassDB::bind_method(D_METHOD("get_position_offset"), &GraphNode::get_position_offset); @@ -1090,16 +1118,18 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("is_selected"), &GraphNode::is_selected); ClassDB::bind_method(D_METHOD("get_connection_input_count"), &GraphNode::get_connection_input_count); - ClassDB::bind_method(D_METHOD("get_connection_input_height", "idx"), &GraphNode::get_connection_input_height); - ClassDB::bind_method(D_METHOD("get_connection_input_position", "idx"), &GraphNode::get_connection_input_position); - ClassDB::bind_method(D_METHOD("get_connection_input_type", "idx"), &GraphNode::get_connection_input_type); - ClassDB::bind_method(D_METHOD("get_connection_input_color", "idx"), &GraphNode::get_connection_input_color); + ClassDB::bind_method(D_METHOD("get_connection_input_height", "port"), &GraphNode::get_connection_input_height); + ClassDB::bind_method(D_METHOD("get_connection_input_position", "port"), &GraphNode::get_connection_input_position); + ClassDB::bind_method(D_METHOD("get_connection_input_type", "port"), &GraphNode::get_connection_input_type); + ClassDB::bind_method(D_METHOD("get_connection_input_color", "port"), &GraphNode::get_connection_input_color); + ClassDB::bind_method(D_METHOD("get_connection_input_slot", "port"), &GraphNode::get_connection_input_slot); ClassDB::bind_method(D_METHOD("get_connection_output_count"), &GraphNode::get_connection_output_count); - ClassDB::bind_method(D_METHOD("get_connection_output_height", "idx"), &GraphNode::get_connection_output_height); - ClassDB::bind_method(D_METHOD("get_connection_output_position", "idx"), &GraphNode::get_connection_output_position); - ClassDB::bind_method(D_METHOD("get_connection_output_type", "idx"), &GraphNode::get_connection_output_type); - ClassDB::bind_method(D_METHOD("get_connection_output_color", "idx"), &GraphNode::get_connection_output_color); + ClassDB::bind_method(D_METHOD("get_connection_output_height", "port"), &GraphNode::get_connection_output_height); + ClassDB::bind_method(D_METHOD("get_connection_output_position", "port"), &GraphNode::get_connection_output_position); + ClassDB::bind_method(D_METHOD("get_connection_output_type", "port"), &GraphNode::get_connection_output_type); + ClassDB::bind_method(D_METHOD("get_connection_output_color", "port"), &GraphNode::get_connection_output_color); + ClassDB::bind_method(D_METHOD("get_connection_output_slot", "port"), &GraphNode::get_connection_output_slot); ClassDB::bind_method(D_METHOD("set_show_close_button", "show"), &GraphNode::set_show_close_button); ClassDB::bind_method(D_METHOD("is_close_button_visible"), &GraphNode::is_close_button_visible); @@ -1123,6 +1153,8 @@ void GraphNode::_bind_methods() { ADD_GROUP("", ""); ADD_SIGNAL(MethodInfo("position_offset_changed")); + ADD_SIGNAL(MethodInfo("selected")); + ADD_SIGNAL(MethodInfo("deselected")); ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx"))); ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to"))); ADD_SIGNAL(MethodInfo("raise_request")); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 9c8f926403..e66b0cfc20 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -78,15 +78,17 @@ private: Vector<int> cache_y; - struct ConnCache { - Vector2 pos; + struct PortCache { + Vector2 position; + int height; + + int slot_idx; int type = 0; Color color; - int height; }; - Vector<ConnCache> conn_input_cache; - Vector<ConnCache> conn_output_cache; + Vector<PortCache> left_port_cache; + Vector<PortCache> right_port_cache; HashMap<int, Slot> slot_info; @@ -165,16 +167,18 @@ public: bool is_close_button_visible() const; int get_connection_input_count(); - int get_connection_input_height(int p_idx); - Vector2 get_connection_input_position(int p_idx); - int get_connection_input_type(int p_idx); - Color get_connection_input_color(int p_idx); + int get_connection_input_height(int p_port); + Vector2 get_connection_input_position(int p_port); + int get_connection_input_type(int p_port); + Color get_connection_input_color(int p_port); + int get_connection_input_slot(int p_port); int get_connection_output_count(); - int get_connection_output_height(int p_idx); - Vector2 get_connection_output_position(int p_idx); - int get_connection_output_type(int p_idx); - Color get_connection_output_color(int p_idx); + int get_connection_output_height(int p_port); + Vector2 get_connection_output_position(int p_port); + int get_connection_output_type(int p_port); + Color get_connection_output_color(int p_port); + int get_connection_output_slot(int p_port); void set_overlay(Overlay p_overlay); Overlay get_overlay() const; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 8c49353105..008109da65 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -596,7 +596,7 @@ ItemList::IconMode ItemList::get_icon_mode() const { return icon_mode; } -void ItemList::set_fixed_icon_size(const Size2 &p_size) { +void ItemList::set_fixed_icon_size(const Size2i &p_size) { if (fixed_icon_size == p_size) { return; } @@ -605,7 +605,7 @@ void ItemList::set_fixed_icon_size(const Size2 &p_size) { queue_redraw(); } -Size2 ItemList::get_fixed_icon_size() const { +Size2i ItemList::get_fixed_icon_size() const { return fixed_icon_size; } @@ -655,7 +655,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid() && mb->is_pressed()) { search_string = ""; //any mousepress cancels Vector2 pos = mb->get_position(); - pos -= theme_cache.bg_style->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y += scroll_bar->get_value(); if (is_layout_rtl()) { @@ -679,7 +679,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) { if (closest != -1 && (mb->get_button_index() == MouseButton::LEFT || (allow_rmb_select && mb->get_button_index() == MouseButton::RIGHT))) { int i = closest; - if (select_mode == SELECT_MULTI && items[i].selected && mb->is_command_pressed()) { + if (select_mode == SELECT_MULTI && items[i].selected && mb->is_command_or_control_pressed()) { deselect(i); emit_signal(SNAME("multi_selected"), i, false); @@ -702,13 +702,13 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) { emit_signal(SNAME("item_clicked"), i, get_local_mouse_position(), mb->get_button_index()); } else { - if (!mb->is_double_click() && !mb->is_command_pressed() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == MouseButton::LEFT) { + if (!mb->is_double_click() && !mb->is_command_or_control_pressed() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == MouseButton::LEFT) { defer_select_single = i; return; } if (!items[i].selected || allow_reselect) { - select(i, select_mode == SELECT_SINGLE || !mb->is_command_pressed()); + select(i, select_mode == SELECT_SINGLE || !mb->is_command_or_control_pressed()); if (select_mode == SELECT_SINGLE) { emit_signal(SNAME("item_selected"), i); @@ -985,8 +985,8 @@ void ItemList::_update_theme_item_cache() { theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); theme_cache.v_separation = get_theme_constant(SNAME("v_separation")); - theme_cache.bg_style = get_theme_stylebox(SNAME("bg")); - theme_cache.bg_focus_style = get_theme_stylebox(SNAME("bg_focus")); + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); + theme_cache.focus_style = get_theme_stylebox(SNAME("focus")); theme_cache.font = get_theme_font(SNAME("font")); theme_cache.font_size = get_theme_font_size(SNAME("font_size")); @@ -1025,13 +1025,13 @@ void ItemList::_notification(int p_what) { int mw = scroll_bar->get_minimum_size().x; scroll_bar->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -mw); scroll_bar->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0); - scroll_bar->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, theme_cache.bg_style->get_margin(SIDE_TOP)); - scroll_bar->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -theme_cache.bg_style->get_margin(SIDE_BOTTOM)); + scroll_bar->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, theme_cache.panel_style->get_margin(SIDE_TOP)); + scroll_bar->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -theme_cache.panel_style->get_margin(SIDE_BOTTOM)); Size2 size = get_size(); - int width = size.width - theme_cache.bg_style->get_minimum_size().width; + int width = size.width - theme_cache.panel_style->get_minimum_size().width; - draw_style_box(theme_cache.bg_style, Rect2(Point2(), size)); + draw_style_box(theme_cache.panel_style, Rect2(Point2(), size)); Ref<StyleBox> sbsel; Ref<StyleBox> cursor; @@ -1047,7 +1047,7 @@ void ItemList::_notification(int p_what) { if (has_focus()) { RenderingServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(), true); - draw_style_box(theme_cache.bg_focus_style, Rect2(Point2(), size)); + draw_style_box(theme_cache.focus_style, Rect2(Point2(), size)); RenderingServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(), false); } @@ -1109,7 +1109,7 @@ void ItemList::_notification(int p_what) { items.write[i].min_rect_cache.size = minsize; } - int fit_size = size.x - theme_cache.bg_style->get_minimum_size().width - mw; + int fit_size = size.x - theme_cache.panel_style->get_minimum_size().width - mw; //2-attempt best fit current_columns = 0x7FFFFFFF; @@ -1160,10 +1160,10 @@ void ItemList::_notification(int p_what) { } if (all_fit) { - float page = MAX(0, size.height - theme_cache.bg_style->get_minimum_size().height); + float page = MAX(0, size.height - theme_cache.panel_style->get_minimum_size().height); float max = MAX(page, ofs.y + max_h); if (auto_height) { - auto_height_value = ofs.y + max_h + theme_cache.bg_style->get_minimum_size().height; + auto_height_value = ofs.y + max_h + theme_cache.panel_style->get_minimum_size().height; } scroll_bar->set_max(max); scroll_bar->set_page(page); @@ -1204,7 +1204,7 @@ void ItemList::_notification(int p_what) { ensure_selected_visible = false; - Vector2 base_ofs = theme_cache.bg_style->get_offset(); + Vector2 base_ofs = theme_cache.panel_style->get_offset(); base_ofs.y -= int(scroll_bar->get_value()); const Rect2 clip(-base_ofs, size); // visible frame, don't need to draw outside of there @@ -1442,7 +1442,7 @@ void ItemList::_notification(int p_what) { } const int y = base_ofs.y + separators[i]; - draw_line(Vector2(theme_cache.bg_style->get_margin(SIDE_LEFT), y), Vector2(width, y), theme_cache.guide_color); + draw_line(Vector2(theme_cache.panel_style->get_margin(SIDE_LEFT), y), Vector2(width, y), theme_cache.guide_color); } } break; } @@ -1454,7 +1454,7 @@ void ItemList::_scroll_changed(double) { int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const { Vector2 pos = p_pos; - pos -= theme_cache.bg_style->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y += scroll_bar->get_value(); if (is_layout_rtl()) { @@ -1491,7 +1491,7 @@ bool ItemList::is_pos_at_end_of_items(const Point2 &p_pos) const { } Vector2 pos = p_pos; - pos -= theme_cache.bg_style->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y += scroll_bar->get_value(); if (is_layout_rtl()) { @@ -1830,7 +1830,7 @@ void ItemList::_bind_methods() { ADD_GROUP("Icon", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_mode", PROPERTY_HINT_ENUM, "Top,Left"), "set_icon_mode", "get_icon_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "icon_scale"), "set_icon_scale", "get_icon_scale"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "fixed_icon_size", PROPERTY_HINT_NONE, "suffix:px"), "set_fixed_icon_size", "get_fixed_icon_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "fixed_icon_size", PROPERTY_HINT_NONE, "suffix:px"), "set_fixed_icon_size", "get_fixed_icon_size"); BIND_ENUM_CONSTANT(ICON_MODE_TOP); BIND_ENUM_CONSTANT(ICON_MODE_LEFT); diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 63bc771185..4b1b9d9282 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -123,8 +123,8 @@ private: int h_separation = 0; int v_separation = 0; - Ref<StyleBox> bg_style; - Ref<StyleBox> bg_focus_style; + Ref<StyleBox> panel_style; + Ref<StyleBox> focus_style; Ref<Font> font; int font_size = 0; @@ -244,8 +244,8 @@ public: void set_icon_mode(IconMode p_mode); IconMode get_icon_mode() const; - void set_fixed_icon_size(const Size2 &p_size); - Size2 get_fixed_icon_size() const; + void set_fixed_icon_size(const Size2i &p_size); + Size2i get_fixed_icon_size() const; void set_allow_rmb_select(bool p_allow); bool get_allow_rmb_select() const; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index c2ce4bdb83..be94337c89 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -589,7 +589,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { // Allow unicode handling if: // * No Modifiers are pressed (except shift) - bool allow_unicode_handling = !(k->is_command_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); + bool allow_unicode_handling = !(k->is_command_or_control_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); if (allow_unicode_handling && editable && k->get_unicode() >= 32) { // Handle Unicode (if no modifiers active) @@ -734,7 +734,7 @@ void LineEdit::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (Engine::get_singleton()->is_editor_hint() && !get_tree()->is_node_being_edited(this)) { set_caret_blink_enabled(EDITOR_GET("text_editor/appearance/caret/caret_blink")); - set_caret_blink_speed(EDITOR_GET("text_editor/appearance/caret/caret_blink_speed")); + set_caret_blink_interval(EDITOR_GET("text_editor/appearance/caret/caret_blink_interval")); if (!EditorSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &LineEdit::_editor_settings_changed))) { EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &LineEdit::_editor_settings_changed)); @@ -777,7 +777,7 @@ void LineEdit::_notification(int p_what) { if (caret_blinking) { caret_blink_timer += get_process_delta_time(); - if (caret_blink_timer >= caret_blink_speed) { + if (caret_blink_timer >= caret_blink_interval) { caret_blink_timer = 0.0; _toggle_draw_caret(); } @@ -1392,13 +1392,13 @@ void LineEdit::set_caret_force_displayed(const bool p_enabled) { queue_redraw(); } -float LineEdit::get_caret_blink_speed() const { - return caret_blink_speed; +float LineEdit::get_caret_blink_interval() const { + return caret_blink_interval; } -void LineEdit::set_caret_blink_speed(const float p_speed) { - ERR_FAIL_COND(p_speed <= 0); - caret_blink_speed = p_speed; +void LineEdit::set_caret_blink_interval(const float p_interval) { + ERR_FAIL_COND(p_interval <= 0); + caret_blink_interval = p_interval; } void LineEdit::_reset_caret_blink_timer() { @@ -2037,7 +2037,7 @@ PopupMenu *LineEdit::get_menu() const { void LineEdit::_editor_settings_changed() { #ifdef TOOLS_ENABLED set_caret_blink_enabled(EDITOR_GET("text_editor/appearance/caret/caret_blink")); - set_caret_blink_speed(EDITOR_GET("text_editor/appearance/caret/caret_blink_speed")); + set_caret_blink_interval(EDITOR_GET("text_editor/appearance/caret/caret_blink_interval")); #endif } @@ -2274,7 +2274,7 @@ Key LineEdit::_get_menu_action_accelerator(const String &p_action) { } void LineEdit::_validate_property(PropertyInfo &p_property) const { - if (!caret_blink_enabled && p_property.name == "caret_blink_speed") { + if (!caret_blink_enabled && p_property.name == "caret_blink_interval") { p_property.usage = PROPERTY_USAGE_NO_EDITOR; } } @@ -2317,8 +2317,8 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_caret_mid_grapheme_enabled"), &LineEdit::is_caret_mid_grapheme_enabled); ClassDB::bind_method(D_METHOD("set_caret_force_displayed", "enabled"), &LineEdit::set_caret_force_displayed); ClassDB::bind_method(D_METHOD("is_caret_force_displayed"), &LineEdit::is_caret_force_displayed); - ClassDB::bind_method(D_METHOD("set_caret_blink_speed", "blink_speed"), &LineEdit::set_caret_blink_speed); - ClassDB::bind_method(D_METHOD("get_caret_blink_speed"), &LineEdit::get_caret_blink_speed); + ClassDB::bind_method(D_METHOD("set_caret_blink_interval", "interval"), &LineEdit::set_caret_blink_interval); + ClassDB::bind_method(D_METHOD("get_caret_blink_interval"), &LineEdit::get_caret_blink_interval); ClassDB::bind_method(D_METHOD("set_max_length", "chars"), &LineEdit::set_max_length); ClassDB::bind_method(D_METHOD("get_max_length"), &LineEdit::get_max_length); ClassDB::bind_method(D_METHOD("insert_text_at_caret", "text"), &LineEdit::insert_text_at_caret); @@ -2419,7 +2419,7 @@ void LineEdit::_bind_methods() { ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "set_caret_blink_speed", "get_caret_blink_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_interval", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "set_caret_blink_interval", "get_caret_blink_interval"); ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_caret_column", "get_caret_column"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "set_caret_force_displayed", "is_caret_force_displayed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled"); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 38863e805c..a4d5205f81 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -170,7 +170,7 @@ private: bool caret_blink_enabled = false; bool caret_force_displayed = false; bool draw_caret = true; - float caret_blink_speed = 0.65; + float caret_blink_interval = 0.65; double caret_blink_timer = 0.0; bool caret_blinking = false; @@ -196,7 +196,7 @@ private: Color clear_button_color; Color clear_button_color_pressed; - int base_scale = 0; + float base_scale = 1.0; } theme_cache; bool _is_over_clear_button(const Point2 &p_pos) const; @@ -311,8 +311,8 @@ public: bool is_caret_blink_enabled() const; void set_caret_blink_enabled(const bool p_enabled); - float get_caret_blink_speed() const; - void set_caret_blink_speed(const float p_speed); + float get_caret_blink_interval() const; + void set_caret_blink_interval(const float p_interval); void set_caret_force_displayed(const bool p_enabled); bool is_caret_force_displayed() const; diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp index 0613652bdf..d6bf84ea5a 100644 --- a/scene/gui/menu_bar.cpp +++ b/scene/gui/menu_bar.cpp @@ -137,7 +137,7 @@ void MenuBar::_open_popup(int p_index, bool p_focus_item) { if (p_focus_item) { for (int i = 0; i < pm->get_item_count(); i++) { if (!pm->is_item_disabled(i)) { - pm->set_current_index(i); + pm->set_focused_item(i); break; } } diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index f779f87ae7..67a36240a2 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -107,7 +107,7 @@ void MenuButton::pressed() { if (!_was_pressed_by_mouse()) { for (int i = 0; i < popup->get_item_count(); i++) { if (!popup->is_item_disabled(i)) { - popup->set_current_index(i); + popup->set_focused_item(i); break; } } @@ -169,7 +169,7 @@ void MenuButton::_notification(int p_what) { menu_btn_other->pressed(); // As the popup wasn't triggered by a mouse click, the item focus needs to be removed manually. - menu_btn_other->get_popup()->set_current_index(-1); + menu_btn_other->get_popup()->set_focused_item(-1); } } break; } diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 0dd9666858..08f5e0bbfb 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -238,7 +238,7 @@ void OptionButton::pressed() { // If not triggered by the mouse, start the popup with the checked item (or the first enabled one) focused. if (current != NONE_SELECTED && !popup->is_item_disabled(current)) { if (!_was_pressed_by_mouse()) { - popup->set_current_index(current); + popup->set_focused_item(current); } else { popup->scroll_to_item(current); } @@ -246,7 +246,7 @@ void OptionButton::pressed() { for (int i = 0; i < popup->get_item_count(); i++) { if (!popup->is_item_disabled(i)) { if (!_was_pressed_by_mouse()) { - popup->set_current_index(i); + popup->set_focused_item(i); } else { popup->scroll_to_item(i); } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index bcc84fc8dc..d4a4efd578 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -209,7 +209,7 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { if (p_by_keyboard) { for (int i = 0; i < submenu_pum->get_item_count(); i++) { if (!submenu_pum->is_item_disabled(i)) { - submenu_pum->set_current_index(i); + submenu_pum->set_focused_item(i); break; } } @@ -431,7 +431,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { - if (m->get_velocity().is_equal_approx(Vector2())) { + if (m->get_velocity().is_zero_approx()) { return; } activated_by_keyboard = false; @@ -1547,7 +1547,7 @@ bool PopupMenu::is_item_shortcut_disabled(int p_idx) const { return items[p_idx].shortcut_is_disabled; } -void PopupMenu::set_current_index(int p_idx) { +void PopupMenu::set_focused_item(int p_idx) { if (p_idx != -1) { ERR_FAIL_INDEX(p_idx, items.size()); } @@ -1564,7 +1564,7 @@ void PopupMenu::set_current_index(int p_idx) { control->queue_redraw(); } -int PopupMenu::get_current_index() const { +int PopupMenu::get_focused_item() const { return mouse_over; } @@ -2057,8 +2057,8 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_shortcut", "index"), &PopupMenu::get_item_shortcut); ClassDB::bind_method(D_METHOD("get_item_indent", "index"), &PopupMenu::get_item_indent); - ClassDB::bind_method(D_METHOD("set_current_index", "index"), &PopupMenu::set_current_index); - ClassDB::bind_method(D_METHOD("get_current_index"), &PopupMenu::get_current_index); + ClassDB::bind_method(D_METHOD("set_focused_item", "index"), &PopupMenu::set_focused_item); + ClassDB::bind_method(D_METHOD("get_focused_item"), &PopupMenu::get_focused_item); ClassDB::bind_method(D_METHOD("set_item_count", "count"), &PopupMenu::set_item_count); ClassDB::bind_method(D_METHOD("get_item_count"), &PopupMenu::get_item_count); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index c8c598bd50..ad7909842e 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -261,8 +261,8 @@ public: int get_item_max_states(int p_idx) const; int get_item_state(int p_idx) const; - void set_current_index(int p_idx); - int get_current_index() const; + void set_focused_item(int p_idx); + int get_focused_item() const; void set_item_count(int p_count); int get_item_count() const; diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index fe609dd834..8369eaa227 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -33,13 +33,13 @@ #include "scene/resources/text_line.h" Size2 ProgressBar::get_minimum_size() const { - Size2 minimum_size = theme_cache.bg_style->get_minimum_size(); - minimum_size.height = MAX(minimum_size.height, theme_cache.fg_style->get_minimum_size().height); - minimum_size.width = MAX(minimum_size.width, theme_cache.fg_style->get_minimum_size().width); - if (percent_visible) { + Size2 minimum_size = theme_cache.background_style->get_minimum_size(); + minimum_size.height = MAX(minimum_size.height, theme_cache.fill_style->get_minimum_size().height); + minimum_size.width = MAX(minimum_size.width, theme_cache.fill_style->get_minimum_size().width); + if (show_percentage) { String txt = "100%"; TextLine tl = TextLine(txt, theme_cache.font, theme_cache.font_size); - minimum_size.height = MAX(minimum_size.height, theme_cache.bg_style->get_minimum_size().height + tl.get_size().y); + minimum_size.height = MAX(minimum_size.height, theme_cache.background_style->get_minimum_size().height + tl.get_size().y); } else { // this is needed, else the progressbar will collapse minimum_size.width = MAX(minimum_size.width, 1); minimum_size.height = MAX(minimum_size.height, 1); @@ -50,8 +50,8 @@ Size2 ProgressBar::get_minimum_size() const { void ProgressBar::_update_theme_item_cache() { Range::_update_theme_item_cache(); - theme_cache.bg_style = get_theme_stylebox(SNAME("bg")); - theme_cache.fg_style = get_theme_stylebox(SNAME("fg")); + theme_cache.background_style = get_theme_stylebox(SNAME("background")); + theme_cache.fill_style = get_theme_stylebox(SNAME("fill")); theme_cache.font = get_theme_font(SNAME("font")); theme_cache.font_size = get_theme_font_size(SNAME("font_size")); @@ -63,14 +63,14 @@ void ProgressBar::_update_theme_item_cache() { void ProgressBar::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - draw_style_box(theme_cache.bg_style, Rect2(Point2(), get_size())); + draw_style_box(theme_cache.background_style, Rect2(Point2(), get_size())); float r = get_as_ratio(); switch (mode) { case FILL_BEGIN_TO_END: case FILL_END_TO_BEGIN: { - int mp = theme_cache.fg_style->get_minimum_size().width; + int mp = theme_cache.fill_style->get_minimum_size().width; int p = round(r * (get_size().width - mp)); // We want FILL_BEGIN_TO_END to map to right to left when UI layout is RTL, // and left to right otherwise. And likewise for FILL_END_TO_BEGIN. @@ -78,23 +78,23 @@ void ProgressBar::_notification(int p_what) { if (p > 0) { if (right_to_left) { int p_remaining = round((1.0 - r) * (get_size().width - mp)); - draw_style_box(theme_cache.fg_style, Rect2(Point2(p_remaining, 0), Size2(p + theme_cache.fg_style->get_minimum_size().width, get_size().height))); + draw_style_box(theme_cache.fill_style, Rect2(Point2(p_remaining, 0), Size2(p + theme_cache.fill_style->get_minimum_size().width, get_size().height))); } else { - draw_style_box(theme_cache.fg_style, Rect2(Point2(0, 0), Size2(p + theme_cache.fg_style->get_minimum_size().width, get_size().height))); + draw_style_box(theme_cache.fill_style, Rect2(Point2(0, 0), Size2(p + theme_cache.fill_style->get_minimum_size().width, get_size().height))); } } } break; case FILL_TOP_TO_BOTTOM: case FILL_BOTTOM_TO_TOP: { - int mp = theme_cache.fg_style->get_minimum_size().height; + int mp = theme_cache.fill_style->get_minimum_size().height; int p = round(r * (get_size().height - mp)); if (p > 0) { if (mode == FILL_TOP_TO_BOTTOM) { - draw_style_box(theme_cache.fg_style, Rect2(Point2(0, 0), Size2(get_size().width, p + theme_cache.fg_style->get_minimum_size().height))); + draw_style_box(theme_cache.fill_style, Rect2(Point2(0, 0), Size2(get_size().width, p + theme_cache.fill_style->get_minimum_size().height))); } else { int p_remaining = round((1.0 - r) * (get_size().height - mp)); - draw_style_box(theme_cache.fg_style, Rect2(Point2(0, p_remaining), Size2(get_size().width, p + theme_cache.fg_style->get_minimum_size().height))); + draw_style_box(theme_cache.fill_style, Rect2(Point2(0, p_remaining), Size2(get_size().width, p + theme_cache.fill_style->get_minimum_size().height))); } } } break; @@ -102,7 +102,7 @@ void ProgressBar::_notification(int p_what) { break; } - if (percent_visible) { + if (show_percentage) { String txt = TS->format_number(itos(int(get_as_ratio() * 100))) + TS->percent_sign(); TextLine tl = TextLine(txt, theme_cache.font, theme_cache.font_size); Vector2 text_pos = (Point2(get_size().width - tl.get_size().x, get_size().height - tl.get_size().y) / 2).round(); @@ -127,27 +127,27 @@ int ProgressBar::get_fill_mode() { return mode; } -void ProgressBar::set_percent_visible(bool p_visible) { - if (percent_visible == p_visible) { +void ProgressBar::set_show_percentage(bool p_visible) { + if (show_percentage == p_visible) { return; } - percent_visible = p_visible; + show_percentage = p_visible; update_minimum_size(); queue_redraw(); } -bool ProgressBar::is_percent_visible() const { - return percent_visible; +bool ProgressBar::is_percentage_shown() const { + return show_percentage; } void ProgressBar::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fill_mode", "mode"), &ProgressBar::set_fill_mode); ClassDB::bind_method(D_METHOD("get_fill_mode"), &ProgressBar::get_fill_mode); - ClassDB::bind_method(D_METHOD("set_percent_visible", "visible"), &ProgressBar::set_percent_visible); - ClassDB::bind_method(D_METHOD("is_percent_visible"), &ProgressBar::is_percent_visible); + ClassDB::bind_method(D_METHOD("set_show_percentage", "visible"), &ProgressBar::set_show_percentage); + ClassDB::bind_method(D_METHOD("is_percentage_shown"), &ProgressBar::is_percentage_shown); ADD_PROPERTY(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Begin to End,End to Begin,Top to Bottom,Bottom to Top"), "set_fill_mode", "get_fill_mode"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "percent_visible"), "set_percent_visible", "is_percent_visible"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_percentage"), "set_show_percentage", "is_percentage_shown"); BIND_ENUM_CONSTANT(FILL_BEGIN_TO_END); BIND_ENUM_CONSTANT(FILL_END_TO_BEGIN); diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h index c79b901928..b6d7d2c7cf 100644 --- a/scene/gui/progress_bar.h +++ b/scene/gui/progress_bar.h @@ -36,11 +36,11 @@ class ProgressBar : public Range { GDCLASS(ProgressBar, Range); - bool percent_visible = true; + bool show_percentage = true; struct ThemeCache { - Ref<StyleBox> bg_style; - Ref<StyleBox> fg_style; + Ref<StyleBox> background_style; + Ref<StyleBox> fill_style; Ref<Font> font; int font_size = 0; @@ -67,8 +67,8 @@ public: void set_fill_mode(int p_fill); int get_fill_mode(); - void set_percent_visible(bool p_visible); - bool is_percent_visible() const; + void set_show_percentage(bool p_visible); + bool is_percentage_shown() const; Size2 get_minimum_size() const override; ProgressBar(); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 9b2e40e050..c936fe9738 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -134,8 +134,7 @@ RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) co } Rect2 RichTextLabel::_get_text_rect() { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - return Rect2(style->get_offset(), get_size() - style->get_minimum_size()); + return Rect2(theme_cache.normal_style->get_offset(), get_size() - theme_cache.normal_style->get_minimum_size()); } RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item_from, RichTextLabel::Item *p_item_to, int p_position) { @@ -287,8 +286,6 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font switch (it->type) { case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); - int hseparation = get_theme_constant(SNAME("table_h_separation")); - int vseparation = get_theme_constant(SNAME("table_v_separation")); int col_count = table->columns.size(); for (int i = 0; i < col_count; i++) { @@ -309,12 +306,12 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font } // Compute minimum width for each cell. - const int available_width = p_width - hseparation * (col_count - 1); + const int available_width = p_width - theme_cache.table_h_separation * (col_count - 1); // Compute available width and total ratio (for expanders). int total_ratio = 0; int remaining_width = available_width; - table->total_width = hseparation; + table->total_width = theme_cache.table_h_separation; for (int i = 0; i < col_count; i++) { remaining_width -= table->columns[i].min_width; @@ -332,7 +329,7 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } - table->total_width += table->columns[i].width + hseparation; + table->total_width += table->columns[i].width + theme_cache.table_h_separation; } // Resize to max_width if needed and distribute the remaining space. @@ -394,9 +391,9 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font frame->lines[i].offset.y = prev_h; frame->lines[i].offset += offset; - float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * get_theme_constant(SNAME("line_separation")); + float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * theme_cache.line_separation; if (i > 0) { - h += get_theme_constant(SNAME("line_separation")); + h += theme_cache.line_separation; } if (frame->min_size_over.y > 0) { h = MAX(h, frame->min_size_over.y); @@ -405,15 +402,15 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font h = MIN(h, frame->max_size_over.y); } yofs += h; - prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * theme_cache.line_separation; } yofs += frame->padding.size.y; - offset.x += table->columns[column].width + hseparation + frame->padding.size.x; + offset.x += table->columns[column].width + theme_cache.table_h_separation + frame->padding.size.x; row_height = MAX(yofs, row_height); if (column == col_count - 1) { offset.x = 0; - row_height += vseparation; + row_height += theme_cache.table_v_separation; table->total_height += row_height; offset.y += row_height; table->rows.push_back(row_height); @@ -551,8 +548,6 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } break; case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); - int hseparation = get_theme_constant(SNAME("table_h_separation")); - int vseparation = get_theme_constant(SNAME("table_v_separation")); int col_count = table->columns.size(); int t_char_count = 0; // Set minimums to zero. @@ -562,7 +557,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->columns[i].width = 0; } // Compute minimum width for each cell. - const int available_width = p_width - hseparation * (col_count - 1); + const int available_width = p_width - theme_cache.table_h_separation * (col_count - 1); int idx = 0; for (Item *E : table->subitems) { @@ -591,7 +586,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> // Compute available width and total ratio (for expanders). int total_ratio = 0; int remaining_width = available_width; - table->total_width = hseparation; + table->total_width = theme_cache.table_h_separation; for (int i = 0; i < col_count; i++) { remaining_width -= table->columns[i].min_width; @@ -609,7 +604,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } - table->total_width += table->columns[i].width + hseparation; + table->total_width += table->columns[i].width + theme_cache.table_h_separation; } // Resize to max_width if needed and distribute the remaining space. @@ -672,9 +667,9 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> frame->lines[i].offset.y = prev_h; frame->lines[i].offset += offset; - float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * get_theme_constant(SNAME("line_separation")); + float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * theme_cache.line_separation; if (i > 0) { - h += get_theme_constant(SNAME("line_separation")); + h += theme_cache.line_separation; } if (frame->min_size_over.y > 0) { h = MAX(h, frame->min_size_over.y); @@ -683,16 +678,16 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> h = MIN(h, frame->max_size_over.y); } yofs += h; - prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * theme_cache.line_separation; } yofs += frame->padding.size.y; - offset.x += table->columns[column].width + hseparation + frame->padding.size.x; + offset.x += table->columns[column].width + theme_cache.table_h_separation + frame->padding.size.x; row_height = MAX(yofs, row_height); // Add row height after last column of the row or last cell of the table. if (column == col_count - 1 || E->next() == nullptr) { offset.x = 0; - row_height += vseparation; + row_height += theme_cache.table_v_separation; table->total_height += row_height; offset.y += row_height; table->rows.push_back(row_height); @@ -723,7 +718,6 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)p_frame->lines.size(), 0); Vector2 off; - int line_spacing = get_theme_constant(SNAME("line_separation")); Line &l = p_frame->lines[p_line]; MutexLock lock(l.text_buf->get_mutex()); @@ -775,8 +769,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } if (!prefix.is_empty()) { - Ref<Font> font = get_theme_font(SNAME("normal_font")); - int font_size = get_theme_font_size(SNAME("normal_font_size")); + Ref<Font> font = theme_cache.normal_font; + int font_size = theme_cache.normal_font_size; ItemFont *font_it = _find_font(l.from); if (font_it) { @@ -819,7 +813,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o // Draw text. for (int line = 0; line < l.text_buf->get_line_count(); line++) { if (line > 0) { - off.y += line_spacing; + off.y += theme_cache.line_separation; } if (p_ofs.y + off.y >= ctrl_size.height) { @@ -894,10 +888,11 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } break; case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); - Color odd_row_bg = get_theme_color(SNAME("table_odd_row_bg")); - Color even_row_bg = get_theme_color(SNAME("table_even_row_bg")); - Color border = get_theme_color(SNAME("table_border")); - int hseparation = get_theme_constant(SNAME("table_h_separation")); + Color odd_row_bg = theme_cache.table_odd_row_bg; + Color even_row_bg = theme_cache.table_even_row_bg; + Color border = theme_cache.table_border; + int hseparation = theme_cache.table_h_separation; + int col_count = table->columns.size(); int row_count = table->rows.size(); @@ -1033,8 +1028,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o uint64_t char_current_rand = item_shake->offset_random(glyphs[i].start); uint64_t char_previous_rand = item_shake->offset_previous_random(glyphs[i].start); uint64_t max_rand = 2147483647; - double current_offset = Math::range_lerp(char_current_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); - double previous_offset = Math::range_lerp(char_previous_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); + double current_offset = Math::remap(char_current_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); + double previous_offset = Math::remap(char_previous_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); double n_time = (double)(item_shake->elapsed_time / (0.5f / item_shake->rate)); n_time = (n_time > 1.0) ? 1.0 : n_time; item_shake->prev_off = Point2(Math::lerp(Math::sin(previous_offset), Math::sin(current_offset), n_time), Math::lerp(Math::cos(previous_offset), Math::cos(current_offset), n_time)) * (float)item_shake->strength / 10.0f; @@ -1093,8 +1088,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o _draw_fbg_boxes(ci, rid, fbg_line_off, it_from, it_to, chr_range.x, chr_range.y, 0); // Draw main text. - Color selection_fg = get_theme_color(SNAME("font_selected_color")); - Color selection_bg = get_theme_color(SNAME("selection_color")); + Color selection_fg = theme_cache.font_selected_color; + Color selection_bg = theme_cache.selection_color; int sel_start = -1; int sel_end = -1; @@ -1136,7 +1131,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } else if (ul_started) { ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); } if (_find_hint(it, nullptr) && underline_hint) { @@ -1149,7 +1144,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } else if (dot_ul_started) { dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); } if (_find_strikethrough(it)) { @@ -1162,7 +1157,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } else if (st_started) { st_started = false; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); } @@ -1248,8 +1243,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o uint64_t char_current_rand = item_shake->offset_random(glyphs[i].start); uint64_t char_previous_rand = item_shake->offset_previous_random(glyphs[i].start); uint64_t max_rand = 2147483647; - double current_offset = Math::range_lerp(char_current_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); - double previous_offset = Math::range_lerp(char_previous_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); + double current_offset = Math::remap(char_current_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); + double previous_offset = Math::remap(char_previous_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI); double n_time = (double)(item_shake->elapsed_time / (0.5f / item_shake->rate)); n_time = (n_time > 1.0) ? 1.0 : n_time; item_shake->prev_off = Point2(Math::lerp(Math::sin(previous_offset), Math::sin(current_offset), n_time), Math::lerp(Math::cos(previous_offset), Math::cos(current_offset), n_time)) * (float)item_shake->strength / 10.0f; @@ -1301,19 +1296,19 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o if (ul_started) { ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); } if (dot_ul_started) { dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); } if (st_started) { st_started = false; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); } } @@ -1323,19 +1318,19 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o if (ul_started) { ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); } if (dot_ul_started) { dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); } if (st_started) { st_started = false; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); } // Draw foreground color box @@ -1371,7 +1366,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item while (ofs.y < size.height && from_line < to_line) { MutexLock lock(main->lines[from_line].text_buf->get_mutex()); _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char, false, p_meta); - ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * theme_cache.line_separation; if (((r_click_item != nullptr) && ((*r_click_item) != nullptr)) || ((r_click_frame != nullptr) && ((*r_click_frame) != nullptr))) { if (r_outside != nullptr) { *r_outside = false; @@ -1449,9 +1444,6 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) { switch (it->type) { case ITEM_TABLE: { - int hseparation = get_theme_constant(SNAME("table_h_separation")); - int vseparation = get_theme_constant(SNAME("table_v_separation")); - ItemTable *table = static_cast<ItemTable *>(it); int idx = 0; @@ -1469,7 +1461,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V if (rtl) { coff.x = rect.size.width - table->columns[col].width - coff.x; } - Rect2 crect = Rect2(rect.position + coff - frame->padding.position, Size2(table->columns[col].width + hseparation, table->rows[row] + vseparation) + frame->padding.position + frame->padding.size); + Rect2 crect = Rect2(rect.position + coff - frame->padding.position, Size2(table->columns[col].width + theme_cache.table_h_separation, table->rows[row] + theme_cache.table_v_separation) + frame->padding.position + frame->padding.size); if (col == col_count - 1) { if (rtl) { crect.size.x = crect.position.x + crect.size.x; @@ -1508,7 +1500,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V } Rect2 rect = Rect2(p_ofs + off - Vector2(0, TS->shaped_text_get_ascent(rid)) - p_frame->padding.position, TS->shaped_text_get_size(rid) + p_frame->padding.position + p_frame->padding.size); if (p_table) { - rect.size.y += get_theme_constant(SNAME("table_v_separation")); + rect.size.y += theme_cache.table_v_separation; } if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) { @@ -1547,7 +1539,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V return table_offy; } - off.y += TS->shaped_text_get_descent(rid) + get_theme_constant(SNAME("line_separation")); + off.y += TS->shaped_text_get_descent(rid) + theme_cache.line_separation; } // Text line hit. @@ -1562,8 +1554,8 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V int stop = text_rect_begin; *r_click_item = _find_indentable(it); while (*r_click_item) { - Ref<Font> font = get_theme_font(SNAME("normal_font")); - int font_size = get_theme_font_size(SNAME("normal_font_size")); + Ref<Font> font = theme_cache.normal_font; + int font_size = theme_cache.normal_font_size; ItemFont *font_it = _find_font(*r_click_item); if (font_it) { if (font_it->font.is_valid()) { @@ -1676,7 +1668,48 @@ int RichTextLabel::_find_first_line(int p_from, int p_to, int p_vofs) const { } _FORCE_INLINE_ float RichTextLabel::_calculate_line_vertical_offset(const RichTextLabel::Line &line) const { - return line.get_height(get_theme_constant(SNAME("line_separation"))); + return line.get_height(theme_cache.line_separation); +} + +void RichTextLabel::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); + theme_cache.focus_style = get_theme_stylebox(SNAME("focus")); + theme_cache.progress_bg_style = get_theme_stylebox(SNAME("background"), SNAME("ProgressBar")); + theme_cache.progress_fg_style = get_theme_stylebox(SNAME("fill"), SNAME("ProgressBar")); + + theme_cache.line_separation = get_theme_constant(SNAME("line_separation")); + + theme_cache.normal_font = get_theme_font(SNAME("normal_font")); + theme_cache.normal_font_size = get_theme_font_size(SNAME("normal_font_size")); + + theme_cache.default_color = get_theme_color(SNAME("default_color")); + theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); + theme_cache.selection_color = get_theme_color(SNAME("selection_color")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + theme_cache.font_shadow_color = get_theme_color(SNAME("font_shadow_color")); + theme_cache.shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); + theme_cache.shadow_offset_x = get_theme_constant(SNAME("shadow_offset_x")); + theme_cache.shadow_offset_y = get_theme_constant(SNAME("shadow_offset_y")); + theme_cache.outline_size = get_theme_constant(SNAME("outline_size")); + + theme_cache.bold_font = get_theme_font(SNAME("bold_font")); + theme_cache.bold_font_size = get_theme_font_size(SNAME("bold_font_size")); + theme_cache.bold_italics_font = get_theme_font(SNAME("bold_italics_font")); + theme_cache.bold_italics_font_size = get_theme_font_size(SNAME("bold_italics_font_size")); + theme_cache.italics_font = get_theme_font(SNAME("italics_font")); + theme_cache.italics_font_size = get_theme_font_size(SNAME("italics_font_size")); + theme_cache.mono_font = get_theme_font(SNAME("mono_font")); + theme_cache.mono_font_size = get_theme_font_size(SNAME("mono_font_size")); + + theme_cache.table_h_separation = get_theme_constant(SNAME("table_h_separation")); + theme_cache.table_v_separation = get_theme_constant(SNAME("table_v_separation")); + theme_cache.table_odd_row_bg = get_theme_color(SNAME("table_odd_row_bg")); + theme_cache.table_even_row_bg = get_theme_color(SNAME("table_even_row_bg")); + theme_cache.table_border = get_theme_color(SNAME("table_border")); + + theme_cache.base_scale = get_theme_default_base_scale(); } void RichTextLabel::_notification(int p_what) { @@ -1732,11 +1765,11 @@ void RichTextLabel::_notification(int p_what) { RID ci = get_canvas_item(); Size2 size = get_size(); - draw_style_box(get_theme_stylebox(SNAME("normal")), Rect2(Point2(), size)); + draw_style_box(theme_cache.normal_style, Rect2(Point2(), size)); if (has_focus()) { RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, true); - draw_style_box(get_theme_stylebox(SNAME("focus")), Rect2(Point2(), size)); + draw_style_box(theme_cache.focus_style, Rect2(Point2(), size)); RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, false); } @@ -1746,24 +1779,20 @@ void RichTextLabel::_notification(int p_what) { } else { // Draw loading progress bar. if ((progress_delay > 0) && (OS::get_singleton()->get_ticks_msec() - loading_started >= (uint64_t)progress_delay)) { - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg"), SNAME("ProgressBar")); - Ref<StyleBox> fg = get_theme_stylebox(SNAME("fg"), SNAME("ProgressBar")); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Vector2 p_size = Vector2(size.width - (theme_cache.normal_style->get_offset().x + vscroll->get_combined_minimum_size().width) * 2, vscroll->get_combined_minimum_size().width); + Vector2 p_pos = Vector2(theme_cache.normal_style->get_offset().x, size.height - theme_cache.normal_style->get_offset().y - vscroll->get_combined_minimum_size().width); - Vector2 p_size = Vector2(size.width - (style->get_offset().x + vscroll->get_combined_minimum_size().width) * 2, vscroll->get_combined_minimum_size().width); - Vector2 p_pos = Vector2(style->get_offset().x, size.height - style->get_offset().y - vscroll->get_combined_minimum_size().width); - - draw_style_box(bg, Rect2(p_pos, p_size)); + draw_style_box(theme_cache.progress_bg_style, Rect2(p_pos, p_size)); bool right_to_left = is_layout_rtl(); double r = loaded.load(); - int mp = fg->get_minimum_size().width; + int mp = theme_cache.progress_fg_style->get_minimum_size().width; int p = round(r * (p_size.width - mp)); if (right_to_left) { int p_remaining = round((1.0 - r) * (p_size.width - mp)); - draw_style_box(fg, Rect2(p_pos + Point2(p_remaining, 0), Size2(p + fg->get_minimum_size().width, p_size.height))); + draw_style_box(theme_cache.progress_fg_style, Rect2(p_pos + Point2(p_remaining, 0), Size2(p + theme_cache.progress_fg_style->get_minimum_size().width, p_size.height))); } else { - draw_style_box(fg, Rect2(p_pos, Size2(p + fg->get_minimum_size().width, p_size.height))); + draw_style_box(theme_cache.progress_fg_style, Rect2(p_pos, Size2(p + theme_cache.progress_fg_style->get_minimum_size().width, p_size.height))); } } } @@ -1776,13 +1805,7 @@ void RichTextLabel::_notification(int p_what) { int to_line = main->first_invalid_line.load(); int from_line = _find_first_line(0, to_line, vofs); - Ref<Font> base_font = get_theme_font(SNAME("normal_font")); - Color base_color = get_theme_color(SNAME("default_color")); - Color outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - Color font_shadow_color = get_theme_color(SNAME("font_shadow_color")); - int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); - Point2 shadow_ofs(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); + Point2 shadow_ofs(theme_cache.shadow_offset_x, theme_cache.shadow_offset_y); visible_paragraph_count = 0; visible_line_count = 0; @@ -1794,8 +1817,8 @@ void RichTextLabel::_notification(int p_what) { MutexLock lock(main->lines[from_line].text_buf->get_mutex()); visible_paragraph_count++; - visible_line_count += _draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_shadow_color, shadow_outline_size, shadow_ofs, processed_glyphs); - ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + visible_line_count += _draw_line(main, from_line, ofs, text_rect.size.x, theme_cache.default_color, theme_cache.outline_size, theme_cache.font_outline_color, theme_cache.font_shadow_color, theme_cache.shadow_outline_size, shadow_ofs, processed_glyphs); + ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * theme_cache.line_separation; from_line++; } } break; @@ -2003,11 +2026,11 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) { handled = true; } if (k->is_action("ui_up") && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() - get_theme_font(SNAME("normal_font"))->get_height(get_theme_font_size(SNAME("normal_font_size")))); + vscroll->set_value(vscroll->get_value() - theme_cache.normal_font->get_height(theme_cache.normal_font_size)); handled = true; } if (k->is_action("ui_down") && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() + get_theme_font(SNAME("normal_font"))->get_height(get_theme_font_size(SNAME("normal_font_size")))); + vscroll->set_value(vscroll->get_value() + theme_cache.normal_font->get_height(theme_cache.normal_font_size)); handled = true; } if (k->is_action("ui_home") && vscroll->is_visible_in_tree()) { @@ -2540,7 +2563,9 @@ bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) { void RichTextLabel::_thread_function(void *self) { RichTextLabel *rtl = reinterpret_cast<RichTextLabel *>(self); + rtl->set_physics_process_internal(true); rtl->_process_line_caches(); + rtl->set_physics_process_internal(false); rtl->updating.store(false); rtl->call_deferred(SNAME("queue_redraw")); } @@ -2587,14 +2612,12 @@ bool RichTextLabel::_validate_line_caches() { MutexLock data_lock(data_mutex); Rect2 text_rect = _get_text_rect(); - Ref<Font> base_font = get_theme_font(SNAME("normal_font")); - int base_font_size = get_theme_font_size(SNAME("normal_font_size")); int ctrl_height = get_size().height; // Update fonts. if (main->first_invalid_font_line.load() != (int)main->lines.size()) { for (int i = main->first_invalid_font_line.load(); i < (int)main->lines.size(); i++) { - _update_line_font(main, i, base_font, base_font_size); + _update_line_font(main, i, theme_cache.normal_font, theme_cache.normal_font_size); } main->first_resized_line.store(main->first_invalid_font_line.load()); main->first_invalid_font_line.store(main->lines.size()); @@ -2609,7 +2632,7 @@ bool RichTextLabel::_validate_line_caches() { float total_height = (fi == 0) ? 0 : _calculate_line_vertical_offset(main->lines[fi - 1]); for (int i = fi; i < (int)main->lines.size(); i++) { - total_height = _resize_line(main, i, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height); + total_height = _resize_line(main, i, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height); updating_scroll = true; bool exceeds = total_height > ctrl_height && scroll_active; @@ -2629,7 +2652,7 @@ bool RichTextLabel::_validate_line_caches() { total_height = 0; for (int j = 0; j <= i; j++) { - total_height = _resize_line(main, j, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height); + total_height = _resize_line(main, j, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height); main->first_resized_line.store(j); } @@ -2658,7 +2681,6 @@ bool RichTextLabel::_validate_line_caches() { loaded.store(true); thread.start(RichTextLabel::_thread_function, reinterpret_cast<void *>(this)); loading_started = OS::get_singleton()->get_ticks_msec(); - set_physics_process_internal(true); return false; } else { _process_line_caches(); @@ -2676,15 +2698,13 @@ void RichTextLabel::_process_line_caches() { MutexLock data_lock(data_mutex); Rect2 text_rect = _get_text_rect(); - int base_font_size = get_theme_font_size(SNAME("normal_font_size")); - Ref<Font> base_font = get_theme_font(SNAME("normal_font")); int ctrl_height = get_size().height; int fi = main->first_invalid_line.load(); int total_chars = (fi == 0) ? 0 : (main->lines[fi].char_offset + main->lines[fi].char_count); float total_height = (fi == 0) ? 0 : _calculate_line_vertical_offset(main->lines[fi - 1]); for (int i = fi; i < (int)main->lines.size(); i++) { - total_height = _shape_line(main, i, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height, &total_chars); + total_height = _shape_line(main, i, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height, &total_chars); updating_scroll = true; bool exceeds = total_height > ctrl_height && scroll_active; if (exceeds != scroll_visible) { @@ -2705,7 +2725,7 @@ void RichTextLabel::_process_line_caches() { // since scroll was added or removed we need to resize all lines total_height = 0; for (int j = 0; j <= i; j++) { - total_height = _resize_line(main, j, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height); + total_height = _resize_line(main, j, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height); main->first_invalid_line.store(j); main->first_resized_line.store(j); @@ -2998,38 +3018,33 @@ void RichTextLabel::push_font(const Ref<Font> &p_font, int p_size) { } void RichTextLabel::push_normal() { - Ref<Font> normal_font = get_theme_font(SNAME("normal_font")); - ERR_FAIL_COND(normal_font.is_null()); + ERR_FAIL_COND(theme_cache.normal_font.is_null()); - push_font(normal_font, get_theme_font_size(SNAME("normal_font_size"))); + push_font(theme_cache.normal_font, theme_cache.normal_font_size); } void RichTextLabel::push_bold() { - Ref<Font> bold_font = get_theme_font(SNAME("bold_font")); - ERR_FAIL_COND(bold_font.is_null()); + ERR_FAIL_COND(theme_cache.bold_font.is_null()); - push_font(bold_font, get_theme_font_size(SNAME("bold_font_size"))); + push_font(theme_cache.bold_font, theme_cache.bold_font_size); } void RichTextLabel::push_bold_italics() { - Ref<Font> bold_italics_font = get_theme_font(SNAME("bold_italics_font")); - ERR_FAIL_COND(bold_italics_font.is_null()); + ERR_FAIL_COND(theme_cache.bold_italics_font.is_null()); - push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); + push_font(theme_cache.bold_italics_font, theme_cache.bold_italics_font_size); } void RichTextLabel::push_italics() { - Ref<Font> italics_font = get_theme_font(SNAME("italics_font")); - ERR_FAIL_COND(italics_font.is_null()); + ERR_FAIL_COND(theme_cache.italics_font.is_null()); - push_font(italics_font, get_theme_font_size(SNAME("italics_font_size"))); + push_font(theme_cache.italics_font, theme_cache.italics_font_size); } void RichTextLabel::push_mono() { - Ref<Font> mono_font = get_theme_font(SNAME("mono_font")); - ERR_FAIL_COND(mono_font.is_null()); + ERR_FAIL_COND(theme_cache.mono_font.is_null()); - push_font(mono_font, get_theme_font_size(SNAME("mono_font_size"))); + push_font(theme_cache.mono_font, theme_cache.mono_font_size); } void RichTextLabel::push_font_size(int p_font_size) { @@ -3476,13 +3491,6 @@ void RichTextLabel::append_text(const String &p_bbcode) { int pos = 0; List<String> tag_stack; - Ref<Font> normal_font = get_theme_font(SNAME("normal_font")); - Ref<Font> bold_font = get_theme_font(SNAME("bold_font")); - Ref<Font> italics_font = get_theme_font(SNAME("italics_font")); - Ref<Font> bold_italics_font = get_theme_font(SNAME("bold_italics_font")); - Ref<Font> mono_font = get_theme_font(SNAME("mono_font")); - - Color base_color = get_theme_color(SNAME("default_color")); int indent_level = 0; @@ -3627,9 +3635,9 @@ void RichTextLabel::append_text(const String &p_bbcode) { //use bold font in_bold = true; if (in_italics) { - push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); + push_font(theme_cache.bold_italics_font, theme_cache.bold_italics_font_size); } else { - push_font(bold_font, get_theme_font_size(SNAME("bold_font_size"))); + push_font(theme_cache.bold_font, theme_cache.bold_font_size); } pos = brk_end + 1; tag_stack.push_front(tag); @@ -3637,15 +3645,15 @@ void RichTextLabel::append_text(const String &p_bbcode) { //use italics font in_italics = true; if (in_bold) { - push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); + push_font(theme_cache.bold_italics_font, theme_cache.bold_italics_font_size); } else { - push_font(italics_font, get_theme_font_size(SNAME("italics_font_size"))); + push_font(theme_cache.italics_font, theme_cache.italics_font_size); } pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "code") { //use monospace font - push_font(mono_font, get_theme_font_size(SNAME("mono_font_size"))); + push_font(theme_cache.mono_font, theme_cache.mono_font_size); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag.begins_with("table=")) { @@ -3930,11 +3938,11 @@ void RichTextLabel::append_text(const String &p_bbcode) { tag_stack.push_front("hint"); } else if (tag.begins_with("dropcap")) { Vector<String> subtag = tag.substr(5, tag.length()).split(" "); - int fs = get_theme_font_size(SNAME("normal_font_size")) * 3; - Ref<Font> f = get_theme_font(SNAME("normal_font")); - Color color = get_theme_color(SNAME("default_color")); - Color outline_color = get_theme_color(SNAME("outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + int fs = theme_cache.normal_font_size * 3; + Ref<Font> f = theme_cache.normal_font; + Color color = theme_cache.default_color; + Color outline_color = theme_cache.font_outline_color; + int outline_size = theme_cache.outline_size; Rect2 dropcap_margins = Rect2(); for (int i = 0; i < subtag.size(); i++) { @@ -4052,14 +4060,14 @@ void RichTextLabel::append_text(const String &p_bbcode) { tag_stack.push_front(bbcode_name); } else if (tag.begins_with("color=")) { String color_str = tag.substr(6, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_color(color); pos = brk_end + 1; tag_stack.push_front("color"); } else if (tag.begins_with("outline_color=")) { String color_str = tag.substr(14, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_outline_color(color); pos = brk_end + 1; tag_stack.push_front("outline_color"); @@ -4074,7 +4082,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { String fnt_ftr = tag.substr(18, tag.length()); Vector<String> subtag = fnt_ftr.split(","); if (subtag.size() > 0) { - Ref<Font> font = normal_font; + Ref<Font> font = theme_cache.normal_font; int font_size = 0; ItemFont *font_it = _find_font(current); if (font_it) { @@ -4286,7 +4294,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } else if (tag.begins_with("bgcolor=")) { String color_str = tag.substr(8, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_bgcolor(color); pos = brk_end + 1; @@ -4294,7 +4302,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } else if (tag.begins_with("fgcolor=")) { String color_str = tag.substr(8, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_fgcolor(color); pos = brk_end + 1; @@ -4360,12 +4368,12 @@ int RichTextLabel::get_visible_paragraph_count() const { } void RichTextLabel::scroll_to_line(int p_line) { - _validate_line_caches(); - if (p_line <= 0) { vscroll->set_value(0); return; } + _validate_line_caches(); + int line_count = 0; int to_line = main->first_invalid_line.load(); for (int i = 0; i < to_line; i++) { @@ -4373,7 +4381,7 @@ void RichTextLabel::scroll_to_line(int p_line) { if ((line_count <= p_line) && (line_count + main->lines[i].text_buf->get_line_count() >= p_line)) { float line_offset = 0.f; for (int j = 0; j < p_line - line_count; j++) { - line_offset += main->lines[i].text_buf->get_line_size(j).y + get_theme_constant(SNAME("line_separation")); + line_offset += main->lines[i].text_buf->get_line_size(j).y + theme_cache.line_separation; } vscroll->set_value(main->lines[i].offset.y + line_offset); return; @@ -4391,7 +4399,7 @@ float RichTextLabel::get_line_offset(int p_line) { if ((line_count <= p_line) && (p_line <= line_count + main->lines[i].text_buf->get_line_count())) { float line_offset = 0.f; for (int j = 0; j < p_line - line_count; j++) { - line_offset += main->lines[i].text_buf->get_line_size(j).y + get_theme_constant(SNAME("line_separation")); + line_offset += main->lines[i].text_buf->get_line_size(j).y + theme_cache.line_separation; } return main->lines[i].offset.y + line_offset; } @@ -4997,7 +5005,7 @@ int RichTextLabel::get_content_height() const { int to_line = main->first_invalid_line.load(); if (to_line) { MutexLock lock(main->lines[to_line - 1].text_buf->get_mutex()); - total_height = main->lines[to_line - 1].offset.y + main->lines[to_line - 1].text_buf->get_size().y + main->lines[to_line - 1].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + total_height = main->lines[to_line - 1].offset.y + main->lines[to_line - 1].text_buf->get_size().y + main->lines[to_line - 1].text_buf->get_line_count() * theme_cache.line_separation; } return total_height; } @@ -5367,8 +5375,7 @@ void RichTextLabel::set_fixed_size_to_width(int p_width) { } Size2 RichTextLabel::get_minimum_size() const { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - Size2 size = style->get_minimum_size(); + Size2 size = theme_cache.normal_style->get_minimum_size(); if (fixed_width != -1) { size.x += fixed_width; diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 79f9c62539..8bc28a9ecf 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -83,6 +83,7 @@ public: }; protected: + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); @@ -512,6 +513,46 @@ private: bool fit_content_height = false; + struct ThemeCache { + Ref<StyleBox> normal_style; + Ref<StyleBox> focus_style; + Ref<StyleBox> progress_bg_style; + Ref<StyleBox> progress_fg_style; + + int line_separation; + + Ref<Font> normal_font; + int normal_font_size; + + Color default_color; + Color font_selected_color; + Color selection_color; + Color font_outline_color; + Color font_shadow_color; + int shadow_outline_size; + int shadow_offset_x; + int shadow_offset_y; + int outline_size; + Color outline_color; + + Ref<Font> bold_font; + int bold_font_size; + Ref<Font> bold_italics_font; + int bold_italics_font_size; + Ref<Font> italics_font; + int italics_font_size; + Ref<Font> mono_font; + int mono_font_size; + + int table_h_separation; + int table_v_separation; + Color table_odd_row_bg; + Color table_even_row_bg; + Color table_border; + + float base_scale = 1.0; + } theme_cache; + public: String get_parsed_text() const; void add_text(const String &p_text); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 374ce6feea..6c05b171e3 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -321,7 +321,7 @@ void ScrollBar::_notification(int p_what) { if (drag_node) { drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONESHOT); + drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT); } } break; @@ -613,7 +613,7 @@ void ScrollBar::set_drag_node(const NodePath &p_path) { if (drag_node) { drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONESHOT); + drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT); } } } diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index f68cebd657..c12ac115b7 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -76,14 +76,14 @@ Size2 ScrollContainer::get_minimum_size() const { min_size.x += v_scroll->get_minimum_size().x; } - min_size += theme_cache.bg_style->get_minimum_size(); + min_size += theme_cache.panel_style->get_minimum_size(); return min_size; } void ScrollContainer::_update_theme_item_cache() { Container::_update_theme_item_cache(); - theme_cache.bg_style = get_theme_stylebox(SNAME("bg")); + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); } void ScrollContainer::_cancel_drag() { @@ -276,8 +276,8 @@ void ScrollContainer::_reposition_children() { Size2 size = get_size(); Point2 ofs; - size -= theme_cache.bg_style->get_minimum_size(); - ofs += theme_cache.bg_style->get_offset(); + size -= theme_cache.panel_style->get_minimum_size(); + ofs += theme_cache.panel_style->get_offset(); bool rtl = is_layout_rtl(); if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons @@ -341,7 +341,7 @@ void ScrollContainer::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - draw_style_box(theme_cache.bg_style, Rect2(Vector2(), get_size())); + draw_style_box(theme_cache.panel_style, Rect2(Vector2(), get_size())); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -416,7 +416,7 @@ void ScrollContainer::_notification(int p_what) { void ScrollContainer::update_scrollbars() { Size2 size = get_size(); - size -= theme_cache.bg_style->get_minimum_size(); + size -= theme_cache.panel_style->get_minimum_size(); Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index fa1f09ab3f..f4899846f4 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -70,7 +70,7 @@ private: bool follow_focus = false; struct ThemeCache { - Ref<StyleBox> bg_style; + Ref<StyleBox> panel_style; } theme_cache; void _cancel_drag(); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index e7e955a17f..2ca1d6239e 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -33,11 +33,99 @@ #include "label.h" #include "margin_container.h" +void SplitContainerDragger::gui_input(const Ref<InputEvent> &p_event) { + ERR_FAIL_COND(p_event.is_null()); + + SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent()); + + if (sc->collapsed || !sc->_getch(0) || !sc->_getch(1) || sc->dragger_visibility != SplitContainer::DRAGGER_VISIBLE) { + return; + } + + Ref<InputEventMouseButton> mb = p_event; + + if (mb.is_valid()) { + if (mb->get_button_index() == MouseButton::LEFT) { + if (mb->is_pressed()) { + sc->_compute_middle_sep(true); + dragging = true; + drag_ofs = sc->split_offset; + if (sc->vertical) { + drag_from = get_transform().xform(mb->get_position()).y; + } else { + drag_from = get_transform().xform(mb->get_position()).x; + } + } else { + dragging = false; + queue_redraw(); + } + } + } + + Ref<InputEventMouseMotion> mm = p_event; + + if (mm.is_valid()) { + if (!dragging) { + return; + } + + Vector2i in_parent_pos = get_transform().xform(mm->get_position()); + if (!sc->vertical && is_layout_rtl()) { + sc->split_offset = drag_ofs - ((sc->vertical ? in_parent_pos.y : in_parent_pos.x) - drag_from); + } else { + sc->split_offset = drag_ofs + ((sc->vertical ? in_parent_pos.y : in_parent_pos.x) - drag_from); + } + sc->_compute_middle_sep(true); + sc->queue_sort(); + sc->emit_signal(SNAME("dragged"), sc->get_split_offset()); + } +} + +Control::CursorShape SplitContainerDragger::get_cursor_shape(const Point2 &p_pos) const { + SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent()); + + if (!sc->collapsed && sc->dragger_visibility == SplitContainer::DRAGGER_VISIBLE) { + return (sc->vertical ? CURSOR_VSPLIT : CURSOR_HSPLIT); + } + + return Control::get_cursor_shape(p_pos); +} + +void SplitContainerDragger::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_MOUSE_ENTER: { + mouse_inside = true; + SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent()); + if (sc->get_theme_constant(SNAME("autohide"))) { + queue_redraw(); + } + } break; + + case NOTIFICATION_MOUSE_EXIT: { + mouse_inside = false; + SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent()); + if (sc->get_theme_constant(SNAME("autohide"))) { + queue_redraw(); + } + } break; + + case NOTIFICATION_DRAW: { + SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent()); + if (!dragging && !mouse_inside && sc->get_theme_constant(SNAME("autohide"))) { + return; + } + + Ref<Texture2D> tex = sc->get_theme_icon(SNAME("grabber")); + draw_texture(tex, (get_size() - tex->get_size()) / 2); + } break; + } +} + Control *SplitContainer::_getch(int p_idx) const { int idx = 0; - for (int i = 0; i < get_child_count(); i++) { - Control *c = Object::cast_to<Control>(get_child(i)); + for (int i = 0; i < get_child_count(false); i++) { + Control *c = Object::cast_to<Control>(get_child(i, false)); if (!c || !c->is_visible()) { continue; } @@ -55,56 +143,84 @@ Control *SplitContainer::_getch(int p_idx) const { return nullptr; } -void SplitContainer::_resort() { - int axis = vertical ? 1 : 0; +Ref<Texture2D> SplitContainer::_get_grabber_icon() const { + if (is_fixed) { + return theme_cache.grabber_icon; + } else { + if (vertical) { + return theme_cache.grabber_icon_v; + } else { + return theme_cache.grabber_icon_h; + } + } +} +void SplitContainer::_compute_middle_sep(bool p_clamp) { Control *first = _getch(0); Control *second = _getch(1); - // If we have only one element - if (!first || !second) { - if (first) { - fit_child_in_rect(first, Rect2(Point2(), get_size())); - } else if (second) { - fit_child_in_rect(second, Rect2(Point2(), get_size())); - } - return; - } - - // Determine expanded children + // Determine expanded children. bool first_expanded = (vertical ? first->get_v_size_flags() : first->get_h_size_flags()) & SIZE_EXPAND; bool second_expanded = (vertical ? second->get_v_size_flags() : second->get_h_size_flags()) & SIZE_EXPAND; - // Determine the separation between items - int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? theme_cache.grabber_icon->get_height() : theme_cache.grabber_icon->get_width()) : 0; + // Compute the minimum size. + int axis = vertical ? 1 : 0; + int size = get_size()[axis]; + int ms_first = first->get_combined_minimum_size()[axis]; + int ms_second = second->get_combined_minimum_size()[axis]; - // Compute the minimum size - Size2 ms_first = first->get_combined_minimum_size(); - Size2 ms_second = second->get_combined_minimum_size(); + // Determine the separation between items. + Ref<Texture2D> g = _get_grabber_icon(); + int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? g->get_height() : g->get_width()) : 0; - // Compute the separator position without the split offset - float ratio = first->get_stretch_ratio() / (first->get_stretch_ratio() + second->get_stretch_ratio()); - int no_offset_middle_sep = 0; + // Compute the wished separation_point. + int wished_middle_sep = 0; + int split_offset_with_collapse = 0; + if (!collapsed) { + split_offset_with_collapse = split_offset; + } if (first_expanded && second_expanded) { - no_offset_middle_sep = get_size()[axis] * ratio - sep / 2; + float ratio = first->get_stretch_ratio() / (first->get_stretch_ratio() + second->get_stretch_ratio()); + wished_middle_sep = size * ratio - sep / 2 + split_offset_with_collapse; } else if (first_expanded) { - no_offset_middle_sep = get_size()[axis] - ms_second[axis] - sep; + wished_middle_sep = size - sep + split_offset_with_collapse; } else { - no_offset_middle_sep = ms_first[axis]; + wished_middle_sep = split_offset_with_collapse; } - // Compute the final middle separation. - middle_sep = no_offset_middle_sep; - if (!collapsed) { - int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, (get_size()[axis] - ms_second[axis] - sep) - no_offset_middle_sep); - middle_sep += clamped_split_offset; - if (should_clamp_split_offset) { - split_offset = clamped_split_offset; + // Clamp the middle sep to acceptatble values. + middle_sep = CLAMP(wished_middle_sep, ms_first, size - sep - ms_second); + + // Clamp the split_offset if requested. + if (p_clamp) { + split_offset -= wished_middle_sep - middle_sep; + p_clamp = false; + } +} - should_clamp_split_offset = false; +void SplitContainer::_resort() { + Control *first = _getch(0); + Control *second = _getch(1); + + // If we have only one element. + if (!first || !second) { + if (first) { + fit_child_in_rect(first, Rect2(Point2(), get_size())); + } else if (second) { + fit_child_in_rect(second, Rect2(Point2(), get_size())); } + dragging_area_control->hide(); + return; } + // If we have more that one. + _compute_middle_sep(false); + + // Determine the separation between items. + Ref<Texture2D> g = _get_grabber_icon(); + int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? g->get_height() : g->get_width()) : 0; + + // Move the children, including the dragger. if (vertical) { fit_child_in_rect(first, Rect2(Point2(0, 0), Size2(get_size().width, middle_sep))); int sofs = middle_sep + sep; @@ -122,14 +238,27 @@ void SplitContainer::_resort() { } } - queue_redraw(); + // Handle the dragger visibility and position. + if (dragger_visibility == DRAGGER_VISIBLE && !collapsed) { + dragging_area_control->show(); + + int dragger_ctrl_size = MAX(sep, theme_cache.minimum_grab_thickness); + if (vertical) { + dragging_area_control->set_rect(Rect2(Point2(0, middle_sep - (dragger_ctrl_size - sep) / 2), Size2(get_size().width, dragger_ctrl_size))); + } else { + dragging_area_control->set_rect(Rect2(Point2(middle_sep - (dragger_ctrl_size - sep) / 2, 0), Size2(dragger_ctrl_size, get_size().height))); + } + + dragging_area_control->queue_redraw(); + } else { + dragging_area_control->hide(); + } } Size2 SplitContainer::get_minimum_size() const { - /* Calculate MINIMUM SIZE */ - Size2i minimum; - int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? theme_cache.grabber_icon->get_height() : theme_cache.grabber_icon->get_width()) : 0; + Ref<Texture2D> g = _get_grabber_icon(); + int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? g->get_height() : g->get_width()) : 0; for (int i = 0; i < 2; i++) { if (!_getch(i)) { @@ -158,12 +287,21 @@ Size2 SplitContainer::get_minimum_size() const { return minimum; } +void SplitContainer::_validate_property(PropertyInfo &p_property) const { + if (is_fixed && p_property.name == "vertical") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + void SplitContainer::_update_theme_item_cache() { Container::_update_theme_item_cache(); theme_cache.separation = get_theme_constant(SNAME("separation")); + theme_cache.minimum_grab_thickness = get_theme_constant(SNAME("minimum_grab_thickness")); theme_cache.autohide = get_theme_constant(SNAME("autohide")); theme_cache.grabber_icon = get_theme_icon(SNAME("grabber")); + theme_cache.grabber_icon_h = get_theme_icon(SNAME("h_grabber")); + theme_cache.grabber_icon_v = get_theme_icon(SNAME("v_grabber")); } void SplitContainer::_notification(int p_what) { @@ -177,126 +315,12 @@ void SplitContainer::_notification(int p_what) { _resort(); } break; - case NOTIFICATION_MOUSE_EXIT: { - mouse_inside = false; - if (theme_cache.autohide) { - queue_redraw(); - } - } break; - - case NOTIFICATION_DRAW: { - if (!_getch(0) || !_getch(1)) { - return; - } - - if (collapsed || (!dragging && !mouse_inside && theme_cache.autohide)) { - return; - } - - if (dragger_visibility != DRAGGER_VISIBLE) { - return; - } - - int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? theme_cache.separation : 0; - Ref<Texture2D> tex = theme_cache.grabber_icon; - Size2 size = get_size(); - - if (vertical) { - draw_texture(tex, Point2i((size.x - tex->get_width()) / 2, middle_sep + (sep - tex->get_height()) / 2)); - } else { - draw_texture(tex, Point2i(middle_sep + (sep - tex->get_width()) / 2, (size.y - tex->get_height()) / 2)); - } - } break; - case NOTIFICATION_THEME_CHANGED: { update_minimum_size(); } break; } } -void SplitContainer::gui_input(const Ref<InputEvent> &p_event) { - ERR_FAIL_COND(p_event.is_null()); - - if (collapsed || !_getch(0) || !_getch(1) || dragger_visibility != DRAGGER_VISIBLE) { - return; - } - - Ref<InputEventMouseButton> mb = p_event; - - if (mb.is_valid()) { - if (mb->get_button_index() == MouseButton::LEFT) { - if (mb->is_pressed()) { - if (vertical) { - if (mb->get_position().y > middle_sep && mb->get_position().y < middle_sep + theme_cache.separation) { - dragging = true; - drag_from = mb->get_position().y; - drag_ofs = split_offset; - } - } else { - if (mb->get_position().x > middle_sep && mb->get_position().x < middle_sep + theme_cache.separation) { - dragging = true; - drag_from = mb->get_position().x; - drag_ofs = split_offset; - } - } - } else { - dragging = false; - } - } - } - - Ref<InputEventMouseMotion> mm = p_event; - - if (mm.is_valid()) { - bool mouse_inside_state = false; - if (vertical) { - mouse_inside_state = mm->get_position().y > middle_sep && mm->get_position().y < middle_sep + theme_cache.separation; - } else { - mouse_inside_state = mm->get_position().x > middle_sep && mm->get_position().x < middle_sep + theme_cache.separation; - } - - if (mouse_inside != mouse_inside_state) { - mouse_inside = mouse_inside_state; - if (theme_cache.autohide) { - queue_redraw(); - } - } - - if (!dragging) { - return; - } - - if (!vertical && is_layout_rtl()) { - split_offset = drag_ofs + (drag_from - (vertical ? mm->get_position().y : mm->get_position().x)); - } else { - split_offset = drag_ofs + ((vertical ? mm->get_position().y : mm->get_position().x) - drag_from); - } - should_clamp_split_offset = true; - queue_sort(); - emit_signal(SNAME("dragged"), get_split_offset()); - } -} - -Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const { - if (dragging) { - return (vertical ? CURSOR_VSPLIT : CURSOR_HSPLIT); - } - - if (!collapsed && _getch(0) && _getch(1) && dragger_visibility == DRAGGER_VISIBLE) { - if (vertical) { - if (p_pos.y > middle_sep && p_pos.y < middle_sep + theme_cache.separation) { - return CURSOR_VSPLIT; - } - } else { - if (p_pos.x > middle_sep && p_pos.x < middle_sep + theme_cache.separation) { - return CURSOR_HSPLIT; - } - } - } - - return Control::get_cursor_shape(p_pos); -} - void SplitContainer::set_split_offset(int p_offset) { if (split_offset == p_offset) { return; @@ -312,8 +336,11 @@ int SplitContainer::get_split_offset() const { } void SplitContainer::clamp_split_offset() { - should_clamp_split_offset = true; + if (!_getch(0) || !_getch(1)) { + return; + } + _compute_middle_sep(true); queue_sort(); } @@ -333,7 +360,6 @@ void SplitContainer::set_dragger_visibility(DraggerVisibility p_visibility) { dragger_visibility = p_visibility; queue_sort(); - queue_redraw(); } SplitContainer::DraggerVisibility SplitContainer::get_dragger_visibility() const { @@ -344,6 +370,17 @@ bool SplitContainer::is_collapsed() const { return collapsed; } +void SplitContainer::set_vertical(bool p_vertical) { + ERR_FAIL_COND_MSG(is_fixed, "Can't change orientation of " + get_class() + "."); + vertical = p_vertical; + update_minimum_size(); + _resort(); +} + +bool SplitContainer::is_vertical() const { + return vertical; +} + Vector<int> SplitContainer::get_allowed_size_flags_horizontal() const { Vector<int> flags; flags.append(SIZE_FILL); @@ -379,11 +416,15 @@ void SplitContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_dragger_visibility", "mode"), &SplitContainer::set_dragger_visibility); ClassDB::bind_method(D_METHOD("get_dragger_visibility"), &SplitContainer::get_dragger_visibility); + ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &SplitContainer::set_vertical); + ClassDB::bind_method(D_METHOD("is_vertical"), &SplitContainer::is_vertical); + ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::INT, "offset"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "split_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_split_offset", "get_split_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collapsed"), "set_collapsed", "is_collapsed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden and Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); BIND_ENUM_CONSTANT(DRAGGER_VISIBLE); BIND_ENUM_CONSTANT(DRAGGER_HIDDEN); @@ -392,4 +433,7 @@ void SplitContainer::_bind_methods() { SplitContainer::SplitContainer(bool p_vertical) { vertical = p_vertical; + + dragging_area_control = memnew(SplitContainerDragger); + add_child(dragging_area_control, false, Node::INTERNAL_MODE_BACK); } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 18f9573973..d297e3a3ea 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -33,8 +33,26 @@ #include "scene/gui/container.h" +class SplitContainerDragger : public Control { + GDCLASS(SplitContainerDragger, Control); + +protected: + void _notification(int p_what); + virtual void gui_input(const Ref<InputEvent> &p_event) override; + +private: + bool dragging = false; + int drag_from = 0; + int drag_ofs = 0; + bool mouse_inside = false; + +public: + virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override; +}; + class SplitContainer : public Container { GDCLASS(SplitContainer, Container); + friend class SplitContainerDragger; public: enum DraggerVisibility { @@ -44,32 +62,38 @@ public: }; private: - bool should_clamp_split_offset = false; int split_offset = 0; int middle_sep = 0; bool vertical = false; - bool dragging = false; - int drag_from = 0; - int drag_ofs = 0; bool collapsed = false; DraggerVisibility dragger_visibility = DRAGGER_VISIBLE; - bool mouse_inside = false; + + SplitContainerDragger *dragging_area_control = nullptr; struct ThemeCache { int separation = 0; + int minimum_grab_thickness = 0; int autohide = 0; Ref<Texture2D> grabber_icon; + Ref<Texture2D> grabber_icon_h; + Ref<Texture2D> grabber_icon_v; } theme_cache; Control *_getch(int p_idx) const; + Ref<Texture2D> _get_grabber_icon() const; + void _compute_middle_sep(bool p_clamp); void _resort(); + void _dragging_area_gui_input(const Ref<InputEvent> &p_event); + protected: - virtual void gui_input(const Ref<InputEvent> &p_event) override; + bool is_fixed = false; + virtual void _update_theme_item_cache() override; void _notification(int p_what); + void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); public: @@ -83,7 +107,8 @@ public: void set_dragger_visibility(DraggerVisibility p_visibility); DraggerVisibility get_dragger_visibility() const; - virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override; + void set_vertical(bool p_vertical); + bool is_vertical() const; virtual Size2 get_minimum_size() const override; @@ -100,7 +125,7 @@ class HSplitContainer : public SplitContainer { public: HSplitContainer() : - SplitContainer(false) {} + SplitContainer(false) { is_fixed = true; } }; class VSplitContainer : public SplitContainer { @@ -108,7 +133,7 @@ class VSplitContainer : public SplitContainer { public: VSplitContainer() : - SplitContainer(true) {} + SplitContainer(true) { is_fixed = true; } }; #endif // SPLIT_CONTAINER_H diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index 4d18af7743..cf6681f809 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -162,7 +162,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP && !mb->is_command_pressed()) { + if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP && !mb->is_command_or_control_pressed()) { if (scrolling_enabled && buttons_visible) { if (offset > 0) { offset--; @@ -172,7 +172,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { } } - if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_pressed()) { + if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_or_control_pressed()) { if (scrolling_enabled && buttons_visible) { if (missing_right && offset < tabs.size()) { offset++; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 95338c7b8c..318447ecd8 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1614,7 +1614,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } if (mb->is_pressed()) { - if (mb->get_button_index() == MouseButton::WHEEL_UP && !mb->is_command_pressed()) { + if (mb->get_button_index() == MouseButton::WHEEL_UP && !mb->is_command_or_control_pressed()) { if (mb->is_shift_pressed()) { h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor())); } else if (mb->is_alt_pressed()) { @@ -1625,7 +1625,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { _scroll_up(3 * mb->get_factor()); } } - if (mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_pressed()) { + if (mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_or_control_pressed()) { if (mb->is_shift_pressed()) { h_scroll->set_value(h_scroll->get_value() + (100 * mb->get_factor())); } else if (mb->is_alt_pressed()) { @@ -1920,7 +1920,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { // Allow unicode handling if: // * No Modifiers are pressed (except shift) - bool allow_unicode_handling = !(k->is_command_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); + bool allow_unicode_handling = !(k->is_command_or_control_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); selection.selecting_text = false; @@ -3990,13 +3990,13 @@ bool TextEdit::is_caret_blink_enabled() const { return caret_blink_enabled; } -float TextEdit::get_caret_blink_speed() const { +float TextEdit::get_caret_blink_interval() const { return caret_blink_timer->get_wait_time(); } -void TextEdit::set_caret_blink_speed(const float p_speed) { - ERR_FAIL_COND(p_speed <= 0); - caret_blink_timer->set_wait_time(p_speed); +void TextEdit::set_caret_blink_interval(const float p_interval) { + ERR_FAIL_COND(p_interval <= 0); + caret_blink_timer->set_wait_time(p_interval); } void TextEdit::set_move_caret_on_right_click_enabled(const bool p_enabled) { @@ -4786,6 +4786,9 @@ void TextEdit::add_gutter(int p_at) { } text.add_gutter(p_at); + + _update_gutter_width(); + emit_signal(SNAME("gutter_added")); queue_redraw(); } @@ -4796,6 +4799,9 @@ void TextEdit::remove_gutter(int p_gutter) { gutters.remove_at(p_gutter); text.remove_gutter(p_gutter); + + _update_gutter_width(); + emit_signal(SNAME("gutter_removed")); queue_redraw(); } @@ -5288,8 +5294,8 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_caret_blink_enabled", "enable"), &TextEdit::set_caret_blink_enabled); ClassDB::bind_method(D_METHOD("is_caret_blink_enabled"), &TextEdit::is_caret_blink_enabled); - ClassDB::bind_method(D_METHOD("set_caret_blink_speed", "blink_speed"), &TextEdit::set_caret_blink_speed); - ClassDB::bind_method(D_METHOD("get_caret_blink_speed"), &TextEdit::get_caret_blink_speed); + ClassDB::bind_method(D_METHOD("set_caret_blink_interval", "interval"), &TextEdit::set_caret_blink_interval); + ClassDB::bind_method(D_METHOD("get_caret_blink_interval"), &TextEdit::get_caret_blink_interval); ClassDB::bind_method(D_METHOD("set_move_caret_on_right_click_enabled", "enable"), &TextEdit::set_move_caret_on_right_click_enabled); ClassDB::bind_method(D_METHOD("is_move_caret_on_right_click_enabled"), &TextEdit::is_move_caret_on_right_click_enabled); @@ -5518,7 +5524,7 @@ void TextEdit::_bind_methods() { ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_type", PROPERTY_HINT_ENUM, "Line,Block"), "set_caret_type", "get_caret_type"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_caret_blink_speed", "get_caret_blink_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_interval", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_caret_blink_interval", "get_caret_blink_interval"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_move_on_right_click"), "set_move_caret_on_right_click_enabled", "is_move_caret_on_right_click_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled"); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index f97f99075c..a8da878ede 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -762,8 +762,8 @@ public: void set_caret_blink_enabled(const bool p_enabled); bool is_caret_blink_enabled() const; - void set_caret_blink_speed(const float p_speed); - float get_caret_blink_speed() const; + void set_caret_blink_interval(const float p_interval); + float get_caret_blink_interval() const; void set_move_caret_on_right_click_enabled(const bool p_enabled); bool is_move_caret_on_right_click_enabled() const; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 2efb6593d3..d9ab1c2c55 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -67,7 +67,7 @@ bool TextureButton::has_point(const Point2 &p_point) const { Rect2 rect = Rect2(); Size2 mask_size = click_mask->get_size(); - if (_position_rect.has_no_area()) { + if (!_position_rect.has_area()) { rect.size = mask_size; } else if (_tile) { // if the stretch mode is tile we offset the point to keep it inside the mask size diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index da53da20b0..459e67091d 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -94,7 +94,7 @@ void TextureRect::_notification(int p_what) { Ref<AtlasTexture> p_atlas = texture; - if (p_atlas.is_valid() && region.has_no_area()) { + if (p_atlas.is_valid() && !region.has_area()) { Size2 scale_size(size.width / texture->get_width(), size.height / texture->get_height()); offset.width += hflip ? p_atlas->get_margin().get_position().width * scale_size.width * 2 : 0; @@ -104,10 +104,10 @@ void TextureRect::_notification(int p_what) { size.width *= hflip ? -1.0f : 1.0f; size.height *= vflip ? -1.0f : 1.0f; - if (region.has_no_area()) { - draw_texture_rect(texture, Rect2(offset, size), tile); - } else { + if (region.has_area()) { draw_texture_rect_region(texture, Rect2(offset, size), region); + } else { + draw_texture_rect(texture, Rect2(offset, size), tile); } } break; } diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index e8164b5728..237c78407b 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1538,12 +1538,14 @@ TreeItem::~TreeItem() { void Tree::_update_theme_item_cache() { Control::_update_theme_item_cache(); + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); + theme_cache.focus_style = get_theme_stylebox(SNAME("focus")); + theme_cache.font = get_theme_font(SNAME("font")); theme_cache.font_size = get_theme_font_size(SNAME("font_size")); theme_cache.tb_font = get_theme_font(SNAME("title_button_font")); theme_cache.tb_font_size = get_theme_font_size(SNAME("title_button_font_size")); - theme_cache.bg = get_theme_stylebox(SNAME("bg")); - theme_cache.bg_focus = get_theme_stylebox(SNAME("bg_focus")); + theme_cache.selected = get_theme_stylebox(SNAME("selected")); theme_cache.selected_focus = get_theme_stylebox(SNAME("selected_focus")); theme_cache.cursor = get_theme_stylebox(SNAME("cursor")); @@ -1955,7 +1957,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (i == 0) { if (p_item->cells[0].selected && select_mode == SELECT_ROW) { - Rect2i row_rect = Rect2i(Point2i(theme_cache.bg->get_margin(SIDE_LEFT), item_rect.position.y), Size2i(get_size().width - theme_cache.bg->get_minimum_size().width, item_rect.size.y)); + Rect2i row_rect = Rect2i(Point2i(theme_cache.panel_style->get_margin(SIDE_LEFT), item_rect.position.y), Size2i(get_size().width - theme_cache.panel_style->get_minimum_size().width, item_rect.size.y)); //Rect2 r = Rect2i(row_rect.pos,row_rect.size); //r.grow(cache.selected->get_margin(SIDE_LEFT)); if (rtl) { @@ -2502,7 +2504,7 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) { void Tree::_range_click_timeout() { if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { - Point2 pos = get_local_mouse_position() - theme_cache.bg->get_offset(); + Point2 pos = get_local_mouse_position() - theme_cache.panel_style->get_offset(); if (show_column_titles) { pos.y -= _get_title_button_height(); @@ -2520,7 +2522,7 @@ void Tree::_range_click_timeout() { Ref<InputEventMouseButton> mb; mb.instantiate(); - int x_limit = get_size().width - theme_cache.bg->get_minimum_size().width; + int x_limit = get_size().width - theme_cache.panel_style->get_minimum_size().width; if (h_scroll->is_visible()) { x_limit -= h_scroll->get_minimum_size().width; } @@ -2609,7 +2611,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int return -1; } else if (col == 0) { int margin = x_ofs + theme_cache.item_margin; //-theme_cache.hseparation; - //int lm = theme_cache.bg->get_margin(SIDE_LEFT); + //int lm = theme_cache.panel_style->get_margin(SIDE_LEFT); col_width -= margin; limit_w -= margin; col_ofs += margin; @@ -2684,7 +2686,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int return -1; } - if (select_mode == SELECT_MULTI && p_mod->is_command_pressed() && c.selectable) { + if (select_mode == SELECT_MULTI && p_mod->is_command_or_control_pressed() && c.selectable) { if (!c.selected || p_button == MouseButton::RIGHT) { p_item->select(col); emit_signal(SNAME("multi_selected"), p_item, col, true); @@ -3125,7 +3127,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; - bool is_command = k.is_valid() && k->is_command_pressed(); + bool is_command = k.is_valid() && k->is_command_or_control_pressed(); if (p_event->is_action("ui_right") && p_event->is_pressed()) { if (!cursor_can_exit_tree) { accept_event(); @@ -3283,7 +3285,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { if (!k->is_pressed()) { return; } - if (k->is_command_pressed() || (k->is_shift_pressed() && k->get_unicode() == 0) || k->is_meta_pressed()) { + if (k->is_command_or_control_pressed() || (k->is_shift_pressed() && k->get_unicode() == 0) || k->is_meta_pressed()) { return; } if (!root) { @@ -3308,14 +3310,14 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - Ref<StyleBox> bg = theme_cache.bg; + Ref<StyleBox> bg = theme_cache.panel_style; bool rtl = is_layout_rtl(); Point2 pos = mm->get_position(); if (rtl) { pos.x = get_size().width - pos.x; } - pos -= theme_cache.bg->get_offset(); + pos -= theme_cache.panel_style->get_offset(); Cache::ClickType old_hover = cache.hover_type; int old_index = cache.hover_index; @@ -3343,7 +3345,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { if (rtl) { mpos.x = get_size().width - mpos.x; } - mpos -= theme_cache.bg->get_offset(); + mpos -= theme_cache.panel_style->get_offset(); mpos.y -= _get_title_button_height(); if (mpos.y >= 0) { if (h_scroll->is_visible_in_tree()) { @@ -3443,7 +3445,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { if (rtl) { pos.x = get_size().width - pos.x; } - pos -= theme_cache.bg->get_offset(); + pos -= theme_cache.panel_style->get_offset(); if (show_column_titles) { pos.y -= _get_title_button_height(); @@ -3537,7 +3539,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { switch (mb->get_button_index()) { case MouseButton::RIGHT: case MouseButton::LEFT: { - Ref<StyleBox> bg = theme_cache.bg; + Ref<StyleBox> bg = theme_cache.panel_style; Point2 pos = mb->get_position(); if (rtl) { @@ -3572,7 +3574,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { pressing_for_editor = false; propagate_mouse_activated = false; - int x_limit = get_size().width - theme_cache.bg->get_minimum_size().width; + int x_limit = get_size().width - theme_cache.panel_style->get_minimum_size().width; if (h_scroll->is_visible()) { x_limit -= h_scroll->get_minimum_size().width; } @@ -3613,7 +3615,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { } if (mb->get_button_index() == MouseButton::LEFT) { - if (get_item_at_position(mb->get_position()) == nullptr && !mb->is_shift_pressed() && !mb->is_ctrl_pressed() && !mb->is_command_pressed()) { + if (get_item_at_position(mb->get_position()) == nullptr && !mb->is_shift_pressed() && !mb->is_ctrl_pressed() && !mb->is_command_or_control_pressed()) { emit_signal(SNAME("nothing_selected")); } } @@ -3766,7 +3768,7 @@ bool Tree::is_editing() { } Size2 Tree::get_internal_min_size() const { - Size2i size = theme_cache.bg->get_offset(); + Size2i size = theme_cache.panel_style->get_offset(); if (root) { size.height += get_item_height(root); } @@ -3789,23 +3791,23 @@ void Tree::update_scrollbars() { Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); - v_scroll->set_begin(Point2(size.width - vmin.width, theme_cache.bg->get_margin(SIDE_TOP))); - v_scroll->set_end(Point2(size.width, size.height - theme_cache.bg->get_margin(SIDE_TOP) - theme_cache.bg->get_margin(SIDE_BOTTOM))); + v_scroll->set_begin(Point2(size.width - vmin.width, theme_cache.panel_style->get_margin(SIDE_TOP))); + v_scroll->set_end(Point2(size.width, size.height - theme_cache.panel_style->get_margin(SIDE_TOP) - theme_cache.panel_style->get_margin(SIDE_BOTTOM))); h_scroll->set_begin(Point2(0, size.height - hmin.height)); h_scroll->set_end(Point2(size.width - vmin.width, size.height)); Size2 internal_min_size = get_internal_min_size(); - bool display_vscroll = internal_min_size.height + theme_cache.bg->get_margin(SIDE_TOP) > size.height; - bool display_hscroll = internal_min_size.width + theme_cache.bg->get_margin(SIDE_LEFT) > size.width; + bool display_vscroll = internal_min_size.height + theme_cache.panel_style->get_margin(SIDE_TOP) > size.height; + bool display_hscroll = internal_min_size.width + theme_cache.panel_style->get_margin(SIDE_LEFT) > size.width; for (int i = 0; i < 2; i++) { // Check twice, as both values are dependent on each other. if (display_hscroll) { - display_vscroll = internal_min_size.height + theme_cache.bg->get_margin(SIDE_TOP) + hmin.height > size.height; + display_vscroll = internal_min_size.height + theme_cache.panel_style->get_margin(SIDE_TOP) + hmin.height > size.height; } if (display_vscroll) { - display_hscroll = internal_min_size.width + theme_cache.bg->get_margin(SIDE_LEFT) + vmin.width > size.width; + display_hscroll = internal_min_size.width + theme_cache.panel_style->get_margin(SIDE_LEFT) + vmin.width > size.width; } } @@ -3941,7 +3943,7 @@ void Tree::_notification(int p_what) { update_scrollbars(); RID ci = get_canvas_item(); - Ref<StyleBox> bg = theme_cache.bg; + Ref<StyleBox> bg = theme_cache.panel_style; Point2 draw_ofs; draw_ofs += bg->get_offset(); @@ -3965,7 +3967,7 @@ void Tree::_notification(int p_what) { if (show_column_titles) { //title buttons - int ofs2 = theme_cache.bg->get_margin(SIDE_LEFT); + int ofs2 = theme_cache.panel_style->get_margin(SIDE_LEFT); for (int i = 0; i < columns.size(); i++) { Ref<StyleBox> sb = (cache.click_type == Cache::CLICK_TITLE && cache.click_index == i) ? theme_cache.title_button_pressed : ((cache.hover_type == Cache::CLICK_TITLE && cache.hover_index == i) ? theme_cache.title_button_hover : theme_cache.title_button); Ref<Font> f = theme_cache.tb_font; @@ -3987,11 +3989,11 @@ void Tree::_notification(int p_what) { } } - // Draw the background focus outline last, so that it is drawn in front of the section headings. + // Draw the focus outline last, so that it is drawn in front of the section headings. // Otherwise, section heading backgrounds can appear to be in front of the focus outline when scrolling. if (has_focus()) { RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, true); - theme_cache.bg_focus->draw(ci, Rect2(Point2(), get_size())); + theme_cache.focus_style->draw(ci, Rect2(Point2(), get_size())); RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, false); } } break; @@ -4033,7 +4035,7 @@ Size2 Tree::get_minimum_size() const { return Size2(); } else { Vector2 min_size = get_internal_min_size(); - Ref<StyleBox> bg = theme_cache.bg; + Ref<StyleBox> bg = theme_cache.panel_style; if (bg.is_valid()) { min_size.x += bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT); min_size.y += bg->get_margin(SIDE_TOP) + bg->get_margin(SIDE_BOTTOM); @@ -4329,7 +4331,7 @@ int Tree::get_column_minimum_width(int p_column) const { // Check if the visible title of the column is wider. if (show_column_titles) { - min_width = MAX(theme_cache.font->get_string_size(columns[p_column].title, HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width + theme_cache.bg->get_margin(SIDE_LEFT) + theme_cache.bg->get_margin(SIDE_RIGHT), min_width); + min_width = MAX(theme_cache.font->get_string_size(columns[p_column].title, HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width + theme_cache.panel_style->get_margin(SIDE_LEFT) + theme_cache.panel_style->get_margin(SIDE_RIGHT), min_width); } if (!columns[p_column].clip_content) { @@ -4374,7 +4376,7 @@ int Tree::get_column_width(int p_column) const { if (columns[p_column].expand) { int expand_area = get_size().width; - Ref<StyleBox> bg = theme_cache.bg; + Ref<StyleBox> bg = theme_cache.panel_style; if (bg.is_valid()) { expand_area -= bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT); @@ -4482,7 +4484,7 @@ void Tree::ensure_cursor_is_visible() { return; // Nothing under cursor. } - const Size2 area_size = get_size() - theme_cache.bg->get_minimum_size(); + const Size2 area_size = get_size() - theme_cache.panel_style->get_minimum_size(); int y_offset = get_item_offset(selected_item); if (y_offset != -1) { @@ -4831,7 +4833,7 @@ int Tree::get_column_at_position(const Point2 &p_pos) const { if (is_layout_rtl()) { pos.x = get_size().width - pos.x; } - pos -= theme_cache.bg->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return -1; @@ -4861,7 +4863,7 @@ int Tree::get_drop_section_at_position(const Point2 &p_pos) const { if (is_layout_rtl()) { pos.x = get_size().width - pos.x; } - pos -= theme_cache.bg->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return -100; @@ -4891,7 +4893,7 @@ TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const { if (is_layout_rtl()) { pos.x = get_size().width - pos.x; } - pos -= theme_cache.bg->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return nullptr; @@ -4918,7 +4920,7 @@ TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const { int Tree::get_button_id_at_position(const Point2 &p_pos) const { if (root) { Point2 pos = p_pos; - pos -= theme_cache.bg->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return -1; @@ -4959,7 +4961,7 @@ int Tree::get_button_id_at_position(const Point2 &p_pos) const { String Tree::get_tooltip(const Point2 &p_pos) const { if (root) { Point2 pos = p_pos; - pos -= theme_cache.bg->get_offset(); + pos -= theme_cache.panel_style->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return Control::get_tooltip(p_pos); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index b4ee686bab..450943c048 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -483,12 +483,14 @@ private: void propagate_set_columns(TreeItem *p_item); struct ThemeCache { + Ref<StyleBox> panel_style; + Ref<StyleBox> focus_style; + Ref<Font> font; Ref<Font> tb_font; int font_size = 0; int tb_font_size = 0; - Ref<StyleBox> bg; - Ref<StyleBox> bg_focus; + Ref<StyleBox> selected; Ref<StyleBox> selected_focus; Ref<StyleBox> cursor; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 61a7600664..05d86f77f2 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -338,6 +338,7 @@ void CanvasItem::_notification(int p_what) { } if (window) { window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window = nullptr; } global_invalid = true; parent_visible_in_tree = false; @@ -368,6 +369,13 @@ void CanvasItem::queue_redraw() { MessageQueue::get_singleton()->push_callable(callable_mp(this, &CanvasItem::_redraw_callback)); } +void CanvasItem::move_to_front() { + if (!get_parent()) { + return; + } + get_parent()->move_child(this, -1); +} + void CanvasItem::set_modulate(const Color &p_modulate) { if (modulate == p_modulate) { return; @@ -896,6 +904,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("hide"), &CanvasItem::hide); ClassDB::bind_method(D_METHOD("queue_redraw"), &CanvasItem::queue_redraw); + ClassDB::bind_method(D_METHOD("move_to_front"), &CanvasItem::move_to_front); ClassDB::bind_method(D_METHOD("set_as_top_level", "enable"), &CanvasItem::set_as_top_level); ClassDB::bind_method(D_METHOD("is_set_as_top_level"), &CanvasItem::is_set_as_top_level); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 1abb4edec9..b80289fdb4 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -198,6 +198,7 @@ public: void hide(); void queue_redraw(); + void move_to_front(); void set_clip_children(bool p_enabled); bool is_clipping_children() const; diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 4890db995a..214efe432b 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -329,14 +329,14 @@ void CanvasLayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_less,or_greater,radians"), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale", PROPERTY_HINT_LINK), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "suffix:px"), "set_transform", "get_transform"); ADD_GROUP("", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", PROPERTY_USAGE_NONE), "set_custom_viewport", "get_custom_viewport"); ADD_GROUP("Follow Viewport", "follow_viewport"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport_enabled"), "set_follow_viewport", "is_following_viewport"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_less"), "set_follow_viewport_scale", "get_follow_viewport_scale"); ADD_SIGNAL(MethodInfo("visibility_changed")); } diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 9a23bc65bf..bec378dd91 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -36,11 +36,11 @@ void HTTPRequest::_redirect_request(const String &p_new_url) { } Error HTTPRequest::_request() { - return client->connect_to_host(url, port, use_ssl, validate_ssl); + return client->connect_to_host(url, port, use_tls, validate_tls); } Error HTTPRequest::_parse_url(const String &p_url) { - use_ssl = false; + use_tls = false; request_string = ""; port = 80; request_sent = false; @@ -54,12 +54,12 @@ Error HTTPRequest::_parse_url(const String &p_url) { Error err = p_url.parse_url(scheme, url, port, request_string); ERR_FAIL_COND_V_MSG(err != OK, err, "Error parsing URL: " + p_url + "."); if (scheme == "https://") { - use_ssl = true; + use_tls = true; } else if (scheme != "http://") { ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Invalid URL scheme: " + scheme + "."); } if (port == 0) { - port = use_ssl ? 443 : 80; + port = use_tls ? 443 : 80; } if (request_string.is_empty()) { request_string = "/"; @@ -98,7 +98,7 @@ String HTTPRequest::get_header_value(const PackedStringArray &p_headers, const S return value; } -Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const String &p_request_data) { +Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_headers, bool p_tls_validate_domain, HTTPClient::Method p_method, const String &p_request_data) { // Copy the string into a raw buffer. Vector<uint8_t> raw_data; @@ -110,10 +110,10 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h memcpy(w, charstr.ptr(), len); } - return request_raw(p_url, p_custom_headers, p_ssl_validate_domain, p_method, raw_data); + return request_raw(p_url, p_custom_headers, p_tls_validate_domain, p_method, raw_data); } -Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const Vector<uint8_t> &p_request_data_raw) { +Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_custom_headers, bool p_tls_validate_domain, HTTPClient::Method p_method, const Vector<uint8_t> &p_request_data_raw) { ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED); ERR_FAIL_COND_V_MSG(requesting, ERR_BUSY, "HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one."); @@ -129,7 +129,7 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_cust return err; } - validate_ssl = p_ssl_validate_domain; + validate_tls = p_tls_validate_domain; headers = p_custom_headers; @@ -413,8 +413,8 @@ bool HTTPRequest::_update_connection() { call_deferred(SNAME("_request_done"), RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray()); return true; } break; - case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: { - call_deferred(SNAME("_request_done"), RESULT_SSL_HANDSHAKE_ERROR, 0, PackedStringArray(), PackedByteArray()); + case HTTPClient::STATUS_TLS_HANDSHAKE_ERROR: { + call_deferred(SNAME("_request_done"), RESULT_TLS_HANDSHAKE_ERROR, 0, PackedStringArray(), PackedByteArray()); return true; } break; } @@ -570,8 +570,8 @@ void HTTPRequest::_timeout() { } void HTTPRequest::_bind_methods() { - ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String())); - ClassDB::bind_method(D_METHOD("request_raw", "url", "custom_headers", "ssl_validate_domain", "method", "request_data_raw"), &HTTPRequest::request_raw, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(PackedByteArray())); + ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "tls_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String())); + ClassDB::bind_method(D_METHOD("request_raw", "url", "custom_headers", "tls_validate_domain", "method", "request_data_raw"), &HTTPRequest::request_raw, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(PackedByteArray())); ClassDB::bind_method(D_METHOD("cancel_request"), &HTTPRequest::cancel_request); ClassDB::bind_method(D_METHOD("get_http_client_status"), &HTTPRequest::get_http_client_status); @@ -621,7 +621,7 @@ void HTTPRequest::_bind_methods() { BIND_ENUM_CONSTANT(RESULT_CANT_CONNECT); BIND_ENUM_CONSTANT(RESULT_CANT_RESOLVE); BIND_ENUM_CONSTANT(RESULT_CONNECTION_ERROR); - BIND_ENUM_CONSTANT(RESULT_SSL_HANDSHAKE_ERROR); + BIND_ENUM_CONSTANT(RESULT_TLS_HANDSHAKE_ERROR); BIND_ENUM_CONSTANT(RESULT_NO_RESPONSE); BIND_ENUM_CONSTANT(RESULT_BODY_SIZE_LIMIT_EXCEEDED); BIND_ENUM_CONSTANT(RESULT_BODY_DECOMPRESS_FAILED); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 4b32188377..290bacd9d2 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -48,7 +48,7 @@ public: RESULT_CANT_CONNECT, RESULT_CANT_RESOLVE, RESULT_CONNECTION_ERROR, - RESULT_SSL_HANDSHAKE_ERROR, + RESULT_TLS_HANDSHAKE_ERROR, RESULT_NO_RESPONSE, RESULT_BODY_SIZE_LIMIT_EXCEEDED, RESULT_BODY_DECOMPRESS_FAILED, @@ -67,8 +67,8 @@ private: String url; int port = 80; Vector<String> headers; - bool validate_ssl = false; - bool use_ssl = false; + bool validate_tls = false; + bool use_tls = false; HTTPClient::Method method; Vector<uint8_t> request_data; @@ -121,8 +121,8 @@ protected: static void _bind_methods(); public: - Error request(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_ssl_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const String &p_request_data = ""); //connects to a full url and perform request - Error request_raw(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_ssl_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const Vector<uint8_t> &p_request_data_raw = Vector<uint8_t>()); //connects to a full url and perform request + Error request(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_tls_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const String &p_request_data = ""); //connects to a full url and perform request + Error request_raw(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_tls_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const Vector<uint8_t> &p_request_data_raw = Vector<uint8_t>()); //connects to a full url and perform request void cancel_request(); HTTPClient::Status get_http_client_status() const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 289e963077..29f4d4fb1c 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -328,12 +328,21 @@ void Node::move_child(Node *p_child, int p_pos) { // We need to check whether node is internal and move it only in the relevant node range. if (p_child->_is_internal_front()) { + if (p_pos < 0) { + p_pos += data.internal_children_front; + } ERR_FAIL_INDEX_MSG(p_pos, data.internal_children_front, vformat("Invalid new child position: %d. Child is internal.", p_pos)); _move_child(p_child, p_pos); } else if (p_child->_is_internal_back()) { + if (p_pos < 0) { + p_pos += data.internal_children_back; + } ERR_FAIL_INDEX_MSG(p_pos, data.internal_children_back, vformat("Invalid new child position: %d. Child is internal.", p_pos)); _move_child(p_child, data.children.size() - data.internal_children_back + p_pos); } else { + if (p_pos < 0) { + p_pos += get_child_count(false); + } ERR_FAIL_INDEX_MSG(p_pos, data.children.size() + 1 - data.internal_children_front - data.internal_children_back, vformat("Invalid new child position: %d.", p_pos)); _move_child(p_child, p_pos + data.internal_children_front); } @@ -389,21 +398,6 @@ void Node::_move_child(Node *p_child, int p_pos, bool p_ignore_end) { data.blocked--; } -void Node::raise() { - if (!data.parent) { - return; - } - - // Internal children move within a different index range. - if (_is_internal_front()) { - data.parent->move_child(this, data.parent->data.internal_children_front - 1); - } else if (_is_internal_back()) { - data.parent->move_child(this, data.parent->data.internal_children_back - 1); - } else { - data.parent->move_child(this, data.parent->get_child_count(false) - 1); - } -} - void Node::_propagate_groups_dirty() { for (const KeyValue<StringName, GroupData> &E : data.grouped) { if (E.value.group) { @@ -1131,7 +1125,7 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name) { add_child_notify(p_child); } -void Node::add_child(Node *p_child, bool p_legible_unique_name, InternalMode p_internal) { +void Node::add_child(Node *p_child, bool p_force_readable_name, InternalMode p_internal) { ERR_FAIL_NULL(p_child); ERR_FAIL_COND_MSG(p_child == this, vformat("Can't add child '%s' to itself.", p_child->get_name())); // adding to itself! ERR_FAIL_COND_MSG(p_child->data.parent, vformat("Can't add child '%s' to '%s', already has a parent '%s'.", p_child->get_name(), get_name(), p_child->data.parent->get_name())); //Fail if node has a parent @@ -1140,7 +1134,7 @@ void Node::add_child(Node *p_child, bool p_legible_unique_name, InternalMode p_i #endif ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, add_node() failed. Consider using call_deferred(\"add_child\", child) instead."); - _validate_child_name(p_child, p_legible_unique_name); + _validate_child_name(p_child, p_force_readable_name); _add_child_nocheck(p_child, p_child->data.name); if (p_internal == INTERNAL_MODE_FRONT) { @@ -1154,7 +1148,7 @@ void Node::add_child(Node *p_child, bool p_legible_unique_name, InternalMode p_i } } -void Node::add_sibling(Node *p_sibling, bool p_legible_unique_name) { +void Node::add_sibling(Node *p_sibling, bool p_force_readable_name) { ERR_FAIL_NULL(p_sibling); ERR_FAIL_NULL(data.parent); ERR_FAIL_COND_MSG(p_sibling == this, vformat("Can't add sibling '%s' to itself.", p_sibling->get_name())); // adding to itself! @@ -1167,7 +1161,7 @@ void Node::add_sibling(Node *p_sibling, bool p_legible_unique_name) { internal = INTERNAL_MODE_BACK; } - data.parent->add_child(p_sibling, p_legible_unique_name, internal); + data.parent->add_child(p_sibling, p_force_readable_name, internal); data.parent->_move_child(p_sibling, get_index() + 1); } @@ -1922,43 +1916,6 @@ Ref<Tween> Node::create_tween() { return tween; } -void Node::remove_and_skip() { - ERR_FAIL_COND(!data.parent); - - Node *new_owner = get_owner(); - - List<Node *> children; - - while (true) { - bool clear = true; - for (int i = 0; i < data.children.size(); i++) { - Node *c_node = data.children[i]; - if (!c_node->get_owner()) { - continue; - } - - remove_child(c_node); - c_node->_propagate_replace_owner(this, nullptr); - children.push_back(c_node); - clear = false; - break; - } - - if (clear) { - break; - } - } - - while (!children.is_empty()) { - Node *c_node = children.front()->get(); - data.parent->add_child(c_node); - c_node->_propagate_replace_owner(nullptr, new_owner); - children.pop_front(); - } - - data.parent->remove_child(this); -} - void Node::set_scene_file_path(const String &p_scene_file_path) { data.scene_file_path = p_scene_file_path; } @@ -2787,11 +2744,11 @@ void Node::_bind_methods() { GLOBAL_DEF("editor/node_naming/name_casing", NAME_CASING_PASCAL_CASE); ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_casing", PropertyInfo(Variant::INT, "editor/node_naming/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); - ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "legible_unique_name"), &Node::add_sibling, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "force_readable_name"), &Node::add_sibling, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_name", "name"), &Node::set_name); ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name); - ClassDB::bind_method(D_METHOD("add_child", "node", "legible_unique_name", "internal"), &Node::add_child, DEFVAL(false), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_child", "node", "force_readable_name", "internal"), &Node::add_child, DEFVAL(false), DEFVAL(0)); ClassDB::bind_method(D_METHOD("remove_child", "node"), &Node::remove_child); ClassDB::bind_method(D_METHOD("get_child_count", "include_internal"), &Node::get_child_count, DEFVAL(false)); // Note that the default value bound for include_internal is false, while the method is declared with true. This is because internal nodes are irrelevant for GDSCript. ClassDB::bind_method(D_METHOD("get_children", "include_internal"), &Node::_get_children, DEFVAL(false)); @@ -2816,10 +2773,8 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("is_in_group", "group"), &Node::is_in_group); ClassDB::bind_method(D_METHOD("move_child", "child_node", "to_position"), &Node::move_child); ClassDB::bind_method(D_METHOD("get_groups"), &Node::_get_groups); - ClassDB::bind_method(D_METHOD("raise"), &Node::raise); ClassDB::bind_method(D_METHOD("set_owner", "owner"), &Node::set_owner); ClassDB::bind_method(D_METHOD("get_owner"), &Node::get_owner); - ClassDB::bind_method(D_METHOD("remove_and_skip"), &Node::remove_and_skip); ClassDB::bind_method(D_METHOD("get_index", "include_internal"), &Node::get_index, DEFVAL(false)); ClassDB::bind_method(D_METHOD("print_tree"), &Node::print_tree); ClassDB::bind_method(D_METHOD("print_tree_pretty"), &Node::print_tree_pretty); diff --git a/scene/main/node.h b/scene/main/node.h index ae6a997579..39225b1358 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -303,8 +303,8 @@ public: StringName get_name() const; void set_name(const String &p_name); - void add_child(Node *p_child, bool p_legible_unique_name = false, InternalMode p_internal = INTERNAL_MODE_DISABLED); - void add_sibling(Node *p_sibling, bool p_legible_unique_name = false); + void add_child(Node *p_child, bool p_force_readable_name = false, InternalMode p_internal = INTERNAL_MODE_DISABLED); + void add_sibling(Node *p_sibling, bool p_force_readable_name = false); void remove_child(Node *p_child); int get_child_count(bool p_include_internal = true) const; @@ -348,7 +348,6 @@ public: void move_child(Node *p_child, int p_pos); void _move_child(Node *p_child, int p_pos, bool p_ignore_end = false); - void raise(); void set_owner(Node *p_owner); Node *get_owner() const; @@ -357,7 +356,6 @@ public: void set_unique_name_in_owner(bool p_enabled); bool is_unique_name_in_owner() const; - void remove_and_skip(); int get_index(bool p_include_internal = true) const; Ref<Tween> create_tween(); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 268b381029..c18aa5aaa2 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -88,6 +88,14 @@ bool SceneTreeTimer::is_process_always() { return process_always; } +void SceneTreeTimer::set_process_in_physics(bool p_process_in_physics) { + process_in_physics = p_process_in_physics; +} + +bool SceneTreeTimer::is_process_in_physics() { + return process_in_physics; +} + void SceneTreeTimer::set_ignore_time_scale(bool p_ignore) { ignore_time_scale = p_ignore; } @@ -420,6 +428,8 @@ bool SceneTree::physics_process(double p_time) { _flush_ugc(); MessageQueue::get_singleton()->flush(); //small little hack + process_timers(p_time, true); //go through timers + process_tweens(p_time, true); flush_transform_notifications(); @@ -462,37 +472,7 @@ bool SceneTree::process(double p_time) { _flush_delete_queue(); - //go through timers - - List<Ref<SceneTreeTimer>>::Element *L = timers.back(); //last element - - for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) { - List<Ref<SceneTreeTimer>>::Element *N = E->next(); - if (paused && !E->get()->is_process_always()) { - if (E == L) { - break; //break on last, so if new timers were added during list traversal, ignore them. - } - E = N; - continue; - } - - double time_left = E->get()->get_time_left(); - if (E->get()->is_ignore_time_scale()) { - time_left -= Engine::get_singleton()->get_process_step(); - } else { - time_left -= p_time; - } - E->get()->set_time_left(time_left); - - if (time_left <= 0) { - E->get()->emit_signal(SNAME("timeout")); - timers.erase(E); - } - if (E == L) { - break; //break on last, so if new timers were added during list traversal, ignore them. - } - E = N; - } + process_timers(p_time, false); //go through timers process_tweens(p_time, false); @@ -530,6 +510,38 @@ bool SceneTree::process(double p_time) { return _quit; } +void SceneTree::process_timers(float p_delta, bool p_physics_frame) { + List<Ref<SceneTreeTimer>>::Element *L = timers.back(); //last element + + for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) { + List<Ref<SceneTreeTimer>>::Element *N = E->next(); + if ((paused && !E->get()->is_process_always()) || (E->get()->is_process_in_physics() != p_physics_frame)) { + if (E == L) { + break; //break on last, so if new timers were added during list traversal, ignore them. + } + E = N; + continue; + } + + double time_left = E->get()->get_time_left(); + if (E->get()->is_ignore_time_scale()) { + time_left -= Engine::get_singleton()->get_process_step(); + } else { + time_left -= p_delta; + } + E->get()->set_time_left(time_left); + + if (time_left <= 0) { + E->get()->emit_signal(SNAME("timeout")); + timers.erase(E); + } + if (E == L) { + break; //break on last, so if new timers were added during list traversal, ignore them. + } + E = N; + } +} + void SceneTree::process_tweens(float p_delta, bool p_physics) { // This methods works similarly to how SceneTreeTimers are handled. List<Ref<Tween>>::Element *L = tweens.back(); @@ -710,22 +722,6 @@ float SceneTree::get_debug_paths_width() const { return debug_paths_width; } -void SceneTree::set_debug_navigation_color(const Color &p_color) { - debug_navigation_color = p_color; -} - -Color SceneTree::get_debug_navigation_color() const { - return debug_navigation_color; -} - -void SceneTree::set_debug_navigation_disabled_color(const Color &p_color) { - debug_navigation_disabled_color = p_color; -} - -Color SceneTree::get_debug_navigation_disabled_color() const { - return debug_navigation_disabled_color; -} - Ref<Material> SceneTree::get_debug_paths_material() { if (debug_paths_material.is_valid()) { return debug_paths_material; @@ -743,40 +739,6 @@ Ref<Material> SceneTree::get_debug_paths_material() { return debug_paths_material; } -Ref<Material> SceneTree::get_debug_navigation_material() { - if (navigation_material.is_valid()) { - return navigation_material; - } - - Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - line_material->set_albedo(get_debug_navigation_color()); - - navigation_material = line_material; - - return navigation_material; -} - -Ref<Material> SceneTree::get_debug_navigation_disabled_material() { - if (navigation_disabled_material.is_valid()) { - return navigation_disabled_material; - } - - Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - line_material->set_albedo(get_debug_navigation_disabled_color()); - - navigation_disabled_material = line_material; - - return navigation_disabled_material; -} - Ref<Material> SceneTree::get_debug_collision_material() { if (collision_material.is_valid()) { return collision_material; @@ -1126,16 +1088,16 @@ void SceneTree::_change_scene(Node *p_to) { } } -Error SceneTree::change_scene(const String &p_path) { +Error SceneTree::change_scene_to_file(const String &p_path) { Ref<PackedScene> new_scene = ResourceLoader::load(p_path); if (new_scene.is_null()) { return ERR_CANT_OPEN; } - return change_scene_to(new_scene); + return change_scene_to_packed(new_scene); } -Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) { +Error SceneTree::change_scene_to_packed(const Ref<PackedScene> &p_scene) { Node *new_scene = nullptr; if (p_scene.is_valid()) { new_scene = p_scene->instantiate(); @@ -1149,7 +1111,7 @@ Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) { Error SceneTree::reload_current_scene() { ERR_FAIL_COND_V(!current_scene, ERR_UNCONFIGURED); String fname = current_scene->get_scene_file_path(); - return change_scene(fname); + return change_scene_to_file(fname); } void SceneTree::add_current_scene(Node *p_current) { @@ -1157,11 +1119,13 @@ void SceneTree::add_current_scene(Node *p_current) { root->add_child(p_current); } -Ref<SceneTreeTimer> SceneTree::create_timer(double p_delay_sec, bool p_process_always) { +Ref<SceneTreeTimer> SceneTree::create_timer(double p_delay_sec, bool p_process_always, bool p_process_in_physics, bool p_ignore_time_scale) { Ref<SceneTreeTimer> stt; stt.instantiate(); stt->set_process_always(p_process_always); stt->set_time_left(p_delay_sec); + stt->set_process_in_physics(p_process_in_physics); + stt->set_ignore_time_scale(p_ignore_time_scale); timers.push_back(stt); return stt; } @@ -1259,7 +1223,7 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pause", "enable"), &SceneTree::set_pause); ClassDB::bind_method(D_METHOD("is_paused"), &SceneTree::is_paused); - ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "process_always"), &SceneTree::create_timer, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "process_always", "process_in_physics", "ignore_time_scale"), &SceneTree::create_timer, DEFVAL(true), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("create_tween"), &SceneTree::create_tween); ClassDB::bind_method(D_METHOD("get_processed_tweens"), &SceneTree::get_processed_tweens); @@ -1296,8 +1260,8 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_current_scene", "child_node"), &SceneTree::set_current_scene); ClassDB::bind_method(D_METHOD("get_current_scene"), &SceneTree::get_current_scene); - ClassDB::bind_method(D_METHOD("change_scene", "path"), &SceneTree::change_scene); - ClassDB::bind_method(D_METHOD("change_scene_to", "packed_scene"), &SceneTree::change_scene_to); + ClassDB::bind_method(D_METHOD("change_scene_to_file", "path"), &SceneTree::change_scene_to_file); + ClassDB::bind_method(D_METHOD("change_scene_to_packed", "packed_scene"), &SceneTree::change_scene_to_packed); ClassDB::bind_method(D_METHOD("reload_current_scene"), &SceneTree::reload_current_scene); @@ -1352,7 +1316,7 @@ void SceneTree::add_idle_callback(IdleCallback p_callback) { } void SceneTree::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { - if (p_function == "change_scene") { + if (p_function == "change_scene_to_file") { Ref<DirAccess> dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); List<String> directories; directories.push_back(dir_access->get_current_dir()); @@ -1390,8 +1354,6 @@ SceneTree::SceneTree() { debug_collision_contact_color = GLOBAL_DEF("debug/shapes/collision/contact_color", Color(1.0, 0.2, 0.1, 0.8)); debug_paths_color = GLOBAL_DEF("debug/shapes/paths/geometry_color", Color(0.1, 1.0, 0.7, 0.4)); debug_paths_width = GLOBAL_DEF("debug/shapes/paths/geometry_width", 2.0); - debug_navigation_color = GLOBAL_DEF("debug/shapes/navigation/geometry_color", Color(0.1, 1.0, 0.7, 0.4)); - debug_navigation_disabled_color = GLOBAL_DEF("debug/shapes/navigation/disabled_geometry_color", Color(1.0, 0.7, 0.1, 0.4)); collision_debug_contacts = GLOBAL_DEF("debug/shapes/collision/max_contacts_displayed", 10000); ProjectSettings::get_singleton()->set_custom_property_info("debug/shapes/collision/max_contacts_displayed", PropertyInfo(Variant::INT, "debug/shapes/collision/max_contacts_displayed", PROPERTY_HINT_RANGE, "0,20000,1")); // No negative diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index e66363ab33..031a331a99 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -53,6 +53,7 @@ class SceneTreeTimer : public RefCounted { double time_left = 0.0; bool process_always = true; + bool process_in_physics = false; bool ignore_time_scale = false; protected: @@ -65,6 +66,9 @@ public: void set_process_always(bool p_process_always); bool is_process_always(); + void set_process_in_physics(bool p_process_in_physics); + bool is_process_in_physics(); + void set_ignore_time_scale(bool p_ignore); bool is_ignore_time_scale(); @@ -176,6 +180,7 @@ private: void node_added(Node *p_node); void node_removed(Node *p_node); void node_renamed(Node *p_node); + void process_timers(float p_delta, bool p_physics_frame); void process_tweens(float p_delta, bool p_physics_frame); Group *add_to_group(const StringName &p_group, Node *p_node); @@ -329,15 +334,7 @@ public: void set_debug_paths_width(float p_width); float get_debug_paths_width() const; - void set_debug_navigation_color(const Color &p_color); - Color get_debug_navigation_color() const; - - void set_debug_navigation_disabled_color(const Color &p_color); - Color get_debug_navigation_disabled_color() const; - Ref<Material> get_debug_paths_material(); - Ref<Material> get_debug_navigation_material(); - Ref<Material> get_debug_navigation_disabled_material(); Ref<Material> get_debug_collision_material(); Ref<ArrayMesh> get_debug_contact_mesh(); @@ -361,11 +358,11 @@ public: void set_current_scene(Node *p_scene); Node *get_current_scene() const; - Error change_scene(const String &p_path); - Error change_scene_to(const Ref<PackedScene> &p_scene); + Error change_scene_to_file(const String &p_path); + Error change_scene_to_packed(const Ref<PackedScene> &p_scene); Error reload_current_scene(); - Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true); + Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true, bool p_process_in_physics = false, bool p_ignore_time_scale = false); Ref<Tween> create_tween(); TypedArray<Tween> get_processed_tweens(); diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index a621aea9c8..13034c5447 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -64,9 +64,9 @@ bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_valu if (active) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = p_value; - RS::get_singleton()->global_shader_uniform_set_override(*r, tex_rid); + RS::get_singleton()->global_shader_parameter_set_override(*r, tex_rid); } else { - RS::get_singleton()->global_shader_uniform_set_override(*r, p_value); + RS::get_singleton()->global_shader_parameter_set_override(*r, p_value); } } o->in_use = p_value.get_type() != Variant::NIL; @@ -93,13 +93,13 @@ bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const { Vector<StringName> variables; - variables = RS::get_singleton()->global_shader_uniform_get_list(); + variables = RS::get_singleton()->global_shader_parameter_get_list(); for (int i = 0; i < variables.size(); i++) { PropertyInfo pinfo; pinfo.name = "params/" + variables[i]; pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - switch (RS::get_singleton()->global_shader_uniform_get_type(variables[i])) { + switch (RS::get_singleton()->global_shader_parameter_get_type(variables[i])) { case RS::GLOBAL_VAR_TYPE_BOOL: { pinfo.type = Variant::BOOL; } break; @@ -234,9 +234,9 @@ void ShaderGlobalsOverride::_activate() { if (o->in_use && o->override.get_type() != Variant::NIL) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = o->override; - RS::get_singleton()->global_shader_uniform_set_override(E.key, tex_rid); + RS::get_singleton()->global_shader_parameter_set_override(E.key, tex_rid); } else { - RS::get_singleton()->global_shader_uniform_set_override(E.key, o->override); + RS::get_singleton()->global_shader_parameter_set_override(E.key, o->override); } } @@ -258,7 +258,7 @@ void ShaderGlobalsOverride::_notification(int p_what) { for (const KeyValue<StringName, Override> &E : overrides) { const Override *o = &E.value; if (o->in_use) { - RS::get_singleton()->global_shader_uniform_set_override(E.key, Variant()); + RS::get_singleton()->global_shader_parameter_set_override(E.key, Variant()); } } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1bb1faacdd..5295de5c09 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -805,6 +805,10 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override, update_canvas_items(); + for (ViewportTexture *E : viewport_textures) { + E->emit_changed(); + } + emit_signal(SNAME("size_changed")); } @@ -2099,7 +2103,7 @@ void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) { p_control->set_as_top_level(true); p_control->set_position(gui.last_mouse_pos); p_base->get_root_parent_control()->add_child(p_control); // Add as child of viewport. - p_control->raise(); + p_control->move_to_front(); gui.drag_preview_id = p_control->get_instance_id(); } diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 79a1c71064..04f56bb874 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -38,6 +38,7 @@ #include "scene/gui/control.h" #include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" +#include "scene/theme/theme_owner.h" void Window::set_title(const String &p_title) { title = p_title; @@ -804,6 +805,14 @@ void Window::_notification(int p_what) { _update_theme_item_cache(); } break; + case NOTIFICATION_PARENTED: { + theme_owner->assign_theme_on_parented(this); + } break; + + case NOTIFICATION_UNPARENTED: { + theme_owner->clear_theme_on_unparented(this); + } break; + case NOTIFICATION_ENTER_TREE: { bool embedded = false; { @@ -856,9 +865,7 @@ void Window::_notification(int p_what) { RS::get_singleton()->viewport_set_active(get_viewport_rid(), true); } - // Need to defer here, because theme owner information might be set in - // add_child_notify, which doesn't get called until right after this. - call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED); + notification(NOTIFICATION_THEME_CHANGED); } break; case NOTIFICATION_THEME_CHANGED: { @@ -1289,28 +1296,29 @@ Rect2i Window::get_usable_parent_rect() const { } void Window::add_child_notify(Node *p_child) { - // We propagate when this node uses a custom theme, so it can pass it on to its children. - if (theme_owner || theme_owner_window) { - // `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`. - Control::_propagate_theme_changed(this, theme_owner, theme_owner_window, false, true); - } - if (is_inside_tree() && wrap_controls) { child_controls_changed(); } } void Window::remove_child_notify(Node *p_child) { - // If the removed child isn't inheriting any theme items through this node, then there's no need to propagate. - if (theme_owner || theme_owner_window) { - Control::_propagate_theme_changed(this, nullptr, nullptr, false, true); - } - if (is_inside_tree() && wrap_controls) { child_controls_changed(); } } +void Window::set_theme_owner_node(Node *p_node) { + theme_owner->set_owner_node(p_node); +} + +Node *Window::get_theme_owner_node() const { + return theme_owner->get_owner_node(); +} + +bool Window::has_theme_owner_node() const { + return theme_owner->has_owner_node(); +} + void Window::set_theme(const Ref<Theme> &p_theme) { if (theme == p_theme) { return; @@ -1322,24 +1330,24 @@ void Window::set_theme(const Ref<Theme> &p_theme) { theme = p_theme; if (theme.is_valid()) { - Control::_propagate_theme_changed(this, nullptr, this, is_inside_tree(), true); + theme_owner->propagate_theme_changed(this, this, is_inside_tree(), true); theme->connect("changed", callable_mp(this, &Window::_theme_changed), CONNECT_DEFERRED); return; } Control *parent_c = Object::cast_to<Control>(get_parent()); - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window, is_inside_tree(), true); + if (parent_c && parent_c->has_theme_owner_node()) { + theme_owner->propagate_theme_changed(this, parent_c->get_theme_owner_node(), is_inside_tree(), true); return; } Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window, is_inside_tree(), true); + if (parent_w && parent_w->has_theme_owner_node()) { + theme_owner->propagate_theme_changed(this, parent_w->get_theme_owner_node(), is_inside_tree(), true); return; } - Control::_propagate_theme_changed(this, nullptr, nullptr, is_inside_tree(), true); + theme_owner->propagate_theme_changed(this, nullptr, is_inside_tree(), true); } Ref<Theme> Window::get_theme() const { @@ -1348,7 +1356,7 @@ Ref<Theme> Window::get_theme() const { void Window::_theme_changed() { if (is_inside_tree()) { - Control::_propagate_theme_changed(this, nullptr, this, true, false); + theme_owner->propagate_theme_changed(this, this, true, false); } } @@ -1375,26 +1383,14 @@ StringName Window::get_theme_type_variation() const { return theme_type_variation; } -void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) { - if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(theme_type_variation) != StringName()) { - ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); - } - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list); - } -} - Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { if (theme_icon_cache.has(p_theme_type) && theme_icon_cache[p_theme_type].has(p_name)) { return theme_icon_cache[p_theme_type][p_name]; } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<Texture2D> icon = Control::get_theme_item_in_types<Ref<Texture2D>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Texture2D> icon = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); theme_icon_cache[p_theme_type][p_name] = icon; return icon; } @@ -1405,8 +1401,8 @@ Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringN } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<StyleBox> style = Control::get_theme_item_in_types<Ref<StyleBox>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<StyleBox> style = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); theme_style_cache[p_theme_type][p_name] = style; return style; } @@ -1417,8 +1413,8 @@ Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_t } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<Font> font = Control::get_theme_item_in_types<Ref<Font>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Font> font = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); theme_font_cache[p_theme_type][p_name] = font; return font; } @@ -1429,8 +1425,8 @@ int Window::get_theme_font_size(const StringName &p_name, const StringName &p_th } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - int font_size = Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int font_size = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); theme_font_size_cache[p_theme_type][p_name] = font_size; return font_size; } @@ -1441,8 +1437,8 @@ Color Window::get_theme_color(const StringName &p_name, const StringName &p_them } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Color color = Control::get_theme_item_in_types<Color>(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Color color = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); theme_color_cache[p_theme_type][p_name] = color; return color; } @@ -1453,58 +1449,58 @@ int Window::get_theme_constant(const StringName &p_name, const StringName &p_the } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - int constant = Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int constant = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); theme_constant_cache[p_theme_type][p_name] = constant; return constant; } bool Window::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); } bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } bool Window::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); } bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } bool Window::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); } bool Window::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } float Window::get_theme_default_base_scale() const { - return Control::fetch_theme_default_base_scale(theme_owner, theme_owner_window); + return theme_owner->get_theme_default_base_scale(); } Ref<Font> Window::get_theme_default_font() const { - return Control::fetch_theme_default_font(theme_owner, theme_owner_window); + return theme_owner->get_theme_default_font(); } int Window::get_theme_default_font_size() const { - return Control::fetch_theme_default_font_size(theme_owner, theme_owner_window); + return theme_owner->get_theme_default_font_size(); } Rect2i Window::get_parent_rect() const { @@ -1834,8 +1830,10 @@ void Window::_bind_methods() { } Window::Window() { + theme_owner = memnew(ThemeOwner); RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED); } Window::~Window() { + memdelete(theme_owner); } diff --git a/scene/main/window.h b/scene/main/window.h index 5a42c5bb83..8113117103 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -38,6 +38,7 @@ class Control; class Font; class Shortcut; class StyleBox; +class ThemeOwner; class Window : public Viewport { GDCLASS(Window, Viewport) @@ -135,10 +136,8 @@ private: Window *exclusive_child = nullptr; HashSet<Window *> transient_children; - friend class Control; + ThemeOwner *theme_owner = nullptr; Ref<Theme> theme; - Control *theme_owner = nullptr; - Window *theme_owner_window = nullptr; StringName theme_type_variation; mutable HashMap<StringName, Theme::ThemeIconMap> theme_icon_cache; @@ -148,8 +147,6 @@ private: mutable HashMap<StringName, Theme::ThemeColorMap> theme_color_cache; mutable HashMap<StringName, Theme::ThemeConstantMap> theme_constant_cache; - _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; - void _theme_changed(); void _invalidate_theme_cache(); @@ -271,6 +268,10 @@ public: void popup_centered(const Size2i &p_minsize = Size2i()); void popup_centered_clamped(const Size2i &p_size = Size2i(), float p_fallback_ratio = 0.75); + void set_theme_owner_node(Node *p_node); + Node *get_theme_owner_node() const; + bool has_theme_owner_node() const; + void set_theme(const Ref<Theme> &p_theme); Ref<Theme> get_theme() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 6643fb8418..72c57f1bfc 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -380,14 +380,14 @@ void register_scene_types() { GDREGISTER_CLASS(VSeparator); GDREGISTER_CLASS(TextureButton); GDREGISTER_CLASS(Container); - GDREGISTER_ABSTRACT_CLASS(BoxContainer); + GDREGISTER_CLASS(BoxContainer); GDREGISTER_CLASS(HBoxContainer); GDREGISTER_CLASS(VBoxContainer); GDREGISTER_CLASS(GridContainer); GDREGISTER_CLASS(CenterContainer); GDREGISTER_CLASS(ScrollContainer); GDREGISTER_CLASS(PanelContainer); - GDREGISTER_ABSTRACT_CLASS(FlowContainer); + GDREGISTER_CLASS(FlowContainer); GDREGISTER_CLASS(HFlowContainer); GDREGISTER_CLASS(VFlowContainer); @@ -424,7 +424,7 @@ void register_scene_types() { GDREGISTER_CLASS(MarginContainer); GDREGISTER_CLASS(SubViewportContainer); - GDREGISTER_ABSTRACT_CLASS(SplitContainer); + GDREGISTER_CLASS(SplitContainer); GDREGISTER_CLASS(HSplitContainer); GDREGISTER_CLASS(VSplitContainer); @@ -642,21 +642,22 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeTexture2DArray); GDREGISTER_CLASS(VisualShaderNodeTexture3D); GDREGISTER_CLASS(VisualShaderNodeCubemap); - GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeUniform); - GDREGISTER_CLASS(VisualShaderNodeUniformRef); - GDREGISTER_CLASS(VisualShaderNodeFloatUniform); - GDREGISTER_CLASS(VisualShaderNodeIntUniform); - GDREGISTER_CLASS(VisualShaderNodeBooleanUniform); - GDREGISTER_CLASS(VisualShaderNodeColorUniform); - GDREGISTER_CLASS(VisualShaderNodeVec2Uniform); - GDREGISTER_CLASS(VisualShaderNodeVec3Uniform); - GDREGISTER_CLASS(VisualShaderNodeVec4Uniform); - GDREGISTER_CLASS(VisualShaderNodeTransformUniform); - GDREGISTER_CLASS(VisualShaderNodeTextureUniform); - GDREGISTER_CLASS(VisualShaderNodeTextureUniformTriplanar); - GDREGISTER_CLASS(VisualShaderNodeTexture2DArrayUniform); - GDREGISTER_CLASS(VisualShaderNodeTexture3DUniform); - GDREGISTER_CLASS(VisualShaderNodeCubemapUniform); + GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeParameter); + GDREGISTER_CLASS(VisualShaderNodeParameterRef); + GDREGISTER_CLASS(VisualShaderNodeFloatParameter); + GDREGISTER_CLASS(VisualShaderNodeIntParameter); + GDREGISTER_CLASS(VisualShaderNodeBooleanParameter); + GDREGISTER_CLASS(VisualShaderNodeColorParameter); + GDREGISTER_CLASS(VisualShaderNodeVec2Parameter); + GDREGISTER_CLASS(VisualShaderNodeVec3Parameter); + GDREGISTER_CLASS(VisualShaderNodeVec4Parameter); + GDREGISTER_CLASS(VisualShaderNodeTransformParameter); + GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeTextureParameter); + GDREGISTER_CLASS(VisualShaderNodeTexture2DParameter); + GDREGISTER_CLASS(VisualShaderNodeTextureParameterTriplanar); + GDREGISTER_CLASS(VisualShaderNodeTexture2DArrayParameter); + GDREGISTER_CLASS(VisualShaderNodeTexture3DParameter); + GDREGISTER_CLASS(VisualShaderNodeCubemapParameter); GDREGISTER_CLASS(VisualShaderNodeLinearSceneDepth); GDREGISTER_CLASS(VisualShaderNodeIf); GDREGISTER_CLASS(VisualShaderNodeSwitch); @@ -1088,10 +1089,12 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); ClassDB::add_compatibility_class("VisualServer", "RenderingServer"); + ClassDB::add_compatibility_class("World", "World3D"); + + // VisualShader classes. ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant"); ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); - ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("VisualShaderNodeScalarClamp", "VisualShaderNodeClamp"); ClassDB::add_compatibility_class("VisualShaderNodeVectorClamp", "VisualShaderNodeClamp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarInterp", "VisualShaderNodeMix"); @@ -1105,7 +1108,17 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarDerivativeFunc", "VisualShaderNodeDerivativeFunc"); ClassDB::add_compatibility_class("VisualShaderNodeVectorDerivativeFunc", "VisualShaderNodeDerivativeFunc"); - ClassDB::add_compatibility_class("World", "World3D"); + + ClassDB::add_compatibility_class("VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeColorUniform", "VisualShaderNodeColorParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeCubeMapUniform", "VisualShaderNodeCubeMapParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeTextureUniform", "VisualShaderNodeTexture2DParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeTextureUniformTriplanar", "VisualShaderNodeTextureParameterTriplanar"); + ClassDB::add_compatibility_class("VisualShaderNodeTransformUniform", "VisualShaderNodeTransformParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Parameter"); + ClassDB::add_compatibility_class("VisualShaderNodeUniform", "VisualShaderNodeParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeUniformRef", "VisualShaderNodeParameterRef"); // Renamed during 4.0 alpha, added to ease transition between alphas. ClassDB::add_compatibility_class("AudioStreamOGGVorbis", "AudioStreamOggVorbis"); @@ -1117,6 +1130,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("StreamTexture2DArray", "CompressedTexture2DArray"); ClassDB::add_compatibility_class("StreamTexture3D", "CompressedTexture3D"); ClassDB::add_compatibility_class("StreamTextureLayered", "CompressedTextureLayered"); + ClassDB::add_compatibility_class("VisualShaderNodeFloatUniform", "VisualShaderNodeFloatParameter"); #endif /* DISABLE_DEPRECATED */ OS::get_singleton()->yield(); // may take time to init diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 32c3c9fe9e..869d582935 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -51,10 +51,7 @@ static const int default_corner_radius = 3; static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = default_margin, float p_margin_top = default_margin, float p_margin_right = default_margin, float p_margin_bottom = default_margin, int p_corner_radius = default_corner_radius, bool p_draw_center = true, int p_border_width = 0) { Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); style->set_bg_color(p_color); - style->set_default_margin(SIDE_LEFT, p_margin_left * scale); - style->set_default_margin(SIDE_RIGHT, p_margin_right * scale); - style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * scale); - style->set_default_margin(SIDE_TOP, p_margin_top * scale); + style->set_default_margin_individual(p_margin_left * scale, p_margin_top * scale, p_margin_right * scale, p_margin_bottom * scale); style->set_corner_radius_all(p_corner_radius); style->set_anti_aliased(true); @@ -93,12 +90,7 @@ static Ref<ImageTexture> generate_icon(int p_index) { static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) { Ref<StyleBox> style(memnew(StyleBoxEmpty)); - - style->set_default_margin(SIDE_LEFT, p_margin_left * scale); - style->set_default_margin(SIDE_RIGHT, p_margin_right * scale); - style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * scale); - style->set_default_margin(SIDE_TOP, p_margin_top * scale); - + style->set_default_margin_individual(p_margin_left * scale, p_margin_top * scale, p_margin_right * scale, p_margin_bottom * scale); return style; } @@ -139,7 +131,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Panel theme->set_stylebox("panel", "Panel", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); - theme->set_stylebox("panel_fg", "Panel", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); // Button @@ -280,15 +271,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // CheckBox Ref<StyleBox> cbx_empty = memnew(StyleBoxEmpty); - cbx_empty->set_default_margin(SIDE_LEFT, 4 * scale); - cbx_empty->set_default_margin(SIDE_RIGHT, 4 * scale); - cbx_empty->set_default_margin(SIDE_TOP, 4 * scale); - cbx_empty->set_default_margin(SIDE_BOTTOM, 4 * scale); + cbx_empty->set_default_margin_all(4 * scale); Ref<StyleBox> cbx_focus = focus; - cbx_focus->set_default_margin(SIDE_LEFT, 4 * scale); - cbx_focus->set_default_margin(SIDE_RIGHT, 4 * scale); - cbx_focus->set_default_margin(SIDE_TOP, 4 * scale); - cbx_focus->set_default_margin(SIDE_BOTTOM, 4 * scale); + cbx_focus->set_default_margin_all(4 * scale); theme->set_stylebox("normal", "CheckBox", cbx_empty); theme->set_stylebox("pressed", "CheckBox", cbx_empty); @@ -318,16 +303,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_outline_color", "CheckBox", Color(1, 1, 1)); theme->set_constant("h_separation", "CheckBox", 4 * scale); - theme->set_constant("check_v_adjust", "CheckBox", 0 * scale); + theme->set_constant("check_v_offset", "CheckBox", 0 * scale); theme->set_constant("outline_size", "CheckBox", 0); // CheckButton Ref<StyleBox> cb_empty = memnew(StyleBoxEmpty); - cb_empty->set_default_margin(SIDE_LEFT, 6 * scale); - cb_empty->set_default_margin(SIDE_RIGHT, 6 * scale); - cb_empty->set_default_margin(SIDE_TOP, 4 * scale); - cb_empty->set_default_margin(SIDE_BOTTOM, 4 * scale); + cb_empty->set_default_margin_individual(6 * scale, 4 * scale, 6 * scale, 4 * scale); theme->set_stylebox("normal", "CheckButton", cb_empty); theme->set_stylebox("pressed", "CheckButton", cb_empty); @@ -336,15 +318,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("hover_pressed", "CheckButton", cb_empty); theme->set_stylebox("focus", "CheckButton", focus); - theme->set_icon("on", "CheckButton", icons["toggle_on"]); - theme->set_icon("on_disabled", "CheckButton", icons["toggle_on_disabled"]); - theme->set_icon("off", "CheckButton", icons["toggle_off"]); - theme->set_icon("off_disabled", "CheckButton", icons["toggle_off_disabled"]); + theme->set_icon("checked", "CheckButton", icons["toggle_on"]); + theme->set_icon("checked_disabled", "CheckButton", icons["toggle_on_disabled"]); + theme->set_icon("unchecked", "CheckButton", icons["toggle_off"]); + theme->set_icon("unchecked_disabled", "CheckButton", icons["toggle_off_disabled"]); - theme->set_icon("on_mirrored", "CheckButton", icons["toggle_on_mirrored"]); - theme->set_icon("on_disabled_mirrored", "CheckButton", icons["toggle_on_disabled_mirrored"]); - theme->set_icon("off_mirrored", "CheckButton", icons["toggle_off_mirrored"]); - theme->set_icon("off_disabled_mirrored", "CheckButton", icons["toggle_off_disabled_mirrored"]); + theme->set_icon("checked_mirrored", "CheckButton", icons["toggle_on_mirrored"]); + theme->set_icon("checked_disabled_mirrored", "CheckButton", icons["toggle_on_disabled_mirrored"]); + theme->set_icon("unchecked_mirrored", "CheckButton", icons["toggle_off_mirrored"]); + theme->set_icon("unchecked_disabled_mirrored", "CheckButton", icons["toggle_off_disabled_mirrored"]); theme->set_font("font", "CheckButton", Ref<Font>()); theme->set_font_size("font_size", "CheckButton", -1); @@ -358,7 +340,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_outline_color", "CheckButton", Color(1, 1, 1)); theme->set_constant("h_separation", "CheckButton", 4 * scale); - theme->set_constant("check_v_adjust", "CheckButton", 0 * scale); + theme->set_constant("check_v_offset", "CheckButton", 0 * scale); theme->set_constant("outline_size", "CheckButton", 0); // Label @@ -423,8 +405,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // ProgressBar - theme->set_stylebox("bg", "ProgressBar", make_flat_stylebox(style_disabled_color, 2, 2, 2, 2, 6)); - theme->set_stylebox("fg", "ProgressBar", make_flat_stylebox(style_progress_color, 2, 2, 2, 2, 6)); + theme->set_stylebox("background", "ProgressBar", make_flat_stylebox(style_disabled_color, 2, 2, 2, 2, 6)); + theme->set_stylebox("fill", "ProgressBar", make_flat_stylebox(style_progress_color, 2, 2, 2, 2, 6)); theme->set_font("font", "ProgressBar", Ref<Font>()); theme->set_font_size("font_size", "ProgressBar", -1); @@ -588,7 +570,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<StyleBoxEmpty> empty; empty.instantiate(); - theme->set_stylebox("bg", "ScrollContainer", empty); + theme->set_stylebox("panel", "ScrollContainer", empty); // Window @@ -610,9 +592,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Dialogs // AcceptDialog is currently the base dialog, so this defines styles for all extending nodes. - theme->set_constant("margin", "AcceptDialog", 8 * scale); - theme->set_constant("button_margin", "AcceptDialog", 32 * scale); - theme->set_stylebox("panel", "AcceptDialog", make_flat_stylebox(style_popup_color, 0, 0, 0, 0)); + theme->set_stylebox("panel", "AcceptDialog", make_flat_stylebox(style_popup_color, 8 * scale, 8 * scale, 8 * scale, 8 * scale)); + theme->set_constant("buttons_separation", "AcceptDialog", 10 * scale); // File Dialog @@ -623,9 +604,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("toggle_hidden", "FileDialog", icons["visibility_visible"]); theme->set_icon("folder", "FileDialog", icons["folder"]); theme->set_icon("file", "FileDialog", icons["file"]); - theme->set_color("folder_icon_modulate", "FileDialog", Color(1, 1, 1)); - theme->set_color("file_icon_modulate", "FileDialog", Color(1, 1, 1)); - theme->set_color("files_disabled", "FileDialog", Color(1, 1, 1, 0.25)); + theme->set_color("folder_icon_color", "FileDialog", Color(1, 1, 1)); + theme->set_color("file_icon_color", "FileDialog", Color(1, 1, 1)); + theme->set_color("file_disabled_color", "FileDialog", Color(1, 1, 1, 0.25)); // Popup @@ -640,16 +621,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<StyleBoxLine> separator_horizontal = memnew(StyleBoxLine); separator_horizontal->set_thickness(Math::round(scale)); separator_horizontal->set_color(style_separator_color); - separator_horizontal->set_default_margin(SIDE_LEFT, default_margin); - separator_horizontal->set_default_margin(SIDE_TOP, 0); - separator_horizontal->set_default_margin(SIDE_RIGHT, default_margin); - separator_horizontal->set_default_margin(SIDE_BOTTOM, 0); + separator_horizontal->set_default_margin_individual(default_margin, 0, default_margin, 0); Ref<StyleBoxLine> separator_vertical = separator_horizontal->duplicate(); separator_vertical->set_vertical(true); - separator_vertical->set_default_margin(SIDE_LEFT, 0); - separator_vertical->set_default_margin(SIDE_TOP, default_margin); - separator_vertical->set_default_margin(SIDE_RIGHT, 0); - separator_vertical->set_default_margin(SIDE_BOTTOM, default_margin); + separator_vertical->set_default_margin_individual(0, default_margin, 0, default_margin); // Always display a border for PopupMenus so they can be distinguished from their background. Ref<StyleBoxFlat> style_popup_panel = make_flat_stylebox(style_popup_color); @@ -737,8 +712,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Tree - theme->set_stylebox("bg", "Tree", make_flat_stylebox(style_normal_color, 4, 4, 4, 5)); - theme->set_stylebox("bg_focus", "Tree", focus); + theme->set_stylebox("panel", "Tree", make_flat_stylebox(style_normal_color, 4, 4, 4, 5)); + theme->set_stylebox("focus", "Tree", focus); theme->set_stylebox("selected", "Tree", make_flat_stylebox(style_selected_color)); theme->set_stylebox("selected_focus", "Tree", make_flat_stylebox(style_selected_color)); theme->set_stylebox("cursor", "Tree", focus); @@ -791,8 +766,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // ItemList - theme->set_stylebox("bg", "ItemList", make_flat_stylebox(style_normal_color)); - theme->set_stylebox("bg_focus", "ItemList", focus); + theme->set_stylebox("panel", "ItemList", make_flat_stylebox(style_normal_color)); + theme->set_stylebox("focus", "ItemList", focus); theme->set_constant("h_separation", "ItemList", 4); theme->set_constant("v_separation", "ItemList", 2); theme->set_constant("icon_margin", "ItemList", 4); @@ -996,9 +971,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Containers + theme->set_icon("h_grabber", "SplitContainer", icons["hsplitter"]); + theme->set_icon("v_grabber", "SplitContainer", icons["vsplitter"]); theme->set_icon("grabber", "VSplitContainer", icons["vsplitter"]); theme->set_icon("grabber", "HSplitContainer", icons["hsplitter"]); + theme->set_constant("separation", "BoxContainer", 4 * scale); theme->set_constant("separation", "HBoxContainer", 4 * scale); theme->set_constant("separation", "VBoxContainer", 4 * scale); theme->set_constant("margin_left", "MarginContainer", 0 * scale); @@ -1007,10 +985,17 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("margin_bottom", "MarginContainer", 0 * scale); theme->set_constant("h_separation", "GridContainer", 4 * scale); theme->set_constant("v_separation", "GridContainer", 4 * scale); + theme->set_constant("separation", "SplitContainer", 12 * scale); theme->set_constant("separation", "HSplitContainer", 12 * scale); theme->set_constant("separation", "VSplitContainer", 12 * scale); + theme->set_constant("minimum_grab_thickness", "SplitContainer", 6 * scale); + theme->set_constant("minimum_grab_thickness", "HSplitContainer", 6 * scale); + theme->set_constant("minimum_grab_thickness", "VSplitContainer", 6 * scale); + theme->set_constant("autohide", "SplitContainer", 1 * scale); theme->set_constant("autohide", "HSplitContainer", 1 * scale); theme->set_constant("autohide", "VSplitContainer", 1 * scale); + theme->set_constant("h_separation", "FlowContainer", 4 * scale); + theme->set_constant("v_separation", "FlowContainer", 4 * scale); theme->set_constant("h_separation", "HFlowContainer", 4 * scale); theme->set_constant("v_separation", "HFlowContainer", 4 * scale); theme->set_constant("h_separation", "VFlowContainer", 4 * scale); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 18df59a7aa..ebdaaaa95f 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1184,7 +1184,7 @@ void Environment::_bind_methods() { ADD_GROUP("Sky", "sky_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), "set_sky_custom_fov", "get_sky_custom_fov"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_sky_rotation", "get_sky_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_sky_rotation", "get_sky_rotation"); // Ambient light @@ -1420,8 +1420,8 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_fog_density", "get_fog_density"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_aerial_perspective", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_aerial_perspective", "get_fog_aerial_perspective"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sky_affect", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_sky_affect", "get_fog_sky_affect"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater,suffix:m"), "set_fog_height", "get_fog_height"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_lesser,or_greater"), "set_fog_height_density", "get_fog_height_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_less,or_greater,suffix:m"), "set_fog_height", "get_fog_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_less,or_greater"), "set_fog_height_density", "get_fog_height_density"); ClassDB::bind_method(D_METHOD("set_volumetric_fog_enabled", "enabled"), &Environment::set_volumetric_fog_enabled); ClassDB::bind_method(D_METHOD("is_volumetric_fog_enabled"), &Environment::is_volumetric_fog_enabled); diff --git a/scene/resources/fog_material.cpp b/scene/resources/fog_material.cpp index 39ade85af6..0395ed0346 100644 --- a/scene/resources/fog_material.cpp +++ b/scene/resources/fog_material.cpp @@ -122,7 +122,7 @@ void FogMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_density_texture", "density_texture"), &FogMaterial::set_density_texture); ClassDB::bind_method(D_METHOD("get_density_texture"), &FogMaterial::get_density_texture); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "density", PROPERTY_HINT_RANGE, "0.0,16.0,0.0001,or_greater,or_lesser"), "set_density", "get_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "density", PROPERTY_HINT_RANGE, "0.0,16.0,0.0001,or_greater,or_less"), "set_density", "get_density"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo", PROPERTY_HINT_COLOR_NO_ALPHA), "set_albedo", "get_albedo"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height_falloff", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_height_falloff", "get_height_falloff"); diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 3638d1862c..0afca95de0 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -154,7 +154,7 @@ Mesh::BlendShapeMode ImporterMesh::get_blend_shape_mode() const { return blend_shape_mode; } -void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name, const uint32_t p_flags) { +void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name, const uint32_t p_flags) { ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size()); ERR_FAIL_COND(p_arrays.size() != Mesh::ARRAY_MAX); Surface s; @@ -1230,7 +1230,7 @@ void ImporterMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ImporterMesh::set_blend_shape_mode); ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ImporterMesh::get_blend_shape_mode); - ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name", "flags"), &ImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name", "flags"), &ImporterMesh::add_surface, DEFVAL(TypedArray<Array>()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_surface_count"), &ImporterMesh::get_surface_count); ClassDB::bind_method(D_METHOD("get_surface_primitive_type", "surface_idx"), &ImporterMesh::get_surface_primitive_type); diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index bf1d0301d1..dce2638c19 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -93,7 +93,7 @@ public: int get_blend_shape_count() const; String get_blend_shape_name(int p_blend_shape) const; - void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String(), const uint32_t p_flags = 0); + void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String(), const uint32_t p_flags = 0); int get_surface_count() const; void set_blend_shape_mode(Mesh::BlendShapeMode p_blend_shape_mode); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 9a1b784ec4..448ff74a53 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -159,15 +159,16 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; - if (n.find("param/") == 0) { //backwards compatibility - pr = n.substr(6, n.length()); - } - if (n.find("shader_uniform/") == 0) { //backwards compatibility + if (n.find("shader_parameter/") == 0) { //backwards compatibility + pr = n.replace_first("shader_parameter/", ""); + } else if (n.find("shader_uniform/") == 0) { //backwards compatibility pr = n.replace_first("shader_uniform/", ""); + } else if (n.find("param/") == 0) { //backwards compatibility + pr = n.substr(6, n.length()); } } if (pr) { - set_shader_uniform(pr, p_value); + set_shader_parameter(pr, p_value); return true; } } @@ -180,11 +181,12 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; - if (n.find("param/") == 0) { //backwards compatibility - pr = n.substr(6, n.length()); - } - if (n.find("shader_uniform/") == 0) { //backwards compatibility + if (n.find("shader_parameter/") == 0) { //backwards compatibility + pr = n.replace_first("shader_parameter/", ""); + } else if (n.find("shader_uniform/") == 0) { //backwards compatibility pr = n.replace_first("shader_uniform/", ""); + } else if (n.find("param/") == 0) { //backwards compatibility + pr = n.substr(6, n.length()); } } @@ -303,7 +305,7 @@ bool ShaderMaterial::_property_can_revert(const StringName &p_name) const { if (shader.is_valid()) { StringName pr = shader->remap_uniform(p_name); if (pr) { - Variant default_value = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); + Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr); Variant current_value; _get(p_name, current_value); return default_value.get_type() != Variant::NIL && default_value != current_value; @@ -316,7 +318,7 @@ bool ShaderMaterial::_property_get_revert(const StringName &p_name, Variant &r_p if (shader.is_valid()) { StringName pr = shader->remap_uniform(p_name); if (pr) { - r_property = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); + r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr); return true; } } @@ -351,7 +353,7 @@ Ref<Shader> ShaderMaterial::get_shader() const { return shader; } -void ShaderMaterial::set_shader_uniform(const StringName &p_param, const Variant &p_value) { +void ShaderMaterial::set_shader_parameter(const StringName &p_param, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { param_cache.erase(p_param); RS::get_singleton()->material_set_param(_get_material(), p_param, Variant()); @@ -371,7 +373,7 @@ void ShaderMaterial::set_shader_uniform(const StringName &p_param, const Variant } } -Variant ShaderMaterial::get_shader_uniform(const StringName &p_param) const { +Variant ShaderMaterial::get_shader_parameter(const StringName &p_param) const { if (param_cache.has(p_param)) { return param_cache[p_param]; } else { @@ -386,20 +388,20 @@ void ShaderMaterial::_shader_changed() { void ShaderMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader); ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader); - ClassDB::bind_method(D_METHOD("set_shader_uniform", "param", "value"), &ShaderMaterial::set_shader_uniform); - ClassDB::bind_method(D_METHOD("get_shader_uniform", "param"), &ShaderMaterial::get_shader_uniform); + ClassDB::bind_method(D_METHOD("set_shader_parameter", "param", "value"), &ShaderMaterial::set_shader_parameter); + ClassDB::bind_method(D_METHOD("get_shader_parameter", "param"), &ShaderMaterial::get_shader_parameter); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader"), "set_shader", "get_shader"); } void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { String f = p_function.operator String(); - if ((f == "get_shader_uniform" || f == "set_shader_uniform") && p_idx == 0) { + if ((f == "get_shader_parameter" || f == "set_shader_parameter") && p_idx == 0) { if (shader.is_valid()) { List<PropertyInfo> pl; shader->get_shader_uniform_list(&pl); for (const PropertyInfo &E : pl) { - r_options->push_back(E.name.replace_first("shader_uniform/", "").quote()); + r_options->push_back(E.name.replace_first("shader_parameter/", "").quote()); } } } diff --git a/scene/resources/material.h b/scene/resources/material.h index 9458e859f0..6c81293ee3 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -115,8 +115,8 @@ public: void set_shader(const Ref<Shader> &p_shader); Ref<Shader> get_shader() const; - void set_shader_uniform(const StringName &p_param, const Variant &p_value); - Variant get_shader_uniform(const StringName &p_param) const; + void set_shader_parameter(const StringName &p_param, const Variant &p_value); + Variant get_shader_parameter(const StringName &p_param) const; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 7f318af899..b42e65c8df 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1614,7 +1614,7 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const emit_changed(); } -void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) { +void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) { ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX); RS::SurfaceData surface; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index fd3c2c4fa4..5ed4164117 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -265,7 +265,7 @@ protected: static void _bind_methods(); public: - void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0); + void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes = TypedArray<Array>(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0); void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data = Vector<uint8_t>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index 6c9c8ffdba..90ea879012 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -32,7 +32,7 @@ #ifdef DEBUG_ENABLED #include "servers/navigation_server_3d.h" -#endif +#endif // DEBUG_ENABLED void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) { ERR_FAIL_COND(p_mesh.is_null()); @@ -341,94 +341,8 @@ void NavigationMesh::clear_polygons() { polygons.clear(); } -#ifndef DISABLE_DEPRECATED -Ref<Mesh> NavigationMesh::get_debug_mesh() { - if (debug_mesh.is_valid()) { - return debug_mesh; - } - - Vector<Vector3> vertices = get_vertices(); - const Vector3 *vr = vertices.ptr(); - List<Face3> faces; - for (int i = 0; i < get_polygon_count(); i++) { - Vector<int> p = get_polygon(i); - - for (int j = 2; j < p.size(); j++) { - Face3 f; - f.vertex[0] = vr[p[0]]; - f.vertex[1] = vr[p[j - 1]]; - f.vertex[2] = vr[p[j]]; - - faces.push_back(f); - } - } - - HashMap<_EdgeKey, bool, _EdgeKey> edge_map; - Vector<Vector3> tmeshfaces; - tmeshfaces.resize(faces.size() * 3); - - { - Vector3 *tw = tmeshfaces.ptrw(); - int tidx = 0; - - for (const Face3 &f : faces) { - for (int j = 0; j < 3; j++) { - tw[tidx++] = f.vertex[j]; - _EdgeKey ek; - ek.from = f.vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON)); - ek.to = f.vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON)); - if (ek.from < ek.to) { - SWAP(ek.from, ek.to); - } - - HashMap<_EdgeKey, bool, _EdgeKey>::Iterator F = edge_map.find(ek); - - if (F) { - F->value = false; - - } else { - edge_map[ek] = true; - } - } - } - } - List<Vector3> lines; - - for (const KeyValue<_EdgeKey, bool> &E : edge_map) { - if (E.value) { - lines.push_back(E.key.from); - lines.push_back(E.key.to); - } - } - - Vector<Vector3> varr; - varr.resize(lines.size()); - { - Vector3 *w = varr.ptrw(); - int idx = 0; - for (const Vector3 &E : lines) { - w[idx++] = E; - } - } - - debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); - - if (!lines.size()) { - return debug_mesh; - } - - Array arr; - arr.resize(Mesh::ARRAY_MAX); - arr[Mesh::ARRAY_VERTEX] = varr; - - debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, arr); - - return debug_mesh; -} -#endif // DISABLE_DEPRECATED - #ifdef DEBUG_ENABLED -Ref<ArrayMesh> NavigationMesh::_get_debug_mesh() { +Ref<ArrayMesh> NavigationMesh::get_debug_mesh() { if (debug_mesh.is_valid()) { // Blocks further updates for now, code below is intended for dynamic updates e.g. when settings change. return debug_mesh; @@ -479,8 +393,6 @@ Ref<ArrayMesh> NavigationMesh::_get_debug_mesh() { for (int i = 0; i < polygon_count; i++) { polygon_color = debug_navigation_geometry_face_color * (Color(Math::randf(), Math::randf(), Math::randf())); - Vector<int> polygon = get_polygon(i); - face_color_array.push_back(polygon_color); face_color_array.push_back(polygon_color); face_color_array.push_back(polygon_color); @@ -490,7 +402,7 @@ Ref<ArrayMesh> NavigationMesh::_get_debug_mesh() { debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array); Ref<StandardMaterial3D> debug_geometry_face_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_material(); - debug_mesh->surface_set_material(debug_mesh->get_surface_count(), debug_geometry_face_material); + debug_mesh->surface_set_material(0, debug_geometry_face_material); // if enabled build geometry edge line surface bool enabled_edge_lines = NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_lines(); @@ -515,12 +427,12 @@ Ref<ArrayMesh> NavigationMesh::_get_debug_mesh() { line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array; debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, line_mesh_array); Ref<StandardMaterial3D> debug_geometry_edge_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_material(); - debug_mesh->surface_set_material(debug_mesh->get_surface_count(), debug_geometry_edge_material); + debug_mesh->surface_set_material(1, debug_geometry_edge_material); } return debug_mesh; } -#endif +#endif // DEBUG_ENABLED void NavigationMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sample_partition_type", "sample_partition_type"), &NavigationMesh::set_sample_partition_type); diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index c66025dc6d..5ddbd75dcb 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -202,11 +202,9 @@ public: Vector<int> get_polygon(int p_idx); void clear_polygons(); -#ifndef DISABLE_DEPRECATED - Ref<Mesh> get_debug_mesh(); -#endif // DISABLE_DEPRECATED - - Ref<ArrayMesh> _get_debug_mesh(); +#ifdef DEBUG_ENABLED + Ref<ArrayMesh> get_debug_mesh(); +#endif // DEBUG_ENABLED NavigationMesh(); }; diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index ed19101de4..e51c786786 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -1684,35 +1684,35 @@ void ParticleProcessMaterial::_bind_methods() { ADD_GROUP("Gravity", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity"); ADD_GROUP("Initial Velocity", "initial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGLE); ADD_GROUP("Scale", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE); @@ -1741,11 +1741,11 @@ void ParticleProcessMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "turbulence_influence_over_life", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TURB_INFLUENCE_OVER_LIFE); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); ADD_GROUP("Sub Emitter", "sub_emitter_"); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 727f7a4e09..c017c90370 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -2663,9 +2663,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0); if (has_depth) { - uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -max_p.y, -min_p.y, real_t(0.4), real_t(0.0))); + uvs_ptr[p_idx] = Vector2(Math::remap(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(point.y, -max_p.y, -min_p.y, real_t(0.4), real_t(0.0))); } else { - uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -max_p.y, -min_p.y, real_t(1.0), real_t(0.0))); + uvs_ptr[p_idx] = Vector2(Math::remap(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(point.y, -max_p.y, -min_p.y, real_t(1.0), real_t(0.0))); } tangents_ptr[p_idx * 4 + 0] = 1.0; tangents_ptr[p_idx * 4 + 1] = 0.0; @@ -2680,7 +2680,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, -depth / 2.0); vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, -1.0); - uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -max_p.y, -min_p.y, real_t(0.8), real_t(0.4))); + uvs_ptr[p_idx] = Vector2(Math::remap(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(point.y, -max_p.y, -min_p.y, real_t(0.8), real_t(0.4))); tangents_ptr[p_idx * 4 + 0] = -1.0; tangents_ptr[p_idx * 4 + 1] = 0.0; tangents_ptr[p_idx * 4 + 2] = 0.0; @@ -2721,9 +2721,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { vertices_ptr[p_idx + m] = quad_faces[m]; normals_ptr[p_idx + m] = Vector3(d.y, d.x, 0.0); if (m < 2) { - uvs_ptr[p_idx + m] = Vector2(Math::range_lerp(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.8 : 0.9); + uvs_ptr[p_idx + m] = Vector2(Math::remap(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.8 : 0.9); } else { - uvs_ptr[p_idx + m] = Vector2(Math::range_lerp(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.9 : 1.0); + uvs_ptr[p_idx + m] = Vector2(Math::remap(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.9 : 1.0); } tangents_ptr[(p_idx + m) * 4 + 0] = d.x; tangents_ptr[(p_idx + m) * 4 + 1] = -d.y; @@ -2760,9 +2760,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { vertices_ptr[p_idx + k] = quad_faces[k]; normals_ptr[p_idx + k] = Vector3(0.0, 0.0, 1.0); if (has_depth) { - uvs_ptr[p_idx + k] = Vector2(Math::range_lerp(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(quad_faces[k].y, -max_p.y, -min_p.y, real_t(0.4), real_t(0.0))); + uvs_ptr[p_idx + k] = Vector2(Math::remap(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(quad_faces[k].y, -max_p.y, -min_p.y, real_t(0.4), real_t(0.0))); } else { - uvs_ptr[p_idx + k] = Vector2(Math::range_lerp(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(quad_faces[k].y, -max_p.y, -min_p.y, real_t(1.0), real_t(0.0))); + uvs_ptr[p_idx + k] = Vector2(Math::remap(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(quad_faces[k].y, -max_p.y, -min_p.y, real_t(1.0), real_t(0.0))); } tangents_ptr[(p_idx + k) * 4 + 0] = 1.0; tangents_ptr[(p_idx + k) * 4 + 1] = 0.0; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 48d06934e3..4d566178a5 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -107,7 +107,7 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr _update_shader(); List<PropertyInfo> local; - RenderingServer::get_singleton()->shader_get_shader_uniform_list(shader, &local); + RenderingServer::get_singleton()->get_shader_parameter_list(shader, &local); params_cache.clear(); params_cache_dirty = false; @@ -138,35 +138,35 @@ RID Shader::get_rid() const { return shader; } -void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index) { +void Shader::set_default_texture_parameter(const StringName &p_name, const Ref<Texture2D> &p_texture, int p_index) { if (p_texture.is_valid()) { - if (!default_textures.has(p_param)) { - default_textures[p_param] = HashMap<int, Ref<Texture2D>>(); + if (!default_textures.has(p_name)) { + default_textures[p_name] = HashMap<int, Ref<Texture2D>>(); } - default_textures[p_param][p_index] = p_texture; - RS::get_singleton()->shader_set_default_texture_param(shader, p_param, p_texture->get_rid(), p_index); + default_textures[p_name][p_index] = p_texture; + RS::get_singleton()->shader_set_default_texture_parameter(shader, p_name, p_texture->get_rid(), p_index); } else { - if (default_textures.has(p_param) && default_textures[p_param].has(p_index)) { - default_textures[p_param].erase(p_index); + if (default_textures.has(p_name) && default_textures[p_name].has(p_index)) { + default_textures[p_name].erase(p_index); - if (default_textures[p_param].is_empty()) { - default_textures.erase(p_param); + if (default_textures[p_name].is_empty()) { + default_textures.erase(p_name); } } - RS::get_singleton()->shader_set_default_texture_param(shader, p_param, RID(), p_index); + RS::get_singleton()->shader_set_default_texture_parameter(shader, p_name, RID(), p_index); } emit_changed(); } -Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param, int p_index) const { - if (default_textures.has(p_param) && default_textures[p_param].has(p_index)) { - return default_textures[p_param][p_index]; +Ref<Texture2D> Shader::get_default_texture_parameter(const StringName &p_name, int p_index) const { + if (default_textures.has(p_name) && default_textures[p_name].has(p_index)) { + return default_textures[p_name][p_index]; } return Ref<Texture2D>(); } -void Shader::get_default_texture_param_list(List<StringName> *r_textures) const { +void Shader::get_default_texture_parameter_list(List<StringName> *r_textures) const { for (const KeyValue<StringName, HashMap<int, Ref<Texture2D>>> &E : default_textures) { r_textures->push_back(E.key); } @@ -176,8 +176,8 @@ bool Shader::is_text_shader() const { return true; } -bool Shader::has_uniform(const StringName &p_param) const { - return params_cache.has("shader_uniform/" + p_param); +bool Shader::has_parameter(const StringName &p_name) const { + return params_cache.has("shader_parameter/" + p_name); } void Shader::_update_shader() const { @@ -189,10 +189,10 @@ void Shader::_bind_methods() { ClassDB::bind_method(D_METHOD("set_code", "code"), &Shader::set_code); ClassDB::bind_method(D_METHOD("get_code"), &Shader::get_code); - ClassDB::bind_method(D_METHOD("set_default_texture_param", "param", "texture", "index"), &Shader::set_default_texture_param, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_default_texture_param", "param", "index"), &Shader::get_default_texture_param, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("set_default_texture_parameter", "name", "texture", "index"), &Shader::set_default_texture_parameter, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_default_texture_parameter", "name", "index"), &Shader::get_default_texture_parameter, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("has_uniform", "name"), &Shader::has_uniform); + ClassDB::bind_method(D_METHOD("has_parameter", "name"), &Shader::has_parameter); ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code"); diff --git a/scene/resources/shader.h b/scene/resources/shader.h index abc953de5f..d267e6520e 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -79,11 +79,11 @@ public: String get_code() const; void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; - bool has_uniform(const StringName &p_param) const; + bool has_parameter(const StringName &p_name) const; - void set_default_texture_param(const StringName &p_uniform, const Ref<Texture2D> &p_texture, int p_index = 0); - Ref<Texture2D> get_default_texture_param(const StringName &p_uniform, int p_index = 0) const; - void get_default_texture_param_list(List<StringName> *r_textures) const; + void set_default_texture_parameter(const StringName &p_name, const Ref<Texture2D> &p_texture, int p_index = 0); + Ref<Texture2D> get_default_texture_parameter(const StringName &p_name, int p_index = 0) const; + void get_default_texture_parameter_list(List<StringName> *r_textures) const; virtual bool is_text_shader() const; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index ff5210f1b3..cd893d8c23 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -41,6 +41,7 @@ float StyleBox::get_style_margin(Side p_side) const { } return 0; } + bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const { bool ret; if (GDVIRTUAL_CALL(_test_mask, p_point, p_rect, ret)) { @@ -63,6 +64,21 @@ void StyleBox::set_default_margin(Side p_side, float p_value) { emit_changed(); } +void StyleBox::set_default_margin_all(float p_value) { + for (int i = 0; i < 4; i++) { + margin[i] = p_value; + } + emit_changed(); +} + +void StyleBox::set_default_margin_individual(float p_left, float p_top, float p_right, float p_bottom) { + margin[SIDE_LEFT] = p_left; + margin[SIDE_TOP] = p_top; + margin[SIDE_RIGHT] = p_right; + margin[SIDE_BOTTOM] = p_bottom; + emit_changed(); +} + float StyleBox::get_default_margin(Side p_side) const { ERR_FAIL_INDEX_V((int)p_side, 4, 0.0); @@ -112,6 +128,7 @@ void StyleBox::_bind_methods() { ClassDB::bind_method(D_METHOD("test_mask", "point", "rect"), &StyleBox::test_mask); ClassDB::bind_method(D_METHOD("set_default_margin", "margin", "offset"), &StyleBox::set_default_margin); + ClassDB::bind_method(D_METHOD("set_default_margin_all", "offset"), &StyleBox::set_default_margin_all); ClassDB::bind_method(D_METHOD("get_default_margin", "margin"), &StyleBox::get_default_margin); ClassDB::bind_method(D_METHOD("get_margin", "margin"), &StyleBox::get_margin); @@ -165,6 +182,21 @@ void StyleBoxTexture::set_margin_size(Side p_side, float p_size) { emit_changed(); } +void StyleBoxTexture::set_margin_size_all(float p_size) { + for (int i = 0; i < 4; i++) { + margin[i] = p_size; + } + emit_changed(); +} + +void StyleBoxTexture::set_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom) { + margin[SIDE_LEFT] = p_left; + margin[SIDE_TOP] = p_top; + margin[SIDE_RIGHT] = p_right; + margin[SIDE_BOTTOM] = p_bottom; + emit_changed(); +} + float StyleBoxTexture::get_margin_size(Side p_side) const { ERR_FAIL_INDEX_V((int)p_side, 4, 0.0); @@ -292,11 +324,11 @@ void StyleBoxTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_texture"), &StyleBoxTexture::get_texture); ClassDB::bind_method(D_METHOD("set_margin_size", "margin", "size"), &StyleBoxTexture::set_margin_size); + ClassDB::bind_method(D_METHOD("set_margin_size_all", "size"), &StyleBoxTexture::set_margin_size_all); ClassDB::bind_method(D_METHOD("get_margin_size", "margin"), &StyleBoxTexture::get_margin_size); ClassDB::bind_method(D_METHOD("set_expand_margin_size", "margin", "size"), &StyleBoxTexture::set_expand_margin_size); ClassDB::bind_method(D_METHOD("set_expand_margin_all", "size"), &StyleBoxTexture::set_expand_margin_size_all); - ClassDB::bind_method(D_METHOD("set_expand_margin_individual", "size_left", "size_top", "size_right", "size_bottom"), &StyleBoxTexture::set_expand_margin_size_individual); ClassDB::bind_method(D_METHOD("get_expand_margin_size", "margin"), &StyleBoxTexture::get_expand_margin_size); ClassDB::bind_method(D_METHOD("set_region_rect", "region"), &StyleBoxTexture::set_region_rect); @@ -687,7 +719,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { const bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0); // Only enable antialiasing if it is actually needed. This improve performances // and maximizes sharpness for non-skewed StyleBoxes with sharp corners. - const bool aa_on = (rounded_corners || !skew.is_equal_approx(Vector2())) && anti_aliased; + const bool aa_on = (rounded_corners || !skew.is_zero_approx()) && anti_aliased; const bool blend_on = blend_border && draw_border; @@ -864,7 +896,6 @@ void StyleBoxFlat::_bind_methods() { ClassDB::bind_method(D_METHOD("set_border_blend", "blend"), &StyleBoxFlat::set_border_blend); ClassDB::bind_method(D_METHOD("get_border_blend"), &StyleBoxFlat::get_border_blend); - ClassDB::bind_method(D_METHOD("set_corner_radius_individual", "radius_top_left", "radius_top_right", "radius_bottom_right", "radius_bottom_left"), &StyleBoxFlat::set_corner_radius_individual); ClassDB::bind_method(D_METHOD("set_corner_radius_all", "radius"), &StyleBoxFlat::set_corner_radius_all); ClassDB::bind_method(D_METHOD("set_corner_radius", "corner", "radius"), &StyleBoxFlat::set_corner_radius); @@ -872,7 +903,6 @@ void StyleBoxFlat::_bind_methods() { ClassDB::bind_method(D_METHOD("set_expand_margin", "margin", "size"), &StyleBoxFlat::set_expand_margin_size); ClassDB::bind_method(D_METHOD("set_expand_margin_all", "size"), &StyleBoxFlat::set_expand_margin_size_all); - ClassDB::bind_method(D_METHOD("set_expand_margin_individual", "size_left", "size_top", "size_right", "size_bottom"), &StyleBoxFlat::set_expand_margin_size_individual); ClassDB::bind_method(D_METHOD("get_expand_margin", "margin"), &StyleBoxFlat::get_expand_margin_size); ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &StyleBoxFlat::set_draw_center); diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 88db4f5fbd..2c72446567 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -57,7 +57,10 @@ public: virtual bool test_mask(const Point2 &p_point, const Rect2 &p_rect) const; void set_default_margin(Side p_side, float p_value); + void set_default_margin_all(float p_value); + void set_default_margin_individual(float p_left, float p_top, float p_right, float p_bottom); float get_default_margin(Side p_side) const; + float get_margin(Side p_side) const; virtual Size2 get_center_size() const; @@ -112,6 +115,8 @@ public: float get_expand_margin_size(Side p_expand_side) const; void set_margin_size(Side p_side, float p_size); + void set_margin_size_all(float p_size); + void set_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom); float get_margin_size(Side p_side) const; void set_region_rect(const Rect2 &p_region_rect); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 028c131d0c..d53dc1a8fc 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2617,26 +2617,30 @@ void AnimatedTexture::_update_proxy() { time += delta; - float limit; - - if (fps == 0) { - limit = 0; - } else { - limit = 1.0 / fps; - } + float speed = speed_scale == 0 ? 0 : abs(1.0 / speed_scale); int iter_max = frame_count; while (iter_max && !pause) { - float frame_limit = limit + frames[current_frame].delay_sec; + float frame_limit = frames[current_frame].duration * speed; if (time > frame_limit) { - current_frame++; + if (speed_scale > 0.0) { + current_frame++; + } else { + current_frame--; + } if (current_frame >= frame_count) { - if (oneshot) { + if (one_shot) { current_frame = frame_count - 1; } else { current_frame = 0; } + } else if (current_frame < 0) { + if (one_shot) { + current_frame = 0; + } else { + current_frame = frame_count - 1; + } } time -= frame_limit; @@ -2684,13 +2688,13 @@ bool AnimatedTexture::get_pause() const { return pause; } -void AnimatedTexture::set_oneshot(bool p_oneshot) { +void AnimatedTexture::set_one_shot(bool p_one_shot) { RWLockWrite r(rw_lock); - oneshot = p_oneshot; + one_shot = p_one_shot; } -bool AnimatedTexture::get_oneshot() const { - return oneshot; +bool AnimatedTexture::get_one_shot() const { + return one_shot; } void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) { @@ -2710,30 +2714,30 @@ Ref<Texture2D> AnimatedTexture::get_frame_texture(int p_frame) const { return frames[p_frame].texture; } -void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) { +void AnimatedTexture::set_frame_duration(int p_frame, float p_duration) { ERR_FAIL_INDEX(p_frame, MAX_FRAMES); RWLockRead r(rw_lock); - frames[p_frame].delay_sec = p_delay_sec; + frames[p_frame].duration = p_duration; } -float AnimatedTexture::get_frame_delay(int p_frame) const { +float AnimatedTexture::get_frame_duration(int p_frame) const { ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0); RWLockRead r(rw_lock); - return frames[p_frame].delay_sec; + return frames[p_frame].duration; } -void AnimatedTexture::set_fps(float p_fps) { - ERR_FAIL_COND(p_fps < 0 || p_fps >= 1000); +void AnimatedTexture::set_speed_scale(float p_scale) { + ERR_FAIL_COND(p_scale < -1000 || p_scale >= 1000); - fps = p_fps; + speed_scale = p_scale; } -float AnimatedTexture::get_fps() const { - return fps; +float AnimatedTexture::get_speed_scale() const { + return speed_scale; } int AnimatedTexture::get_width() const { @@ -2809,27 +2813,27 @@ void AnimatedTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pause", "pause"), &AnimatedTexture::set_pause); ClassDB::bind_method(D_METHOD("get_pause"), &AnimatedTexture::get_pause); - ClassDB::bind_method(D_METHOD("set_oneshot", "oneshot"), &AnimatedTexture::set_oneshot); - ClassDB::bind_method(D_METHOD("get_oneshot"), &AnimatedTexture::get_oneshot); + ClassDB::bind_method(D_METHOD("set_one_shot", "one_shot"), &AnimatedTexture::set_one_shot); + ClassDB::bind_method(D_METHOD("get_one_shot"), &AnimatedTexture::get_one_shot); - ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps); - ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps); + ClassDB::bind_method(D_METHOD("set_speed_scale", "scale"), &AnimatedTexture::set_speed_scale); + ClassDB::bind_method(D_METHOD("get_speed_scale"), &AnimatedTexture::get_speed_scale); ClassDB::bind_method(D_METHOD("set_frame_texture", "frame", "texture"), &AnimatedTexture::set_frame_texture); ClassDB::bind_method(D_METHOD("get_frame_texture", "frame"), &AnimatedTexture::get_frame_texture); - ClassDB::bind_method(D_METHOD("set_frame_delay", "frame", "delay"), &AnimatedTexture::set_frame_delay); - ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay); + ClassDB::bind_method(D_METHOD("set_frame_duration", "frame", "duration"), &AnimatedTexture::set_frame_duration); + ClassDB::bind_method(D_METHOD("get_frame_duration", "frame"), &AnimatedTexture::get_frame_duration); ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames"); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_frame", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_current_frame", "get_current_frame"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pause"), "set_pause", "get_pause"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "oneshot"), "set_oneshot", "get_oneshot"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "-60,60,0.1,or_greater,or_lesser"), "set_speed_scale", "get_speed_scale"); for (int i = 0; i < MAX_FRAMES; i++) { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,suffix:s", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "frame_" + itos(i) + "/duration", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater,suffix:s", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_duration", "get_frame_duration", i); } BIND_CONSTANT(MAX_FRAMES); @@ -2955,7 +2959,7 @@ ImageTextureLayered::LayeredType ImageTextureLayered::get_layered_type() const { return layered_type; } -Error ImageTextureLayered::_create_from_images(const Array &p_images) { +Error ImageTextureLayered::_create_from_images(const TypedArray<Image> &p_images) { Vector<Ref<Image>> images; for (int i = 0; i < p_images.size(); i++) { Ref<Image> img = p_images[i]; @@ -2966,8 +2970,8 @@ Error ImageTextureLayered::_create_from_images(const Array &p_images) { return create_from_images(images); } -Array ImageTextureLayered::_get_images() const { - Array images; +TypedArray<Image> ImageTextureLayered::_get_images() const { + TypedArray<Image> images; for (int i = 0; i < layers; i++) { images.push_back(get_layer_data(i)); } @@ -3054,7 +3058,7 @@ void ImageTextureLayered::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_images"), &ImageTextureLayered::_get_images); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_ARRAY_TYPE, "Image", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images"); } ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 133b312d27..da4b8046a5 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -422,9 +422,9 @@ class ImageTextureLayered : public TextureLayered { int layers = 0; bool mipmaps = false; - Error _create_from_images(const Array &p_images); + Error _create_from_images(const TypedArray<Image> &p_images); - Array _get_images() const; + TypedArray<Image> _get_images() const; protected: static void _bind_methods(); @@ -922,15 +922,15 @@ private: struct Frame { Ref<Texture2D> texture; - float delay_sec = 0.0; + float duration = 1.0; }; Frame frames[MAX_FRAMES]; int frame_count = 1.0; int current_frame = 0; bool pause = false; - bool oneshot = false; - float fps = 4.0; + bool one_shot = false; + float speed_scale = 1.0; float time = 0.0; @@ -952,17 +952,17 @@ public: void set_pause(bool p_pause); bool get_pause() const; - void set_oneshot(bool p_oneshot); - bool get_oneshot() const; + void set_one_shot(bool p_one_shot); + bool get_one_shot() const; void set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture); Ref<Texture2D> get_frame_texture(int p_frame) const; - void set_frame_delay(int p_frame, float p_delay_sec); - float get_frame_delay(int p_frame) const; + void set_frame_duration(int p_frame, float p_duration); + float get_frame_duration(int p_frame) const; - void set_fps(float p_fps); - float get_fps() const; + void set_speed_scale(float p_scale); + float get_speed_scale() const; virtual int get_width() const override; virtual int get_height() const override; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 0dad5d4be4..262dbe28ed 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -723,10 +723,10 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co n.node = p_node; n.position = p_position; - Ref<VisualShaderNodeUniform> uniform = n.node; - if (uniform.is_valid()) { - String valid_name = validate_uniform_name(uniform->get_uniform_name(), uniform); - uniform->set_uniform_name(valid_name); + Ref<VisualShaderNodeParameter> parameter = n.node; + if (parameter.is_valid()) { + String valid_name = validate_parameter_name(parameter->get_parameter_name(), parameter); + parameter->set_parameter_name(valid_name); } Ref<VisualShaderNodeInput> input = n.node; @@ -1279,7 +1279,7 @@ String VisualShader::validate_port_name(const String &p_port_name, VisualShaderN return name; } -String VisualShader::validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const { +String VisualShader::validate_parameter_name(const String &p_name, const Ref<VisualShaderNodeParameter> &p_parameter) const { String name = p_name; //validate name first while (name.length() && !is_ascii_char(name[0])) { name = name.substr(1, name.length() - 1); @@ -1299,7 +1299,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua } if (name.is_empty()) { - name = p_uniform->get_caption(); + name = p_parameter->get_caption(); } int attempt = 1; @@ -1308,11 +1308,11 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua bool exists = false; for (int i = 0; i < TYPE_MAX; i++) { for (const KeyValue<int, Node> &E : graph[i].nodes) { - Ref<VisualShaderNodeUniform> node = E.value.node; - if (node == p_uniform) { //do not test on self + Ref<VisualShaderNodeParameter> node = E.value.node; + if (node == p_parameter) { //do not test on self continue; } - if (node.is_valid() && node->get_uniform_name() == name) { + if (node.is_valid() && node->get_parameter_name() == name) { exists = true; break; } @@ -1620,8 +1620,8 @@ Error VisualShader::_write_node(Type type, StringBuilder *global_code, StringBui bool skip_global = input.is_valid() && for_preview; if (!skip_global) { - Ref<VisualShaderNodeUniform> uniform = vsnode; - if (!uniform.is_valid() || !uniform->is_global_code_generated()) { + Ref<VisualShaderNodeParameter> parameter = vsnode; + if (!parameter.is_valid() || !parameter->is_global_code_generated()) { if (global_code) { *global_code += vsnode->generate_global(get_mode(), type, node); } @@ -1680,8 +1680,8 @@ Error VisualShader::_write_node(Type type, StringBuilder *global_code, StringBui VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr()); if (ptr->has_method("get_input_real_name")) { inputs[i] = ptr->call("get_input_real_name"); - } else if (ptr->has_method("get_uniform_name")) { - inputs[i] = ptr->call("get_uniform_name"); + } else if (ptr->has_method("get_parameter_name")) { + inputs[i] = ptr->call("get_parameter_name"); } else { inputs[i] = ""; } @@ -2150,8 +2150,8 @@ void VisualShader::_update_shader() const { static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "start", "process", "collide", "start_custom", "process_custom", "sky", "fog" }; String global_expressions; - HashSet<String> used_uniform_names; - List<VisualShaderNodeUniform *> uniforms; + HashSet<String> used_parameter_names; + List<VisualShaderNodeParameter *> parameters; HashMap<int, List<int>> emitters; HashMap<int, List<int>> varying_setters; @@ -2170,13 +2170,13 @@ void VisualShader::_update_shader() const { expr += "\n"; global_expressions += expr; } - Ref<VisualShaderNodeUniformRef> uniform_ref = E.value.node; - if (uniform_ref.is_valid()) { - used_uniform_names.insert(uniform_ref->get_uniform_name()); + Ref<VisualShaderNodeParameterRef> parameter_ref = E.value.node; + if (parameter_ref.is_valid()) { + used_parameter_names.insert(parameter_ref->get_parameter_name()); } - Ref<VisualShaderNodeUniform> uniform = E.value.node; - if (uniform.is_valid()) { - uniforms.push_back(uniform.ptr()); + Ref<VisualShaderNodeParameter> parameter = E.value.node; + if (parameter.is_valid()) { + parameters.push_back(parameter.ptr()); } Ref<VisualShaderNodeVaryingSetter> varying_setter = E.value.node; if (varying_setter.is_valid() && varying_setter->is_input_port_connected(0)) { @@ -2195,13 +2195,13 @@ void VisualShader::_update_shader() const { } } - for (int i = 0; i < uniforms.size(); i++) { - VisualShaderNodeUniform *uniform = uniforms[i]; - if (used_uniform_names.has(uniform->get_uniform_name())) { - global_code += uniform->generate_global(get_mode(), Type(i), -1); - const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(true); + for (int i = 0; i < parameters.size(); i++) { + VisualShaderNodeParameter *parameter = parameters[i]; + if (used_parameter_names.has(parameter->get_parameter_name())) { + global_code += parameter->generate_global(get_mode(), Type(i), -1); + const_cast<VisualShaderNodeParameter *>(parameter)->set_global_code_generated(true); } else { - const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(false); + const_cast<VisualShaderNodeParameter *>(parameter)->set_global_code_generated(false); } } @@ -2520,7 +2520,7 @@ void VisualShader::_update_shader() const { const_cast<VisualShader *>(this)->set_code(final_code); for (int i = 0; i < default_tex_params.size(); i++) { for (int j = 0; j < default_tex_params[i].params.size(); j++) { - const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].params[j], j); + const_cast<VisualShader *>(this)->set_default_texture_parameter(default_tex_params[i].name, default_tex_params[i].params[j], j); } } if (previous_code != final_code) { @@ -3215,20 +3215,20 @@ void VisualShaderNodeInput::_bind_methods() { VisualShaderNodeInput::VisualShaderNodeInput() { } -////////////// UniformRef +////////////// ParameterRef -RBMap<RID, List<VisualShaderNodeUniformRef::Uniform>> uniforms; +RBMap<RID, List<VisualShaderNodeParameterRef::Parameter>> parameters; -void VisualShaderNodeUniformRef::add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type) { - uniforms[p_shader_rid].push_back({ p_name, p_type }); +void VisualShaderNodeParameterRef::add_parameter(RID p_shader_rid, const String &p_name, ParameterType p_type) { + parameters[p_shader_rid].push_back({ p_name, p_type }); } -void VisualShaderNodeUniformRef::clear_uniforms(RID p_shader_rid) { - uniforms[p_shader_rid].clear(); +void VisualShaderNodeParameterRef::clear_parameters(RID p_shader_rid) { + parameters[p_shader_rid].clear(); } -bool VisualShaderNodeUniformRef::has_uniform(RID p_shader_rid, const String &p_name) { - for (const VisualShaderNodeUniformRef::Uniform &E : uniforms[p_shader_rid]) { +bool VisualShaderNodeParameterRef::has_parameter(RID p_shader_rid, const String &p_name) { + for (const VisualShaderNodeParameterRef::Parameter &E : parameters[p_shader_rid]) { if (E.name == p_name) { return true; } @@ -3236,41 +3236,41 @@ bool VisualShaderNodeUniformRef::has_uniform(RID p_shader_rid, const String &p_n return false; } -String VisualShaderNodeUniformRef::get_caption() const { - return "UniformRef"; +String VisualShaderNodeParameterRef::get_caption() const { + return "ParameterRef"; } -int VisualShaderNodeUniformRef::get_input_port_count() const { +int VisualShaderNodeParameterRef::get_input_port_count() const { return 0; } -VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_input_port_type(int p_port) const { +VisualShaderNodeParameterRef::PortType VisualShaderNodeParameterRef::get_input_port_type(int p_port) const { return PortType::PORT_TYPE_SCALAR; } -String VisualShaderNodeUniformRef::get_input_port_name(int p_port) const { +String VisualShaderNodeParameterRef::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeUniformRef::get_output_port_count() const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: +int VisualShaderNodeParameterRef::get_output_port_count() const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: return 1; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return 1; - case UniformType::UNIFORM_TYPE_BOOLEAN: + case PARAMETER_TYPE_BOOLEAN: return 1; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return 1; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return 1; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return 1; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return 1; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: return 2; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return 1; default: break; @@ -3278,30 +3278,30 @@ int VisualShaderNodeUniformRef::get_output_port_count() const { return 1; } -VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port_type(int p_port) const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: +VisualShaderNodeParameterRef::PortType VisualShaderNodeParameterRef::get_output_port_type(int p_port) const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: return PortType::PORT_TYPE_SCALAR; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return PortType::PORT_TYPE_SCALAR_INT; - case UniformType::UNIFORM_TYPE_BOOLEAN: + case PARAMETER_TYPE_BOOLEAN: return PortType::PORT_TYPE_BOOLEAN; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return PortType::PORT_TYPE_VECTOR_2D; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return PortType::PORT_TYPE_VECTOR_3D; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return PortType::PORT_TYPE_VECTOR_4D; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return PortType::PORT_TYPE_TRANSFORM; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: if (p_port == 0) { return PortType::PORT_TYPE_VECTOR_3D; } else if (p_port == 1) { return PORT_TYPE_SCALAR; } break; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return PortType::PORT_TYPE_SAMPLER; default: break; @@ -3309,30 +3309,30 @@ VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port return PORT_TYPE_SCALAR; } -String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: +String VisualShaderNodeParameterRef::get_output_port_name(int p_port) const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: return ""; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return ""; - case UniformType::UNIFORM_TYPE_BOOLEAN: + case PARAMETER_TYPE_BOOLEAN: return ""; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return ""; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return ""; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return ""; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return ""; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: if (p_port == 0) { return "rgb"; } else if (p_port == 1) { return "alpha"; } break; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return ""; break; default: @@ -3341,85 +3341,85 @@ String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const { return ""; } -void VisualShaderNodeUniformRef::set_shader_rid(const RID &p_shader_rid) { +void VisualShaderNodeParameterRef::set_shader_rid(const RID &p_shader_rid) { shader_rid = p_shader_rid; } -void VisualShaderNodeUniformRef::set_uniform_name(const String &p_name) { - uniform_name = p_name; +void VisualShaderNodeParameterRef::set_parameter_name(const String &p_name) { + parameter_name = p_name; if (shader_rid.is_valid()) { - update_uniform_type(); + update_parameter_type(); } emit_changed(); } -void VisualShaderNodeUniformRef::update_uniform_type() { - if (uniform_name != "[None]") { - uniform_type = get_uniform_type_by_name(uniform_name); +void VisualShaderNodeParameterRef::update_parameter_type() { + if (parameter_name != "[None]") { + param_type = get_parameter_type_by_name(parameter_name); } else { - uniform_type = UniformType::UNIFORM_TYPE_FLOAT; + param_type = PARAMETER_TYPE_FLOAT; } } -String VisualShaderNodeUniformRef::get_uniform_name() const { - return uniform_name; +String VisualShaderNodeParameterRef::get_parameter_name() const { + return parameter_name; } -int VisualShaderNodeUniformRef::get_uniforms_count() const { +int VisualShaderNodeParameterRef::get_parameters_count() const { ERR_FAIL_COND_V(!shader_rid.is_valid(), 0); - return uniforms[shader_rid].size(); + return parameters[shader_rid].size(); } -String VisualShaderNodeUniformRef::get_uniform_name_by_index(int p_idx) const { +String VisualShaderNodeParameterRef::get_parameter_name_by_index(int p_idx) const { ERR_FAIL_COND_V(!shader_rid.is_valid(), String()); - if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) { - return uniforms[shader_rid][p_idx].name; + if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) { + return parameters[shader_rid][p_idx].name; } return ""; } -VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_name(const String &p_name) const { - ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT); +VisualShaderNodeParameterRef::ParameterType VisualShaderNodeParameterRef::get_parameter_type_by_name(const String &p_name) const { + ERR_FAIL_COND_V(!shader_rid.is_valid(), PARAMETER_TYPE_FLOAT); - for (int i = 0; i < uniforms[shader_rid].size(); i++) { - if (uniforms[shader_rid][i].name == p_name) { - return uniforms[shader_rid][i].type; + for (int i = 0; i < parameters[shader_rid].size(); i++) { + if (parameters[shader_rid][i].name == p_name) { + return parameters[shader_rid][i].type; } } - return UniformType::UNIFORM_TYPE_FLOAT; + return PARAMETER_TYPE_FLOAT; } -VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_index(int p_idx) const { - ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT); +VisualShaderNodeParameterRef::ParameterType VisualShaderNodeParameterRef::get_parameter_type_by_index(int p_idx) const { + ERR_FAIL_COND_V(!shader_rid.is_valid(), PARAMETER_TYPE_FLOAT); - if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) { - return uniforms[shader_rid][p_idx].type; + if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) { + return parameters[shader_rid][p_idx].type; } - return UniformType::UNIFORM_TYPE_FLOAT; + return PARAMETER_TYPE_FLOAT; } -VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_by_index(int p_idx) const { +VisualShaderNodeParameterRef::PortType VisualShaderNodeParameterRef::get_port_type_by_index(int p_idx) const { ERR_FAIL_COND_V(!shader_rid.is_valid(), PORT_TYPE_SCALAR); - if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) { - switch (uniforms[shader_rid][p_idx].type) { - case UniformType::UNIFORM_TYPE_FLOAT: + if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) { + switch (parameters[shader_rid][p_idx].type) { + case PARAMETER_TYPE_FLOAT: return PORT_TYPE_SCALAR; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return PORT_TYPE_SCALAR_INT; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return PORT_TYPE_SAMPLER; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return PORT_TYPE_VECTOR_2D; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return PORT_TYPE_VECTOR_3D; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return PORT_TYPE_VECTOR_4D; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return PORT_TYPE_TRANSFORM; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: return PORT_TYPE_VECTOR_3D; default: break; @@ -3428,54 +3428,54 @@ VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_b return PORT_TYPE_SCALAR; } -String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: - if (uniform_name == "[None]") { +String VisualShaderNodeParameterRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: + if (parameter_name == "[None]") { return " " + p_output_vars[0] + " = 0.0;\n"; } break; - case UniformType::UNIFORM_TYPE_COLOR: { - String code = " " + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n"; - code += " " + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n"; + case PARAMETER_TYPE_COLOR: { + String code = " " + p_output_vars[0] + " = " + get_parameter_name() + ".rgb;\n"; + code += " " + p_output_vars[1] + " = " + get_parameter_name() + ".a;\n"; return code; } break; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return String(); default: break; } - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeUniformRef::_set_uniform_type(int p_uniform_type) { - uniform_type = (UniformType)p_uniform_type; +void VisualShaderNodeParameterRef::_set_parameter_type(int p_type) { + param_type = (ParameterType)p_type; } -int VisualShaderNodeUniformRef::_get_uniform_type() const { - return (int)uniform_type; +int VisualShaderNodeParameterRef::_get_parameter_type() const { + return (int)param_type; } -void VisualShaderNodeUniformRef::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniformRef::set_uniform_name); - ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniformRef::get_uniform_name); +void VisualShaderNodeParameterRef::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_parameter_name", "name"), &VisualShaderNodeParameterRef::set_parameter_name); + ClassDB::bind_method(D_METHOD("get_parameter_name"), &VisualShaderNodeParameterRef::get_parameter_name); - ClassDB::bind_method(D_METHOD("_set_uniform_type", "type"), &VisualShaderNodeUniformRef::_set_uniform_type); - ClassDB::bind_method(D_METHOD("_get_uniform_type"), &VisualShaderNodeUniformRef::_get_uniform_type); + ClassDB::bind_method(D_METHOD("_set_parameter_type", "type"), &VisualShaderNodeParameterRef::_set_parameter_type); + ClassDB::bind_method(D_METHOD("_get_parameter_type"), &VisualShaderNodeParameterRef::_get_parameter_type); - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name", PROPERTY_HINT_ENUM, ""), "set_uniform_name", "get_uniform_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "uniform_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_uniform_type", "_get_uniform_type"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "parameter_name", PROPERTY_HINT_ENUM, ""), "set_parameter_name", "get_parameter_name"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "param_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_parameter_type", "_get_parameter_type"); } -Vector<StringName> VisualShaderNodeUniformRef::get_editable_properties() const { +Vector<StringName> VisualShaderNodeParameterRef::get_editable_properties() const { Vector<StringName> props; - props.push_back("uniform_name"); - props.push_back("uniform_type"); + props.push_back("parameter_name"); + props.push_back("param_type"); return props; } -VisualShaderNodeUniformRef::VisualShaderNodeUniformRef() { +VisualShaderNodeParameterRef::VisualShaderNodeParameterRef() { } //////////////////////////////////////////// @@ -3687,17 +3687,17 @@ VisualShaderNodeOutput::VisualShaderNodeOutput() { /////////////////////////// -void VisualShaderNodeUniform::set_uniform_name(const String &p_name) { - uniform_name = p_name; +void VisualShaderNodeParameter::set_parameter_name(const String &p_name) { + parameter_name = p_name; emit_signal(SNAME("name_changed")); emit_changed(); } -String VisualShaderNodeUniform::get_uniform_name() const { - return uniform_name; +String VisualShaderNodeParameter::get_parameter_name() const { + return parameter_name; } -void VisualShaderNodeUniform::set_qualifier(VisualShaderNodeUniform::Qualifier p_qual) { +void VisualShaderNodeParameter::set_qualifier(VisualShaderNodeParameter::Qualifier p_qual) { ERR_FAIL_INDEX(int(p_qual), int(QUAL_MAX)); if (qualifier == p_qual) { return; @@ -3706,26 +3706,37 @@ void VisualShaderNodeUniform::set_qualifier(VisualShaderNodeUniform::Qualifier p emit_changed(); } -VisualShaderNodeUniform::Qualifier VisualShaderNodeUniform::get_qualifier() const { +VisualShaderNodeParameter::Qualifier VisualShaderNodeParameter::get_qualifier() const { return qualifier; } -void VisualShaderNodeUniform::set_global_code_generated(bool p_enabled) { +void VisualShaderNodeParameter::set_global_code_generated(bool p_enabled) { global_code_generated = p_enabled; } -bool VisualShaderNodeUniform::is_global_code_generated() const { +bool VisualShaderNodeParameter::is_global_code_generated() const { return global_code_generated; } -void VisualShaderNodeUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name); - ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name); +#ifndef DISABLE_DEPRECATED +// Kept for compatibility from 3.x to 4.0. +bool VisualShaderNodeParameter::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "uniform_name") { + set_parameter_name(p_value); + return true; + } + return false; +} +#endif + +void VisualShaderNodeParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_parameter_name", "name"), &VisualShaderNodeParameter::set_parameter_name); + ClassDB::bind_method(D_METHOD("get_parameter_name"), &VisualShaderNodeParameter::get_parameter_name); - ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeUniform::set_qualifier); - ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeUniform::get_qualifier); + ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeParameter::set_qualifier); + ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeParameter::get_qualifier); - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "parameter_name"), "set_parameter_name", "get_parameter_name"); ADD_PROPERTY(PropertyInfo(Variant::INT, "qualifier", PROPERTY_HINT_ENUM, "None,Global,Instance"), "set_qualifier", "get_qualifier"); BIND_ENUM_CONSTANT(QUAL_NONE); @@ -3734,7 +3745,7 @@ void VisualShaderNodeUniform::_bind_methods() { BIND_ENUM_CONSTANT(QUAL_MAX); } -String VisualShaderNodeUniform::_get_qual_str() const { +String VisualShaderNodeParameter::_get_qual_str() const { if (is_qualifier_supported(qualifier)) { switch (qualifier) { case QUAL_NONE: @@ -3750,11 +3761,11 @@ String VisualShaderNodeUniform::_get_qual_str() const { return String(); } -String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { +String VisualShaderNodeParameter::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { List<String> keyword_list; ShaderLanguage::get_keyword_list(&keyword_list); - if (keyword_list.find(uniform_name)) { - return RTR("Shader keywords cannot be used as uniform names.\nChoose another name."); + if (keyword_list.find(parameter_name)) { + return RTR("Shader keywords cannot be used as parameter names.\nChoose another name."); } if (!is_qualifier_supported(qualifier)) { String qualifier_str; @@ -3770,66 +3781,66 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T default: break; } - return vformat(RTR("This uniform type does not support the '%s' qualifier."), qualifier_str); + return vformat(RTR("This parameter type does not support the '%s' qualifier."), qualifier_str); } else if (qualifier == Qualifier::QUAL_GLOBAL) { - RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(uniform_name); + RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(parameter_name); if (gvt == RS::GLOBAL_VAR_TYPE_MAX) { - return vformat(RTR("Global uniform '%s' does not exist.\nCreate it in the Project Settings."), uniform_name); + return vformat(RTR("Global parameter '%s' does not exist.\nCreate it in the Project Settings."), parameter_name); } bool incompatible_type = false; switch (gvt) { case RS::GLOBAL_VAR_TYPE_FLOAT: { - if (!Object::cast_to<VisualShaderNodeFloatUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeFloatParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_INT: { - if (!Object::cast_to<VisualShaderNodeIntUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeIntParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_BOOL: { - if (!Object::cast_to<VisualShaderNodeBooleanUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeBooleanParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_COLOR: { - if (!Object::cast_to<VisualShaderNodeColorUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeColorParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_VEC3: { - if (!Object::cast_to<VisualShaderNodeVec3Uniform>(this)) { + if (!Object::cast_to<VisualShaderNodeVec3Parameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - if (!Object::cast_to<VisualShaderNodeVec4Uniform>(this)) { + if (!Object::cast_to<VisualShaderNodeVec4Parameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - if (!Object::cast_to<VisualShaderNodeTransformUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTransformParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { - if (!Object::cast_to<VisualShaderNodeTextureUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTextureParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { - if (!Object::cast_to<VisualShaderNodeTexture3DUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTexture3DParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { - if (!Object::cast_to<VisualShaderNodeTexture2DArrayUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTexture2DArrayParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { - if (!Object::cast_to<VisualShaderNodeCubemapUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeCubemapParameter>(this)) { incompatible_type = true; } } break; @@ -3837,20 +3848,20 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T break; } if (incompatible_type) { - return vformat(RTR("Global uniform '%s' has an incompatible type for this kind of node.\nChange it in the Project Settings."), uniform_name); + return vformat(RTR("Global parameter '%s' has an incompatible type for this kind of node.\nChange it in the Project Settings."), parameter_name); } } return String(); } -Vector<StringName> VisualShaderNodeUniform::get_editable_properties() const { +Vector<StringName> VisualShaderNodeParameter::get_editable_properties() const { Vector<StringName> props; props.push_back("qualifier"); return props; } -VisualShaderNodeUniform::VisualShaderNodeUniform() { +VisualShaderNodeParameter::VisualShaderNodeParameter() { } ////////////// ResizeableBase diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index d62c823791..4116eaa196 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -36,7 +36,7 @@ #include "scene/gui/control.h" #include "scene/resources/shader.h" -class VisualShaderNodeUniform; +class VisualShaderNodeParameter; class VisualShaderNode; class VisualShader : public Shader { @@ -229,7 +229,7 @@ public: // internal methods String generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &r_default_tex_params) const; String validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const; - String validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const; + String validate_parameter_name(const String &p_name, const Ref<VisualShaderNodeParameter> &p_parameter) const; VisualShader(); }; @@ -499,8 +499,8 @@ public: VisualShaderNodeOutput(); }; -class VisualShaderNodeUniform : public VisualShaderNode { - GDCLASS(VisualShaderNodeUniform, VisualShaderNode); +class VisualShaderNodeParameter : public VisualShaderNode { + GDCLASS(VisualShaderNodeParameter, VisualShaderNode); public: enum Qualifier { @@ -511,7 +511,7 @@ public: }; private: - String uniform_name = ""; + String parameter_name = ""; Qualifier qualifier = QUAL_NONE; bool global_code_generated = false; @@ -519,9 +519,13 @@ protected: static void _bind_methods(); String _get_qual_str() const; +#ifndef DISABLE_DEPRECATED + bool _set(const StringName &p_name, const Variant &p_value); +#endif + public: - void set_uniform_name(const String &p_name); - String get_uniform_name() const; + void set_parameter_name(const String &p_name); + String get_parameter_name() const; void set_qualifier(Qualifier p_qual); Qualifier get_qualifier() const; @@ -535,44 +539,44 @@ public: virtual Vector<StringName> get_editable_properties() const override; virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override; - VisualShaderNodeUniform(); + VisualShaderNodeParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeUniform::Qualifier) +VARIANT_ENUM_CAST(VisualShaderNodeParameter::Qualifier) -class VisualShaderNodeUniformRef : public VisualShaderNode { - GDCLASS(VisualShaderNodeUniformRef, VisualShaderNode); +class VisualShaderNodeParameterRef : public VisualShaderNode { + GDCLASS(VisualShaderNodeParameterRef, VisualShaderNode); public: - enum UniformType { - UNIFORM_TYPE_FLOAT, - UNIFORM_TYPE_INT, - UNIFORM_TYPE_BOOLEAN, - UNIFORM_TYPE_VECTOR2, - UNIFORM_TYPE_VECTOR3, - UNIFORM_TYPE_VECTOR4, - UNIFORM_TYPE_TRANSFORM, - UNIFORM_TYPE_COLOR, + enum ParameterType { + PARAMETER_TYPE_FLOAT, + PARAMETER_TYPE_INT, + PARAMETER_TYPE_BOOLEAN, + PARAMETER_TYPE_VECTOR2, + PARAMETER_TYPE_VECTOR3, + PARAMETER_TYPE_VECTOR4, + PARAMETER_TYPE_TRANSFORM, + PARAMETER_TYPE_COLOR, UNIFORM_TYPE_SAMPLER, }; - struct Uniform { + struct Parameter { String name; - UniformType type; + ParameterType type; }; private: RID shader_rid; - String uniform_name = "[None]"; - UniformType uniform_type = UniformType::UNIFORM_TYPE_FLOAT; + String parameter_name = "[None]"; + ParameterType param_type = ParameterType::PARAMETER_TYPE_FLOAT; protected: static void _bind_methods(); public: - static void add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type); - static void clear_uniforms(RID p_shader_rid); - static bool has_uniform(RID p_shader_rid, const String &p_name); + static void add_parameter(RID p_shader_rid, const String &p_name, ParameterType p_type); + static void clear_parameters(RID p_shader_rid); + static bool has_parameter(RID p_shader_rid, const String &p_name); public: virtual String get_caption() const override; @@ -587,25 +591,25 @@ public: void set_shader_rid(const RID &p_shader); - void set_uniform_name(const String &p_name); - String get_uniform_name() const; + void set_parameter_name(const String &p_name); + String get_parameter_name() const; - void update_uniform_type(); + void update_parameter_type(); - void _set_uniform_type(int p_uniform_type); - int _get_uniform_type() const; + void _set_parameter_type(int p_parameter_type); + int _get_parameter_type() const; - int get_uniforms_count() const; - String get_uniform_name_by_index(int p_idx) const; - UniformType get_uniform_type_by_name(const String &p_name) const; - UniformType get_uniform_type_by_index(int p_idx) const; + int get_parameters_count() const; + String get_parameter_name_by_index(int p_idx) const; + ParameterType get_parameter_type_by_name(const String &p_name) const; + ParameterType get_parameter_type_by_index(int p_idx) const; PortType get_port_type_by_index(int p_idx) const; virtual Vector<StringName> get_editable_properties() const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeUniformRef(); + VisualShaderNodeParameterRef(); }; class VisualShaderNodeResizableBase : public VisualShaderNode { diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a968aebdaa..de13912b75 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -1636,10 +1636,14 @@ String VisualShaderNodeLinearSceneDepth::get_output_port_name(int p_port) const return "linear depth"; } +bool VisualShaderNodeLinearSceneDepth::has_output_port_preview(int p_port) const { + return false; +} + String VisualShaderNodeLinearSceneDepth::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; - code += " float _log_depth = texture(DEPTH_TEXTURE, SCREEN_UV).x;\n"; + code += " float _log_depth = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).x;\n"; code += " vec3 _depth_ndc = vec3(SCREEN_UV * 2.0 - 1.0, _log_depth);\n"; code += " vec4 _depth_view = INV_PROJECTION_MATRIX * vec4(_depth_ndc, 1.0);\n"; code += " _depth_view.xyz /= _depth_view.w;"; @@ -4712,44 +4716,44 @@ VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() { set_input_port_default_value(0, Transform3D()); } -////////////// Float Uniform +////////////// Float Parameter -String VisualShaderNodeFloatUniform::get_caption() const { - return "FloatUniform"; +String VisualShaderNodeFloatParameter::get_caption() const { + return "FloatParameter"; } -int VisualShaderNodeFloatUniform::get_input_port_count() const { +int VisualShaderNodeFloatParameter::get_input_port_count() const { return 0; } -VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_input_port_type(int p_port) const { +VisualShaderNodeFloatParameter::PortType VisualShaderNodeFloatParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeFloatUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeFloatUniform::get_output_port_count() const { +int VisualShaderNodeFloatParameter::get_output_port_count() const { return 1; } -VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_output_port_type(int p_port) const { +VisualShaderNodeFloatParameter::PortType VisualShaderNodeFloatParameter::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeFloatParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = ""; if (hint == HINT_RANGE) { - code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")"; + code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { - code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")"; + code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")"; } else { - code += _get_qual_str() + "uniform float " + get_uniform_name(); + code += _get_qual_str() + "uniform float " + get_parameter_name(); } if (default_value_enabled) { code += " = " + rtos(default_value); @@ -4758,19 +4762,19 @@ String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, Visual return code; } -String VisualShaderNodeFloatUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeFloatParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeFloatUniform::is_show_prop_names() const { +bool VisualShaderNodeFloatParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeFloatUniform::is_use_prop_slots() const { +bool VisualShaderNodeFloatParameter::is_use_prop_slots() const { return true; } -void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) { +void VisualShaderNodeFloatParameter::set_hint(Hint p_hint) { ERR_FAIL_INDEX(int(p_hint), int(HINT_MAX)); if (hint == p_hint) { return; @@ -4779,11 +4783,11 @@ void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) { emit_changed(); } -VisualShaderNodeFloatUniform::Hint VisualShaderNodeFloatUniform::get_hint() const { +VisualShaderNodeFloatParameter::Hint VisualShaderNodeFloatParameter::get_hint() const { return hint; } -void VisualShaderNodeFloatUniform::set_min(float p_value) { +void VisualShaderNodeFloatParameter::set_min(float p_value) { if (Math::is_equal_approx(hint_range_min, p_value)) { return; } @@ -4791,11 +4795,11 @@ void VisualShaderNodeFloatUniform::set_min(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_min() const { +float VisualShaderNodeFloatParameter::get_min() const { return hint_range_min; } -void VisualShaderNodeFloatUniform::set_max(float p_value) { +void VisualShaderNodeFloatParameter::set_max(float p_value) { if (Math::is_equal_approx(hint_range_max, p_value)) { return; } @@ -4803,11 +4807,11 @@ void VisualShaderNodeFloatUniform::set_max(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_max() const { +float VisualShaderNodeFloatParameter::get_max() const { return hint_range_max; } -void VisualShaderNodeFloatUniform::set_step(float p_value) { +void VisualShaderNodeFloatParameter::set_step(float p_value) { if (Math::is_equal_approx(hint_range_step, p_value)) { return; } @@ -4815,11 +4819,11 @@ void VisualShaderNodeFloatUniform::set_step(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_step() const { +float VisualShaderNodeFloatParameter::get_step() const { return hint_range_step; } -void VisualShaderNodeFloatUniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeFloatParameter::set_default_value_enabled(bool p_enabled) { if (default_value_enabled == p_enabled) { return; } @@ -4827,11 +4831,11 @@ void VisualShaderNodeFloatUniform::set_default_value_enabled(bool p_enabled) { emit_changed(); } -bool VisualShaderNodeFloatUniform::is_default_value_enabled() const { +bool VisualShaderNodeFloatParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeFloatUniform::set_default_value(float p_value) { +void VisualShaderNodeFloatParameter::set_default_value(float p_value) { if (Math::is_equal_approx(default_value, p_value)) { return; } @@ -4839,28 +4843,28 @@ void VisualShaderNodeFloatUniform::set_default_value(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_default_value() const { +float VisualShaderNodeFloatParameter::get_default_value() const { return default_value; } -void VisualShaderNodeFloatUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatUniform::set_hint); - ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatUniform::get_hint); +void VisualShaderNodeFloatParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatParameter::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatParameter::get_hint); - ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatUniform::set_min); - ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatUniform::get_min); + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatParameter::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatParameter::get_min); - ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatUniform::set_max); - ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatUniform::get_max); + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatParameter::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatParameter::get_max); - ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatUniform::set_step); - ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatUniform::get_step); + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatParameter::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatParameter::get_step); - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeFloatUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeFloatUniform::is_default_value_enabled); + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeFloatParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeFloatParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeFloatUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeFloatUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeFloatParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeFloatParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min"), "set_min", "get_min"); @@ -4875,16 +4879,16 @@ void VisualShaderNodeFloatUniform::_bind_methods() { BIND_ENUM_CONSTANT(HINT_MAX); } -bool VisualShaderNodeFloatUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeFloatParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeFloatUniform::is_convertible_to_constant() const { +bool VisualShaderNodeFloatParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeFloatParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("hint"); if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { props.push_back("min"); @@ -4900,47 +4904,47 @@ Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const return props; } -VisualShaderNodeFloatUniform::VisualShaderNodeFloatUniform() { +VisualShaderNodeFloatParameter::VisualShaderNodeFloatParameter() { } -////////////// Integer Uniform +////////////// Integer Parametet -String VisualShaderNodeIntUniform::get_caption() const { - return "IntUniform"; +String VisualShaderNodeIntParameter::get_caption() const { + return "IntParameter"; } -int VisualShaderNodeIntUniform::get_input_port_count() const { +int VisualShaderNodeIntParameter::get_input_port_count() const { return 0; } -VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_input_port_type(int p_port) const { +VisualShaderNodeIntParameter::PortType VisualShaderNodeIntParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR_INT; } -String VisualShaderNodeIntUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeIntParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeIntUniform::get_output_port_count() const { +int VisualShaderNodeIntParameter::get_output_port_count() const { return 1; } -VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_output_port_type(int p_port) const { +VisualShaderNodeIntParameter::PortType VisualShaderNodeIntParameter::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR_INT; } -String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeIntParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeIntParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = ""; if (hint == HINT_RANGE) { - code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")"; + code += _get_qual_str() + "uniform int " + get_parameter_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { - code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ", " + itos(hint_range_step) + ")"; + code += _get_qual_str() + "uniform int " + get_parameter_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ", " + itos(hint_range_step) + ")"; } else { - code += _get_qual_str() + "uniform int " + get_uniform_name(); + code += _get_qual_str() + "uniform int " + get_parameter_name(); } if (default_value_enabled) { code += " = " + itos(default_value); @@ -4949,19 +4953,19 @@ String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualSh return code; } -String VisualShaderNodeIntUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeIntParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeIntUniform::is_show_prop_names() const { +bool VisualShaderNodeIntParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeIntUniform::is_use_prop_slots() const { +bool VisualShaderNodeIntParameter::is_use_prop_slots() const { return true; } -void VisualShaderNodeIntUniform::set_hint(Hint p_hint) { +void VisualShaderNodeIntParameter::set_hint(Hint p_hint) { ERR_FAIL_INDEX(int(p_hint), int(HINT_MAX)); if (hint == p_hint) { return; @@ -4970,11 +4974,11 @@ void VisualShaderNodeIntUniform::set_hint(Hint p_hint) { emit_changed(); } -VisualShaderNodeIntUniform::Hint VisualShaderNodeIntUniform::get_hint() const { +VisualShaderNodeIntParameter::Hint VisualShaderNodeIntParameter::get_hint() const { return hint; } -void VisualShaderNodeIntUniform::set_min(int p_value) { +void VisualShaderNodeIntParameter::set_min(int p_value) { if (hint_range_min == p_value) { return; } @@ -4982,11 +4986,11 @@ void VisualShaderNodeIntUniform::set_min(int p_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_min() const { +int VisualShaderNodeIntParameter::get_min() const { return hint_range_min; } -void VisualShaderNodeIntUniform::set_max(int p_value) { +void VisualShaderNodeIntParameter::set_max(int p_value) { if (hint_range_max == p_value) { return; } @@ -4994,11 +4998,11 @@ void VisualShaderNodeIntUniform::set_max(int p_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_max() const { +int VisualShaderNodeIntParameter::get_max() const { return hint_range_max; } -void VisualShaderNodeIntUniform::set_step(int p_value) { +void VisualShaderNodeIntParameter::set_step(int p_value) { if (hint_range_step == p_value) { return; } @@ -5006,11 +5010,11 @@ void VisualShaderNodeIntUniform::set_step(int p_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_step() const { +int VisualShaderNodeIntParameter::get_step() const { return hint_range_step; } -void VisualShaderNodeIntUniform::set_default_value_enabled(bool p_default_value_enabled) { +void VisualShaderNodeIntParameter::set_default_value_enabled(bool p_default_value_enabled) { if (default_value_enabled == p_default_value_enabled) { return; } @@ -5018,11 +5022,11 @@ void VisualShaderNodeIntUniform::set_default_value_enabled(bool p_default_value_ emit_changed(); } -bool VisualShaderNodeIntUniform::is_default_value_enabled() const { +bool VisualShaderNodeIntParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeIntUniform::set_default_value(int p_default_value) { +void VisualShaderNodeIntParameter::set_default_value(int p_default_value) { if (default_value == p_default_value) { return; } @@ -5030,28 +5034,28 @@ void VisualShaderNodeIntUniform::set_default_value(int p_default_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_default_value() const { +int VisualShaderNodeIntParameter::get_default_value() const { return default_value; } -void VisualShaderNodeIntUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntUniform::set_hint); - ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntUniform::get_hint); +void VisualShaderNodeIntParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntParameter::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntParameter::get_hint); - ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntUniform::set_min); - ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntUniform::get_min); + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntParameter::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntParameter::get_min); - ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntUniform::set_max); - ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntUniform::get_max); + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntParameter::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntParameter::get_max); - ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntUniform::set_step); - ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntUniform::get_step); + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntParameter::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntParameter::get_step); - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeIntUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeIntUniform::is_default_value_enabled); + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeIntParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeIntParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range + Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); @@ -5066,16 +5070,16 @@ void VisualShaderNodeIntUniform::_bind_methods() { BIND_ENUM_CONSTANT(HINT_MAX); } -bool VisualShaderNodeIntUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeIntParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeIntUniform::is_convertible_to_constant() const { +bool VisualShaderNodeIntParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeIntParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("hint"); if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { props.push_back("min"); @@ -5091,40 +5095,40 @@ Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { return props; } -VisualShaderNodeIntUniform::VisualShaderNodeIntUniform() { +VisualShaderNodeIntParameter::VisualShaderNodeIntParameter() { } -////////////// Boolean Uniform +////////////// Boolean Parameter -String VisualShaderNodeBooleanUniform::get_caption() const { - return "BooleanUniform"; +String VisualShaderNodeBooleanParameter::get_caption() const { + return "BooleanParameter"; } -int VisualShaderNodeBooleanUniform::get_input_port_count() const { +int VisualShaderNodeBooleanParameter::get_input_port_count() const { return 0; } -VisualShaderNodeBooleanUniform::PortType VisualShaderNodeBooleanUniform::get_input_port_type(int p_port) const { +VisualShaderNodeBooleanParameter::PortType VisualShaderNodeBooleanParameter::get_input_port_type(int p_port) const { return PORT_TYPE_BOOLEAN; } -String VisualShaderNodeBooleanUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeBooleanParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeBooleanUniform::get_output_port_count() const { +int VisualShaderNodeBooleanParameter::get_output_port_count() const { return 1; } -VisualShaderNodeBooleanUniform::PortType VisualShaderNodeBooleanUniform::get_output_port_type(int p_port) const { +VisualShaderNodeBooleanParameter::PortType VisualShaderNodeBooleanParameter::get_output_port_type(int p_port) const { return PORT_TYPE_BOOLEAN; } -String VisualShaderNodeBooleanUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeBooleanParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -void VisualShaderNodeBooleanUniform::set_default_value_enabled(bool p_default_value_enabled) { +void VisualShaderNodeBooleanParameter::set_default_value_enabled(bool p_default_value_enabled) { if (default_value_enabled == p_default_value_enabled) { return; } @@ -5132,11 +5136,11 @@ void VisualShaderNodeBooleanUniform::set_default_value_enabled(bool p_default_va emit_changed(); } -bool VisualShaderNodeBooleanUniform::is_default_value_enabled() const { +bool VisualShaderNodeBooleanParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeBooleanUniform::set_default_value(bool p_default_value) { +void VisualShaderNodeBooleanParameter::set_default_value(bool p_default_value) { if (default_value == p_default_value) { return; } @@ -5144,12 +5148,12 @@ void VisualShaderNodeBooleanUniform::set_default_value(bool p_default_value) { emit_changed(); } -bool VisualShaderNodeBooleanUniform::get_default_value() const { +bool VisualShaderNodeBooleanParameter::get_default_value() const { return default_value; } -String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform bool " + get_uniform_name(); +String VisualShaderNodeBooleanParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform bool " + get_parameter_name(); if (default_value_enabled) { if (default_value) { code += " = true"; @@ -5161,39 +5165,39 @@ String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, Visu return code; } -String VisualShaderNodeBooleanUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeBooleanParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeBooleanUniform::is_show_prop_names() const { +bool VisualShaderNodeBooleanParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeBooleanUniform::is_use_prop_slots() const { +bool VisualShaderNodeBooleanParameter::is_use_prop_slots() const { return true; } -void VisualShaderNodeBooleanUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanUniform::is_default_value_enabled); +void VisualShaderNodeBooleanParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeBooleanParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeBooleanUniform::is_convertible_to_constant() const { +bool VisualShaderNodeBooleanParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeBooleanParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5201,47 +5205,47 @@ Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() con return props; } -VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() { +VisualShaderNodeBooleanParameter::VisualShaderNodeBooleanParameter() { } -////////////// Color Uniform +////////////// Color Parameter -String VisualShaderNodeColorUniform::get_caption() const { - return "ColorUniform"; +String VisualShaderNodeColorParameter::get_caption() const { + return "ColorParameter"; } -int VisualShaderNodeColorUniform::get_input_port_count() const { +int VisualShaderNodeColorParameter::get_input_port_count() const { return 0; } -VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_input_port_type(int p_port) const { +VisualShaderNodeColorParameter::PortType VisualShaderNodeColorParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeColorParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeColorUniform::get_output_port_count() const { +int VisualShaderNodeColorParameter::get_output_port_count() const { return 1; } -VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_output_port_type(int p_port) const { +VisualShaderNodeColorParameter::PortType VisualShaderNodeColorParameter::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR_4D : PORT_TYPE_SCALAR; } -String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeColorParameter::get_output_port_name(int p_port) const { return "color"; } -bool VisualShaderNodeColorUniform::is_output_port_expandable(int p_port) const { +bool VisualShaderNodeColorParameter::is_output_port_expandable(int p_port) const { if (p_port == 0) { return true; } return false; } -void VisualShaderNodeColorUniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeColorParameter::set_default_value_enabled(bool p_enabled) { if (default_value_enabled == p_enabled) { return; } @@ -5249,11 +5253,11 @@ void VisualShaderNodeColorUniform::set_default_value_enabled(bool p_enabled) { emit_changed(); } -bool VisualShaderNodeColorUniform::is_default_value_enabled() const { +bool VisualShaderNodeColorParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeColorUniform::set_default_value(const Color &p_value) { +void VisualShaderNodeColorParameter::set_default_value(const Color &p_value) { if (default_value.is_equal_approx(p_value)) { return; } @@ -5261,12 +5265,12 @@ void VisualShaderNodeColorUniform::set_default_value(const Color &p_value) { emit_changed(); } -Color VisualShaderNodeColorUniform::get_default_value() const { +Color VisualShaderNodeColorParameter::get_default_value() const { return default_value; } -String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec4 " + get_uniform_name() + " : source_color"; +String VisualShaderNodeColorParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec4 " + get_parameter_name() + " : source_color"; if (default_value_enabled) { code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.r, default_value.g, default_value.b, default_value.a); } @@ -5274,35 +5278,35 @@ String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, Visual return code; } -String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeColorParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeColorUniform::is_show_prop_names() const { +bool VisualShaderNodeColorParameter::is_show_prop_names() const { return true; } -void VisualShaderNodeColorUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorUniform::is_default_value_enabled); +void VisualShaderNodeColorParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeColorParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeColorUniform::is_convertible_to_constant() const { +bool VisualShaderNodeColorParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeColorParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5310,59 +5314,59 @@ Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const return props; } -VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() { +VisualShaderNodeColorParameter::VisualShaderNodeColorParameter() { } -////////////// Vector2 Uniform +////////////// Vector2 Parameter -String VisualShaderNodeVec2Uniform::get_caption() const { - return "Vector2Uniform"; +String VisualShaderNodeVec2Parameter::get_caption() const { + return "Vector2Parameter"; } -int VisualShaderNodeVec2Uniform::get_input_port_count() const { +int VisualShaderNodeVec2Parameter::get_input_port_count() const { return 0; } -VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_input_port_type(int p_port) const { +VisualShaderNodeVec2Parameter::PortType VisualShaderNodeVec2Parameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_2D; } -String VisualShaderNodeVec2Uniform::get_input_port_name(int p_port) const { +String VisualShaderNodeVec2Parameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeVec2Uniform::get_output_port_count() const { +int VisualShaderNodeVec2Parameter::get_output_port_count() const { return 1; } -VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_output_port_type(int p_port) const { +VisualShaderNodeVec2Parameter::PortType VisualShaderNodeVec2Parameter::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR_2D; } -String VisualShaderNodeVec2Uniform::get_output_port_name(int p_port) const { +String VisualShaderNodeVec2Parameter::get_output_port_name(int p_port) const { return String(); } -void VisualShaderNodeVec2Uniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeVec2Parameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeVec2Uniform::is_default_value_enabled() const { +bool VisualShaderNodeVec2Parameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeVec2Uniform::set_default_value(const Vector2 &p_value) { +void VisualShaderNodeVec2Parameter::set_default_value(const Vector2 &p_value) { default_value = p_value; emit_changed(); } -Vector2 VisualShaderNodeVec2Uniform::get_default_value() const { +Vector2 VisualShaderNodeVec2Parameter::get_default_value() const { return default_value; } -String VisualShaderNodeVec2Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec2 " + get_uniform_name(); +String VisualShaderNodeVec2Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec2 " + get_parameter_name(); if (default_value_enabled) { code += vformat(" = vec2(%.6f, %.6f)", default_value.x, default_value.y); } @@ -5370,39 +5374,39 @@ String VisualShaderNodeVec2Uniform::generate_global(Shader::Mode p_mode, VisualS return code; } -String VisualShaderNodeVec2Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeVec2Parameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeVec2Uniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec2Uniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec2Uniform::is_default_value_enabled); +void VisualShaderNodeVec2Parameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec2Parameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec2Parameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec2Uniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec2Uniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec2Parameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec2Parameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeVec2Uniform::is_show_prop_names() const { +bool VisualShaderNodeVec2Parameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeVec2Uniform::is_use_prop_slots() const { +bool VisualShaderNodeVec2Parameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeVec2Uniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeVec2Parameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeVec2Uniform::is_convertible_to_constant() const { +bool VisualShaderNodeVec2Parameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeVec2Uniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeVec2Parameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5410,59 +5414,59 @@ Vector<StringName> VisualShaderNodeVec2Uniform::get_editable_properties() const return props; } -VisualShaderNodeVec2Uniform::VisualShaderNodeVec2Uniform() { +VisualShaderNodeVec2Parameter::VisualShaderNodeVec2Parameter() { } -////////////// Vector3 Uniform +////////////// Vector3 Parameter -String VisualShaderNodeVec3Uniform::get_caption() const { - return "Vector3Uniform"; +String VisualShaderNodeVec3Parameter::get_caption() const { + return "Vector3Parameter"; } -int VisualShaderNodeVec3Uniform::get_input_port_count() const { +int VisualShaderNodeVec3Parameter::get_input_port_count() const { return 0; } -VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_input_port_type(int p_port) const { +VisualShaderNodeVec3Parameter::PortType VisualShaderNodeVec3Parameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_3D; } -String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const { +String VisualShaderNodeVec3Parameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeVec3Uniform::get_output_port_count() const { +int VisualShaderNodeVec3Parameter::get_output_port_count() const { return 1; } -VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_output_port_type(int p_port) const { +VisualShaderNodeVec3Parameter::PortType VisualShaderNodeVec3Parameter::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR_3D; } -String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const { +String VisualShaderNodeVec3Parameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -void VisualShaderNodeVec3Uniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeVec3Parameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeVec3Uniform::is_default_value_enabled() const { +bool VisualShaderNodeVec3Parameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeVec3Uniform::set_default_value(const Vector3 &p_value) { +void VisualShaderNodeVec3Parameter::set_default_value(const Vector3 &p_value) { default_value = p_value; emit_changed(); } -Vector3 VisualShaderNodeVec3Uniform::get_default_value() const { +Vector3 VisualShaderNodeVec3Parameter::get_default_value() const { return default_value; } -String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec3 " + get_uniform_name(); +String VisualShaderNodeVec3Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec3 " + get_parameter_name(); if (default_value_enabled) { code += vformat(" = vec3(%.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z); } @@ -5470,39 +5474,39 @@ String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualS return code; } -String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeVec3Parameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeVec3Uniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Uniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Uniform::is_default_value_enabled); +void VisualShaderNodeVec3Parameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Parameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Parameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Uniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Uniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Parameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Parameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeVec3Uniform::is_show_prop_names() const { +bool VisualShaderNodeVec3Parameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeVec3Uniform::is_use_prop_slots() const { +bool VisualShaderNodeVec3Parameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeVec3Parameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeVec3Uniform::is_convertible_to_constant() const { +bool VisualShaderNodeVec3Parameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeVec3Parameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5510,59 +5514,59 @@ Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const return props; } -VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() { +VisualShaderNodeVec3Parameter::VisualShaderNodeVec3Parameter() { } -////////////// Vector4 Uniform +////////////// Vector4 Parameter -String VisualShaderNodeVec4Uniform::get_caption() const { - return "Vector4Uniform"; +String VisualShaderNodeVec4Parameter::get_caption() const { + return "Vector4Parameter"; } -int VisualShaderNodeVec4Uniform::get_input_port_count() const { +int VisualShaderNodeVec4Parameter::get_input_port_count() const { return 0; } -VisualShaderNodeVec4Uniform::PortType VisualShaderNodeVec4Uniform::get_input_port_type(int p_port) const { +VisualShaderNodeVec4Parameter::PortType VisualShaderNodeVec4Parameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_4D; } -String VisualShaderNodeVec4Uniform::get_input_port_name(int p_port) const { +String VisualShaderNodeVec4Parameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeVec4Uniform::get_output_port_count() const { +int VisualShaderNodeVec4Parameter::get_output_port_count() const { return 1; } -VisualShaderNodeVec4Uniform::PortType VisualShaderNodeVec4Uniform::get_output_port_type(int p_port) const { +VisualShaderNodeVec4Parameter::PortType VisualShaderNodeVec4Parameter::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR_4D; } -String VisualShaderNodeVec4Uniform::get_output_port_name(int p_port) const { +String VisualShaderNodeVec4Parameter::get_output_port_name(int p_port) const { return ""; // No output port means the editor will be used as port. } -void VisualShaderNodeVec4Uniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeVec4Parameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeVec4Uniform::is_default_value_enabled() const { +bool VisualShaderNodeVec4Parameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeVec4Uniform::set_default_value(const Quaternion &p_value) { +void VisualShaderNodeVec4Parameter::set_default_value(const Vector4 &p_value) { default_value = p_value; emit_changed(); } -Quaternion VisualShaderNodeVec4Uniform::get_default_value() const { +Vector4 VisualShaderNodeVec4Parameter::get_default_value() const { return default_value; } -String VisualShaderNodeVec4Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec4 " + get_uniform_name(); +String VisualShaderNodeVec4Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec4 " + get_parameter_name(); if (default_value_enabled) { code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z, default_value.w); } @@ -5570,39 +5574,39 @@ String VisualShaderNodeVec4Uniform::generate_global(Shader::Mode p_mode, VisualS return code; } -String VisualShaderNodeVec4Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeVec4Parameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeVec4Uniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec4Uniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec4Uniform::is_default_value_enabled); +void VisualShaderNodeVec4Parameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec4Parameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec4Parameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec4Uniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec4Uniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec4Parameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec4Parameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "default_value"), "set_default_value", "get_default_value"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR4, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeVec4Uniform::is_show_prop_names() const { +bool VisualShaderNodeVec4Parameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeVec4Uniform::is_use_prop_slots() const { +bool VisualShaderNodeVec4Parameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeVec4Uniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeVec4Parameter::is_qualifier_supported(Qualifier p_qual) const { return true; // All qualifiers are supported. } -bool VisualShaderNodeVec4Uniform::is_convertible_to_constant() const { +bool VisualShaderNodeVec4Parameter::is_convertible_to_constant() const { return true; // Conversion is allowed. } -Vector<StringName> VisualShaderNodeVec4Uniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeVec4Parameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5610,59 +5614,59 @@ Vector<StringName> VisualShaderNodeVec4Uniform::get_editable_properties() const return props; } -VisualShaderNodeVec4Uniform::VisualShaderNodeVec4Uniform() { +VisualShaderNodeVec4Parameter::VisualShaderNodeVec4Parameter() { } -////////////// Transform Uniform +////////////// Transform Parameter -String VisualShaderNodeTransformUniform::get_caption() const { - return "TransformUniform"; +String VisualShaderNodeTransformParameter::get_caption() const { + return "TransformParameter"; } -int VisualShaderNodeTransformUniform::get_input_port_count() const { +int VisualShaderNodeTransformParameter::get_input_port_count() const { return 0; } -VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_input_port_type(int p_port) const { +VisualShaderNodeTransformParameter::PortType VisualShaderNodeTransformParameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_3D; } -String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeTransformParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeTransformUniform::get_output_port_count() const { +int VisualShaderNodeTransformParameter::get_output_port_count() const { return 1; } -VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_output_port_type(int p_port) const { +VisualShaderNodeTransformParameter::PortType VisualShaderNodeTransformParameter::get_output_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } -String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeTransformParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -void VisualShaderNodeTransformUniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeTransformParameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeTransformUniform::is_default_value_enabled() const { +bool VisualShaderNodeTransformParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeTransformUniform::set_default_value(const Transform3D &p_value) { +void VisualShaderNodeTransformParameter::set_default_value(const Transform3D &p_value) { default_value = p_value; emit_changed(); } -Transform3D VisualShaderNodeTransformUniform::get_default_value() const { +Transform3D VisualShaderNodeTransformParameter::get_default_value() const { return default_value; } -String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform mat4 " + get_uniform_name(); +String VisualShaderNodeTransformParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform mat4 " + get_parameter_name(); if (default_value_enabled) { Vector3 row0 = default_value.basis.rows[0]; Vector3 row1 = default_value.basis.rows[1]; @@ -5674,42 +5678,42 @@ String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, Vi return code; } -String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeTransformParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeTransformUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformUniform::is_default_value_enabled); +void VisualShaderNodeTransformParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeTransformUniform::is_show_prop_names() const { +bool VisualShaderNodeTransformParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeTransformUniform::is_use_prop_slots() const { +bool VisualShaderNodeTransformParameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeTransformParameter::is_qualifier_supported(Qualifier p_qual) const { if (p_qual == Qualifier::QUAL_INSTANCE) { return false; } return true; } -bool VisualShaderNodeTransformUniform::is_convertible_to_constant() const { +bool VisualShaderNodeTransformParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeTransformParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5717,12 +5721,12 @@ Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() c return props; } -VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() { +VisualShaderNodeTransformParameter::VisualShaderNodeTransformParameter() { } ////////////// -String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_type, VisualShaderNodeTextureUniform::ColorDefault p_color_default, VisualShaderNodeTextureUniform::TextureFilter p_texture_filter, VisualShaderNodeTextureUniform::TextureRepeat p_texture_repeat) { +String get_sampler_hint(VisualShaderNodeTextureParameter::TextureType p_texture_type, VisualShaderNodeTextureParameter::ColorDefault p_color_default, VisualShaderNodeTextureParameter::TextureFilter p_texture_filter, VisualShaderNodeTextureParameter::TextureRepeat p_texture_repeat) { String code; bool has_colon = false; @@ -5731,25 +5735,25 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty String type_code; switch (p_texture_type) { - case VisualShaderNodeTextureUniform::TYPE_DATA: - if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { + case VisualShaderNodeTextureParameter::TYPE_DATA: + if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_BLACK) { type_code = "hint_default_black"; - } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + } else if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_TRANSPARENT) { type_code = "hint_default_transparent"; } break; - case VisualShaderNodeTextureUniform::TYPE_COLOR: + case VisualShaderNodeTextureParameter::TYPE_COLOR: type_code = "source_color"; - if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { + if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_BLACK) { type_code += ", hint_default_black"; - } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + } else if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_TRANSPARENT) { type_code += ", hint_default_transparent"; } break; - case VisualShaderNodeTextureUniform::TYPE_NORMAL_MAP: + case VisualShaderNodeTextureParameter::TYPE_NORMAL_MAP: type_code = "hint_normal"; break; - case VisualShaderNodeTextureUniform::TYPE_ANISOTROPY: + case VisualShaderNodeTextureParameter::TYPE_ANISOTROPY: type_code = "hint_anisotropy"; break; default: @@ -5767,22 +5771,22 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty String filter_code; switch (p_texture_filter) { - case VisualShaderNodeTextureUniform::FILTER_NEAREST: + case VisualShaderNodeTextureParameter::FILTER_NEAREST: filter_code = "filter_nearest"; break; - case VisualShaderNodeTextureUniform::FILTER_LINEAR: + case VisualShaderNodeTextureParameter::FILTER_LINEAR: filter_code = "filter_linear"; break; - case VisualShaderNodeTextureUniform::FILTER_NEAREST_MIPMAP: + case VisualShaderNodeTextureParameter::FILTER_NEAREST_MIPMAP: filter_code = "filter_nearest_mipmap"; break; - case VisualShaderNodeTextureUniform::FILTER_LINEAR_MIPMAP: + case VisualShaderNodeTextureParameter::FILTER_LINEAR_MIPMAP: filter_code = "filter_linear_mipmap"; break; - case VisualShaderNodeTextureUniform::FILTER_NEAREST_MIPMAP_ANISOTROPIC: + case VisualShaderNodeTextureParameter::FILTER_NEAREST_MIPMAP_ANISOTROPIC: filter_code = "filter_nearest_mipmap_anisotropic"; break; - case VisualShaderNodeTextureUniform::FILTER_LINEAR_MIPMAP_ANISOTROPIC: + case VisualShaderNodeTextureParameter::FILTER_LINEAR_MIPMAP_ANISOTROPIC: filter_code = "filter_linear_mipmap_anisotropic"; break; default: @@ -5805,10 +5809,10 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty String repeat_code; switch (p_texture_repeat) { - case VisualShaderNodeTextureUniform::REPEAT_ENABLED: + case VisualShaderNodeTextureParameter::REPEAT_ENABLED: repeat_code = "repeat_enable"; break; - case VisualShaderNodeTextureUniform::REPEAT_DISABLED: + case VisualShaderNodeTextureParameter::REPEAT_DISABLED: repeat_code = "repeat_disable"; break; default: @@ -5828,29 +5832,25 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty return code; } -////////////// Texture Uniform +////////////// Texture Parameter -String VisualShaderNodeTextureUniform::get_caption() const { - return "TextureUniform"; -} - -int VisualShaderNodeTextureUniform::get_input_port_count() const { +int VisualShaderNodeTextureParameter::get_input_port_count() const { return 0; } -VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const { +VisualShaderNodeTextureParameter::PortType VisualShaderNodeTextureParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeTextureParameter::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeTextureUniform::get_output_port_count() const { +int VisualShaderNodeTextureParameter::get_output_port_count() const { return 1; } -VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const { +VisualShaderNodeTextureParameter::PortType VisualShaderNodeTextureParameter::get_output_port_type(int p_port) const { switch (p_port) { case 0: return PORT_TYPE_SAMPLER; @@ -5859,27 +5859,11 @@ VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_out } } -String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { - switch (p_port) { - case 0: - return "sampler2D"; - default: - return ""; - } -} - -String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform sampler2D " + get_uniform_name(); - code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); - code += ";\n"; - return code; -} - -String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { +String VisualShaderNodeTextureParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return ""; } -void VisualShaderNodeTextureUniform::set_texture_type(TextureType p_texture_type) { +void VisualShaderNodeTextureParameter::set_texture_type(TextureType p_texture_type) { ERR_FAIL_INDEX(int(p_texture_type), int(TYPE_MAX)); if (texture_type == p_texture_type) { return; @@ -5888,11 +5872,11 @@ void VisualShaderNodeTextureUniform::set_texture_type(TextureType p_texture_type emit_changed(); } -VisualShaderNodeTextureUniform::TextureType VisualShaderNodeTextureUniform::get_texture_type() const { +VisualShaderNodeTextureParameter::TextureType VisualShaderNodeTextureParameter::get_texture_type() const { return texture_type; } -void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_color_default) { +void VisualShaderNodeTextureParameter::set_color_default(ColorDefault p_color_default) { ERR_FAIL_INDEX(int(p_color_default), int(COLOR_DEFAULT_MAX)); if (color_default == p_color_default) { return; @@ -5901,11 +5885,11 @@ void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_color_defa emit_changed(); } -VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get_color_default() const { +VisualShaderNodeTextureParameter::ColorDefault VisualShaderNodeTextureParameter::get_color_default() const { return color_default; } -void VisualShaderNodeTextureUniform::set_texture_filter(TextureFilter p_filter) { +void VisualShaderNodeTextureParameter::set_texture_filter(TextureFilter p_filter) { ERR_FAIL_INDEX(int(p_filter), int(FILTER_MAX)); if (texture_filter == p_filter) { return; @@ -5914,11 +5898,11 @@ void VisualShaderNodeTextureUniform::set_texture_filter(TextureFilter p_filter) emit_changed(); } -VisualShaderNodeTextureUniform::TextureFilter VisualShaderNodeTextureUniform::get_texture_filter() const { +VisualShaderNodeTextureParameter::TextureFilter VisualShaderNodeTextureParameter::get_texture_filter() const { return texture_filter; } -void VisualShaderNodeTextureUniform::set_texture_repeat(TextureRepeat p_repeat) { +void VisualShaderNodeTextureParameter::set_texture_repeat(TextureRepeat p_repeat) { ERR_FAIL_INDEX(int(p_repeat), int(REPEAT_MAX)); if (texture_repeat == p_repeat) { return; @@ -5927,12 +5911,12 @@ void VisualShaderNodeTextureUniform::set_texture_repeat(TextureRepeat p_repeat) emit_changed(); } -VisualShaderNodeTextureUniform::TextureRepeat VisualShaderNodeTextureUniform::get_texture_repeat() const { +VisualShaderNodeTextureParameter::TextureRepeat VisualShaderNodeTextureParameter::get_texture_repeat() const { return texture_repeat; } -Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeTextureParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("texture_type"); if (texture_type == TYPE_DATA || texture_type == TYPE_COLOR) { props.push_back("color_default"); @@ -5942,11 +5926,11 @@ Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() con return props; } -bool VisualShaderNodeTextureUniform::is_show_prop_names() const { +bool VisualShaderNodeTextureParameter::is_show_prop_names() const { return true; } -HashMap<StringName, String> VisualShaderNodeTextureUniform::get_editable_properties_names() const { +HashMap<StringName, String> VisualShaderNodeTextureParameter::get_editable_properties_names() const { HashMap<StringName, String> names; names.insert("texture_type", RTR("Type")); names.insert("color_default", RTR("Default Color")); @@ -5955,18 +5939,18 @@ HashMap<StringName, String> VisualShaderNodeTextureUniform::get_editable_propert return names; } -void VisualShaderNodeTextureUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureUniform::set_texture_type); - ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureUniform::get_texture_type); +void VisualShaderNodeTextureParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureParameter::set_texture_type); + ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureParameter::get_texture_type); - ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureUniform::set_color_default); - ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureUniform::get_color_default); + ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureParameter::set_color_default); + ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureParameter::get_color_default); - ClassDB::bind_method(D_METHOD("set_texture_filter", "filter"), &VisualShaderNodeTextureUniform::set_texture_filter); - ClassDB::bind_method(D_METHOD("get_texture_filter"), &VisualShaderNodeTextureUniform::get_texture_filter); + ClassDB::bind_method(D_METHOD("set_texture_filter", "filter"), &VisualShaderNodeTextureParameter::set_texture_filter); + ClassDB::bind_method(D_METHOD("get_texture_filter"), &VisualShaderNodeTextureParameter::get_texture_filter); - ClassDB::bind_method(D_METHOD("set_texture_repeat", "type"), &VisualShaderNodeTextureUniform::set_texture_repeat); - ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::get_texture_repeat); + ClassDB::bind_method(D_METHOD("set_texture_repeat", "type"), &VisualShaderNodeTextureParameter::set_texture_repeat); + ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureParameter::get_texture_repeat); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default"); @@ -5999,7 +5983,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { BIND_ENUM_CONSTANT(REPEAT_MAX); } -bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeTextureParameter::is_qualifier_supported(Qualifier p_qual) const { switch (p_qual) { case Qualifier::QUAL_NONE: return true; @@ -6013,31 +5997,56 @@ bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) co return false; } -bool VisualShaderNodeTextureUniform::is_convertible_to_constant() const { +bool VisualShaderNodeTextureParameter::is_convertible_to_constant() const { return false; // conversion is not allowed } -VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { +VisualShaderNodeTextureParameter::VisualShaderNodeTextureParameter() { +} + +////////////// Texture2D Parameter + +String VisualShaderNodeTexture2DParameter::get_caption() const { + return "Texture2DParameter"; +} + +String VisualShaderNodeTexture2DParameter::get_output_port_name(int p_port) const { + switch (p_port) { + case 0: + return "sampler2D"; + default: + return ""; + } +} + +String VisualShaderNodeTexture2DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name(); + code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); + code += ";\n"; + return code; +} + +VisualShaderNodeTexture2DParameter::VisualShaderNodeTexture2DParameter() { } -////////////// Texture Uniform (Triplanar) +////////////// Texture Parameter (Triplanar) -String VisualShaderNodeTextureUniformTriplanar::get_caption() const { +String VisualShaderNodeTextureParameterTriplanar::get_caption() const { return "TextureUniformTriplanar"; } -int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { +int VisualShaderNodeTextureParameterTriplanar::get_input_port_count() const { return 2; } -VisualShaderNodeTextureUniformTriplanar::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { +VisualShaderNodeTextureParameterTriplanar::PortType VisualShaderNodeTextureParameterTriplanar::get_input_port_type(int p_port) const { if (p_port == 0 || p_port == 1) { return PORT_TYPE_VECTOR_3D; } return PORT_TYPE_SCALAR; } -String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) const { +String VisualShaderNodeTextureParameterTriplanar::get_input_port_name(int p_port) const { if (p_port == 0) { return "weights"; } else if (p_port == 1) { @@ -6046,11 +6055,11 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) return ""; } -int VisualShaderNodeTextureUniformTriplanar::get_output_port_count() const { +int VisualShaderNodeTextureParameterTriplanar::get_output_port_count() const { return 2; } -VisualShaderNodeTextureUniformTriplanar::PortType VisualShaderNodeTextureUniformTriplanar::get_output_port_type(int p_port) const { +VisualShaderNodeTextureParameterTriplanar::PortType VisualShaderNodeTextureParameterTriplanar::get_output_port_type(int p_port) const { switch (p_port) { case 0: return PORT_TYPE_VECTOR_4D; @@ -6061,7 +6070,7 @@ VisualShaderNodeTextureUniformTriplanar::PortType VisualShaderNodeTextureUniform } } -String VisualShaderNodeTextureUniformTriplanar::get_output_port_name(int p_port) const { +String VisualShaderNodeTextureParameterTriplanar::get_output_port_name(int p_port) const { switch (p_port) { case 0: return "color"; @@ -6072,7 +6081,7 @@ String VisualShaderNodeTextureUniformTriplanar::get_output_port_name(int p_port) } } -String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { +String VisualShaderNodeTextureParameterTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; code += "// " + get_caption() + "\n"; @@ -6094,7 +6103,7 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader: return code; } -String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeTextureParameterTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code; if (p_type == VisualShader::TYPE_VERTEX) { @@ -6110,8 +6119,15 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader: return code; } -String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - String id = get_uniform_name(); +String VisualShaderNodeTextureParameterTriplanar::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name(); + code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); + code += ";\n"; + return code; +} + +String VisualShaderNodeTextureParameterTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String id = get_parameter_name(); String code; if (p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) { @@ -6127,7 +6143,7 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod return code; } -bool VisualShaderNodeTextureUniformTriplanar::is_input_port_default(int p_port, Shader::Mode p_mode) const { +bool VisualShaderNodeTextureParameterTriplanar::is_input_port_default(int p_port, Shader::Mode p_mode) const { if (p_port == 0) { return true; } else if (p_port == 1) { @@ -6136,79 +6152,67 @@ bool VisualShaderNodeTextureUniformTriplanar::is_input_port_default(int p_port, return false; } -VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { +VisualShaderNodeTextureParameterTriplanar::VisualShaderNodeTextureParameterTriplanar() { } -////////////// Texture2DArray Uniform +////////////// Texture2DArray Parameter -String VisualShaderNodeTexture2DArrayUniform::get_caption() const { - return "Texture2DArrayUniform"; +String VisualShaderNodeTexture2DArrayParameter::get_caption() const { + return "Texture2DArrayParameter"; } -String VisualShaderNodeTexture2DArrayUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeTexture2DArrayParameter::get_output_port_name(int p_port) const { return "sampler2DArray"; } -String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform sampler2DArray " + get_uniform_name(); +String VisualShaderNodeTexture2DArrayParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler2DArray " + get_parameter_name(); code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); code += ";\n"; return code; } -String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return String(); -} - -VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() { +VisualShaderNodeTexture2DArrayParameter::VisualShaderNodeTexture2DArrayParameter() { } -////////////// Texture3D Uniform +////////////// Texture3D Parameter -String VisualShaderNodeTexture3DUniform::get_caption() const { - return "Texture3DUniform"; +String VisualShaderNodeTexture3DParameter::get_caption() const { + return "Texture3DParameter"; } -String VisualShaderNodeTexture3DUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeTexture3DParameter::get_output_port_name(int p_port) const { return "sampler3D"; } -String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform sampler3D " + get_uniform_name(); +String VisualShaderNodeTexture3DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler3D " + get_parameter_name(); code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); code += ";\n"; return code; } -String VisualShaderNodeTexture3DUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return String(); +VisualShaderNodeTexture3DParameter::VisualShaderNodeTexture3DParameter() { } -VisualShaderNodeTexture3DUniform::VisualShaderNodeTexture3DUniform() { -} +////////////// Cubemap Parameter -////////////// Cubemap Uniform - -String VisualShaderNodeCubemapUniform::get_caption() const { - return "CubemapUniform"; +String VisualShaderNodeCubemapParameter::get_caption() const { + return "CubemapParameter"; } -String VisualShaderNodeCubemapUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeCubemapParameter::get_output_port_name(int p_port) const { return "samplerCube"; } -String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform samplerCube " + get_uniform_name(); +String VisualShaderNodeCubemapParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform samplerCube " + get_parameter_name(); code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); code += ";\n"; return code; } -String VisualShaderNodeCubemapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return String(); -} - -VisualShaderNodeCubemapUniform::VisualShaderNodeCubemapUniform() { +VisualShaderNodeCubemapParameter::VisualShaderNodeCubemapParameter() { } ////////////// If @@ -7201,6 +7205,10 @@ String VisualShaderNodeDistanceFade::get_output_port_name(int p_port) const { return "amount"; } +bool VisualShaderNodeDistanceFade::has_output_port_preview(int p_port) const { + return false; +} + String VisualShaderNodeDistanceFade::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; code += vformat(" %s = clamp(smoothstep(%s, %s,-VERTEX.z),0.0,1.0);\n", p_output_vars[0], p_input_vars[0], p_input_vars[1]); @@ -7242,6 +7250,10 @@ String VisualShaderNodeProximityFade::get_output_port_name(int p_port) const { return "fade"; } +bool VisualShaderNodeProximityFade::has_output_port_preview(int p_port) const { + return false; +} + String VisualShaderNodeProximityFade::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index c603a10eae..4b883c25cc 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -636,6 +636,7 @@ public: virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + virtual bool has_output_port_preview(int p_port) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; @@ -1762,11 +1763,11 @@ public: }; /////////////////////////////////////// -/// UNIFORMS +/// PARAMETERS /////////////////////////////////////// -class VisualShaderNodeFloatUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeFloatUniform, VisualShaderNodeUniform); +class VisualShaderNodeFloatParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeFloatParameter, VisualShaderNodeParameter); public: enum Hint { @@ -1827,13 +1828,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeFloatUniform(); + VisualShaderNodeFloatParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeFloatUniform::Hint) +VARIANT_ENUM_CAST(VisualShaderNodeFloatParameter::Hint) -class VisualShaderNodeIntUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeIntUniform, VisualShaderNodeUniform); +class VisualShaderNodeIntParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeIntParameter, VisualShaderNodeParameter); public: enum Hint { @@ -1894,15 +1895,15 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeIntUniform(); + VisualShaderNodeIntParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeIntUniform::Hint) +VARIANT_ENUM_CAST(VisualShaderNodeIntParameter::Hint) /////////////////////////////////////// -class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeBooleanUniform, VisualShaderNodeUniform); +class VisualShaderNodeBooleanParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeBooleanParameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -1939,13 +1940,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeBooleanUniform(); + VisualShaderNodeBooleanParameter(); }; /////////////////////////////////////// -class VisualShaderNodeColorUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeColorUniform, VisualShaderNodeUniform); +class VisualShaderNodeColorParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeColorParameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -1983,13 +1984,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeColorUniform(); + VisualShaderNodeColorParameter(); }; /////////////////////////////////////// -class VisualShaderNodeVec2Uniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeVec2Uniform, VisualShaderNodeUniform); +class VisualShaderNodeVec2Parameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeVec2Parameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -2026,13 +2027,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeVec2Uniform(); + VisualShaderNodeVec2Parameter(); }; /////////////////////////////////////// -class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform); +class VisualShaderNodeVec3Parameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeVec3Parameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -2069,17 +2070,17 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeVec3Uniform(); + VisualShaderNodeVec3Parameter(); }; /////////////////////////////////////// -class VisualShaderNodeVec4Uniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeVec4Uniform, VisualShaderNodeUniform); +class VisualShaderNodeVec4Parameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeVec4Parameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; - Quaternion default_value; + Vector4 default_value; protected: static void _bind_methods(); @@ -2104,21 +2105,21 @@ public: void set_default_value_enabled(bool p_enabled); bool is_default_value_enabled() const; - void set_default_value(const Quaternion &p_value); - Quaternion get_default_value() const; + void set_default_value(const Vector4 &p_value); + Vector4 get_default_value() const; bool is_qualifier_supported(Qualifier p_qual) const override; bool is_convertible_to_constant() const override; virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeVec4Uniform(); + VisualShaderNodeVec4Parameter(); }; /////////////////////////////////////// -class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeTransformUniform, VisualShaderNodeUniform); +class VisualShaderNodeTransformParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeTransformParameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -2155,13 +2156,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeTransformUniform(); + VisualShaderNodeTransformParameter(); }; /////////////////////////////////////// -class VisualShaderNodeTextureUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeTextureUniform, VisualShaderNodeUniform); +class VisualShaderNodeTextureParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeTextureParameter, VisualShaderNodeParameter); public: enum TextureType { @@ -2207,17 +2208,13 @@ protected: static void _bind_methods(); public: - virtual String get_caption() const override; - virtual int get_input_port_count() const override; virtual PortType get_input_port_type(int p_port) const override; virtual String get_input_port_name(int p_port) const override; virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual HashMap<StringName, String> get_editable_properties_names() const override; @@ -2240,18 +2237,32 @@ public: bool is_qualifier_supported(Qualifier p_qual) const override; bool is_convertible_to_constant() const override; - VisualShaderNodeTextureUniform(); + VisualShaderNodeTextureParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureType) -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::ColorDefault) -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureFilter) -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureRepeat) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureType) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::ColorDefault) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureFilter) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureRepeat) /////////////////////////////////////// -class VisualShaderNodeTextureUniformTriplanar : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeTextureUniformTriplanar, VisualShaderNodeTextureUniform); +class VisualShaderNodeTexture2DParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTexture2DParameter, VisualShaderNodeTextureParameter); + +public: + virtual String get_caption() const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + + VisualShaderNodeTexture2DParameter(); +}; + +/////////////////////////////////////// + +class VisualShaderNodeTextureParameterTriplanar : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTextureParameterTriplanar, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; @@ -2268,54 +2279,52 @@ public: virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeTextureUniformTriplanar(); + VisualShaderNodeTextureParameterTriplanar(); }; /////////////////////////////////////// -class VisualShaderNodeTexture2DArrayUniform : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeTexture2DArrayUniform, VisualShaderNodeTextureUniform); +class VisualShaderNodeTexture2DArrayParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTexture2DArrayParameter, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeTexture2DArrayUniform(); + VisualShaderNodeTexture2DArrayParameter(); }; /////////////////////////////////////// -class VisualShaderNodeTexture3DUniform : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeTexture3DUniform, VisualShaderNodeTextureUniform); +class VisualShaderNodeTexture3DParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTexture3DParameter, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeTexture3DUniform(); + VisualShaderNodeTexture3DParameter(); }; /////////////////////////////////////// -class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform); +class VisualShaderNodeCubemapParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeCubemapParameter, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeCubemapUniform(); + VisualShaderNodeCubemapParameter(); }; /////////////////////////////////////// @@ -2636,6 +2645,7 @@ public: virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + virtual bool has_output_port_preview(int p_port) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; @@ -2655,6 +2665,7 @@ public: virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + virtual bool has_output_port_preview(int p_port) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; diff --git a/scene/theme/theme_owner.cpp b/scene/theme/theme_owner.cpp new file mode 100644 index 0000000000..e89aa1b28d --- /dev/null +++ b/scene/theme/theme_owner.cpp @@ -0,0 +1,410 @@ +/*************************************************************************/ +/* theme_owner.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "theme_owner.h" + +#include "scene/gui/control.h" +#include "scene/main/window.h" +#include "scene/theme/theme_db.h" + +// Theme owner node. + +void ThemeOwner::set_owner_node(Node *p_node) { + owner_control = nullptr; + owner_window = nullptr; + + Control *c = Object::cast_to<Control>(p_node); + if (c) { + owner_control = c; + return; + } + + Window *w = Object::cast_to<Window>(p_node); + if (w) { + owner_window = w; + return; + } +} + +Node *ThemeOwner::get_owner_node() const { + if (owner_control) { + return owner_control; + } else if (owner_window) { + return owner_window; + } + return nullptr; +} + +bool ThemeOwner::has_owner_node() const { + return bool(owner_control || owner_window); +} + +// Theme propagation. + +void ThemeOwner::assign_theme_on_parented(Node *p_for_node) { + // We check if there are any themes affecting the parent. If that's the case + // its children also need to be affected. + // We don't notify here because `NOTIFICATION_THEME_CHANGED` will be handled + // a bit later by `NOTIFICATION_ENTER_TREE`. + + Node *parent = p_for_node->get_parent(); + + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c && parent_c->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, parent_c->get_theme_owner_node(), false, true); + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w && parent_w->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, parent_w->get_theme_owner_node(), false, true); + } + } +} + +void ThemeOwner::clear_theme_on_unparented(Node *p_for_node) { + // We check if there were any themes affecting the parent. If that's the case + // its children need were also affected and need to be updated. + // We don't notify because we're exiting the tree, and it's not important. + + Node *parent = p_for_node->get_parent(); + + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c && parent_c->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, nullptr, false, true); + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w && parent_w->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, nullptr, false, true); + } + } +} + +void ThemeOwner::propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign) { + Control *c = Object::cast_to<Control>(p_to_node); + Window *w = c == nullptr ? Object::cast_to<Window>(p_to_node) : nullptr; + + if (!c && !w) { + // Theme inheritance chains are broken by nodes that aren't Control or Window. + return; + } + + bool assign = p_assign; + if (c) { + if (c != p_owner_node && c->get_theme().is_valid()) { + // Has a theme, so we don't want to change the theme owner, + // but we still want to propagate in case this child has theme items + // it inherits from the theme this node uses. + // See https://github.com/godotengine/godot/issues/62844. + assign = false; + } + + if (assign) { + c->set_theme_owner_node(p_owner_node); + } + + if (p_notify) { + c->notification(Control::NOTIFICATION_THEME_CHANGED); + } + } else if (w) { + if (w != p_owner_node && w->get_theme().is_valid()) { + // Same as above. + assign = false; + } + + if (assign) { + w->set_theme_owner_node(p_owner_node); + } + + if (p_notify) { + w->notification(Window::NOTIFICATION_THEME_CHANGED); + } + } + + for (int i = 0; i < p_to_node->get_child_count(); i++) { + propagate_theme_changed(p_to_node->get_child(i), p_owner_node, p_notify, assign); + } +} + +// Theme lookup. + +void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List<StringName> *r_list) const { + const Control *for_c = Object::cast_to<Control>(p_for_node); + const Window *for_w = Object::cast_to<Window>(p_for_node); + ERR_FAIL_COND_MSG(!for_c && !for_w, "Only Control and Window nodes and derivatives can be polled for theming."); + + Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme(); + Ref<Theme> project_theme = ThemeDB::get_singleton()->get_project_theme(); + + StringName type_variation; + if (for_c) { + type_variation = for_c->get_theme_type_variation(); + } else if (for_w) { + type_variation = for_w->get_theme_type_variation(); + } + + if (p_theme_type == StringName() || p_theme_type == p_for_node->get_class_name() || p_theme_type == type_variation) { + if (project_theme.is_valid() && project_theme->get_type_variation_base(type_variation) != StringName()) { + project_theme->get_type_dependencies(p_for_node->get_class_name(), type_variation, r_list); + } else { + default_theme->get_type_dependencies(p_for_node->get_class_name(), type_variation, r_list); + } + } else { + default_theme->get_type_dependencies(p_theme_type, StringName(), r_list); + } +} + +Node *ThemeOwner::_get_next_owner_node(Node *p_from_node) const { + Node *parent = p_from_node->get_parent(); + + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + return parent_c->get_theme_owner_node(); + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + return parent_w->get_theme_owner_node(); + } + } + + return nullptr; +} + +Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, Variant(), "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Node *owner_node = get_owner_node(); + + while (owner_node) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_theme_item(p_data_type, p_name, E)) { + return owner_theme->get_theme_item(p_data_type, p_name, E); + } + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { + return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(p_data_type, p_name, E); + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, E); + } + } + + // If they don't exist, use any type to return the default/empty value. + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, p_theme_types[0]); +} + +bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Node *owner_node = get_owner_node(); + + while (owner_node) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + + return false; +} + +float ThemeOwner::get_theme_default_base_scale() { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Node *owner_node = get_owner_node(); + + while (owner_node) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_default_base_scale()) { + return owner_theme->get_default_base_scale(); + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_base_scale()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_base_scale(); + } + } + + // Lastly, fall back on the default Theme. + if (ThemeDB::get_singleton()->get_default_theme()->has_default_base_scale()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_base_scale(); + } + return ThemeDB::get_singleton()->get_fallback_base_scale(); +} + +Ref<Font> ThemeOwner::get_theme_default_font() { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Node *owner_node = get_owner_node(); + + while (owner_node) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_default_font()) { + return owner_theme->get_default_font(); + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_font()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_font(); + } + } + + // Lastly, fall back on the default Theme. + if (ThemeDB::get_singleton()->get_default_theme()->has_default_font()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_font(); + } + return ThemeDB::get_singleton()->get_fallback_font(); +} + +int ThemeOwner::get_theme_default_font_size() { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Node *owner_node = get_owner_node(); + + while (owner_node) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_default_font_size()) { + return owner_theme->get_default_font_size(); + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_font_size()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_font_size(); + } + } + + // Lastly, fall back on the default Theme. + if (ThemeDB::get_singleton()->get_default_theme()->has_default_font_size()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_font_size(); + } + return ThemeDB::get_singleton()->get_fallback_font_size(); +} diff --git a/scene/theme/theme_owner.h b/scene/theme/theme_owner.h new file mode 100644 index 0000000000..59b72c1627 --- /dev/null +++ b/scene/theme/theme_owner.h @@ -0,0 +1,75 @@ +/*************************************************************************/ +/* theme_owner.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef THEME_OWNER_H +#define THEME_OWNER_H + +#include "core/object/object.h" +#include "scene/resources/theme.h" + +class Control; +class Node; +class Window; + +class ThemeOwner : public Object { + Control *owner_control = nullptr; + Window *owner_window = nullptr; + + Node *_get_next_owner_node(Node *p_from_node) const; + +public: + // Theme owner node. + + void set_owner_node(Node *p_node); + Node *get_owner_node() const; + bool has_owner_node() const; + + // Theme propagation. + + void assign_theme_on_parented(Node *p_for_node); + void clear_theme_on_unparented(Node *p_for_node); + void propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign); + + // Theme lookup. + + void get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List<StringName> *r_list) const; + + Variant get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); + bool has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); + + float get_theme_default_base_scale(); + Ref<Font> get_theme_default_font(); + int get_theme_default_font_size(); + + ThemeOwner() {} + ~ThemeOwner() {} +}; + +#endif // THEME_OWNER_H |