diff options
| -rw-r--r-- | SConstruct | 15 | ||||
| -rw-r--r-- | core/os/os.cpp | 6 | ||||
| -rw-r--r-- | doc/classes/DynamicFontData.xml | 2 | ||||
| -rw-r--r-- | doc/classes/RichTextLabel.xml | 4 | ||||
| -rw-r--r-- | editor/plugins/collision_shape_2d_editor_plugin.cpp | 1 | ||||
| -rw-r--r-- | editor/project_manager.cpp | 6 | ||||
| -rw-r--r-- | editor/scene_tree_dock.cpp | 5 | ||||
| -rw-r--r-- | editor/script_create_dialog.cpp | 7 | ||||
| -rw-r--r-- | methods.py | 24 | ||||
| -rw-r--r-- | modules/opus/config.py | 2 | ||||
| -rw-r--r-- | modules/theora/config.py | 2 | ||||
| -rw-r--r-- | modules/vorbis/config.py | 2 | ||||
| -rw-r--r-- | modules/webm/config.py | 5 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.cpp | 299 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.h | 5 | ||||
| -rw-r--r-- | scene/register_scene_types.cpp | 1 | ||||
| -rw-r--r-- | scene/resources/dynamic_font.cpp | 2 | ||||
| -rw-r--r-- | scene/resources/ray_shape_2d.cpp | 105 | ||||
| -rw-r--r-- | scene/resources/ray_shape_2d.h | 61 | ||||
| -rw-r--r-- | scene/resources/segment_shape_2d.cpp | 74 | ||||
| -rw-r--r-- | scene/resources/segment_shape_2d.h | 25 | 
21 files changed, 387 insertions, 266 deletions
diff --git a/SConstruct b/SConstruct index 27e6c5f2d3..b424363dc8 100644 --- a/SConstruct +++ b/SConstruct @@ -86,6 +86,7 @@ env_base.__class__.add_library = methods.add_library  env_base.__class__.add_program = methods.add_program  env_base.__class__.CommandNoCache = methods.CommandNoCache  env_base.__class__.disable_warnings = methods.disable_warnings +env_base.__class__.module_check_dependencies = methods.module_check_dependencies  env_base["x86_libtheora_opt_gcc"] = False  env_base["x86_libtheora_opt_vc"] = False @@ -607,14 +608,12 @@ if selected_platform in platform_list:          env.Append(CPPDEFINES=["MINIZIP_ENABLED"])      editor_module_list = ["regex"] -    for x in editor_module_list: -        if not env["module_" + x + "_enabled"]: -            if env["tools"]: -                print( -                    "Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), " -                    "only with 'tools=no' (export template)." -                ) -                Exit(255) +    if env["tools"] and not env.module_check_dependencies("tools", editor_module_list): +        print( +            "Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), " +            "only with 'tools=no' (export template)." +        ) +        Exit(255)      if not env["verbose"]:          methods.no_verbose(sys, env) diff --git a/core/os/os.cpp b/core/os/os.cpp index c29930e485..56755bcf51 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -457,18 +457,22 @@ PackedStringArray OS::get_connected_midi_inputs() {  	}  	PackedStringArray list; -	return list; +	ERR_FAIL_V_MSG(list, vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name()));  }  void OS::open_midi_inputs() {  	if (MIDIDriver::get_singleton()) {  		MIDIDriver::get_singleton()->open(); +	} else { +		ERR_PRINT(vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name()));  	}  }  void OS::close_midi_inputs() {  	if (MIDIDriver::get_singleton()) {  		MIDIDriver::get_singleton()->close(); +	} else { +		ERR_PRINT(vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name()));  	}  } diff --git a/doc/classes/DynamicFontData.xml b/doc/classes/DynamicFontData.xml index 2b4ec17bf1..483da96f3f 100644 --- a/doc/classes/DynamicFontData.xml +++ b/doc/classes/DynamicFontData.xml @@ -12,7 +12,7 @@  	</methods>  	<members>  		<member name="antialiased" type="bool" setter="set_antialiased" getter="is_antialiased" default="true"> -			If [code]true[/code], the font is rendered with anti-aliasing. +			If [code]true[/code], the font is rendered with anti-aliasing. This property applies both to the main font and its outline (if it has one).  		</member>  		<member name="font_path" type="String" setter="set_font_path" getter="get_font_path" default="""">  			The path to the vector font file. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index efc0c9d600..db036d7d88 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -20,8 +20,10 @@  			</argument>  			<argument index="2" name="height" type="int" default="0">  			</argument> +			<argument index="3" name="color" type="Color" default="Color( 1, 1, 1, 1 )"> +			</argument>  			<description> -				Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image. +				Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image and a [code]color[/code] to tint the image.  				If [code]width[/code] or [code]height[/code] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.  			</description>  		</method> diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 0f381c06b4..596629f8e8 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -36,6 +36,7 @@  #include "scene/resources/concave_polygon_shape_2d.h"  #include "scene/resources/convex_polygon_shape_2d.h"  #include "scene/resources/line_shape_2d.h" +#include "scene/resources/ray_shape_2d.h"  #include "scene/resources/rectangle_shape_2d.h"  #include "scene/resources/segment_shape_2d.h" diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index dc5ff6a5eb..499f7d4017 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -916,6 +916,8 @@ public:  		icon = nullptr;  		icon_needs_reload = true;  		hover = false; + +		set_focus_mode(FocusMode::FOCUS_ALL);  	}  	void set_is_favorite(bool fav) { @@ -1739,6 +1741,10 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {  			select_project(clicked_index);  		} +		if (_selected_project_keys.has(clicked_project.project_key)) { +			clicked_project.control->grab_focus(); +		} +  		emit_signal(SIGNAL_SELECTION_CHANGED);  		if (!mb->get_control() && mb->is_doubleclick()) { diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index a81a2ff4e9..c37d32b26b 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2557,6 +2557,11 @@ void SceneTreeDock::_focus_node() {  }  void SceneTreeDock::attach_script_to_selected(bool p_extend) { +	if (ScriptServer::get_language_count() == 0) { +		EditorNode::get_singleton()->show_warning(TTR("Cannot attach a script: there are no languages registered.\nThis is probably because this editor was built with all language modules disabled.")); +		return; +	} +  	if (!profile_allow_script_editing) {  		return;  	} diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 04fbfdff9d..ae5229b628 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -783,7 +783,7 @@ ScriptCreateDialog::ScriptCreateDialog() {  	gc->add_child(memnew(Label(TTR("Language:"))));  	gc->add_child(language_menu); -	default_language = 0; +	default_language = -1;  	for (int i = 0; i < ScriptServer::get_language_count(); i++) {  		String lang = ScriptServer::get_language(i)->get_name();  		language_menu->add_item(lang); @@ -791,8 +791,9 @@ ScriptCreateDialog::ScriptCreateDialog() {  			default_language = i;  		}  	} - -	language_menu->select(default_language); +	if (default_language >= 0) { +		language_menu->select(default_language); +	}  	current_language = default_language;  	language_menu->connect("item_selected", callable_mp(this, &ScriptCreateDialog::_lang_changed)); diff --git a/methods.py b/methods.py index c1245cd95a..756db19e9a 100644 --- a/methods.py +++ b/methods.py @@ -231,6 +231,30 @@ def disable_module(self):      self.disabled_modules.append(self.current_module) +def module_check_dependencies(self, module, dependencies): +    """ +    Checks if module dependencies are enabled for a given module, +    and prints a warning if they aren't. +    Meant to be used in module `can_build` methods. +    Returns a boolean (True if dependencies are satisfied). +    """ +    missing_deps = [] +    for dep in dependencies: +        opt = "module_{}_enabled".format(dep) +        if not opt in self or not self[opt]: +            missing_deps.append(dep) + +    if missing_deps != []: +        print( +            "Disabling '{}' module as the following dependencies are not satisfied: {}".format( +                module, ", ".join(missing_deps) +            ) +        ) +        return False +    else: +        return True + +  def use_windows_spawn_fix(self, platform=None):      if os.name != "nt": diff --git a/modules/opus/config.py b/modules/opus/config.py index d22f9454ed..9ff7b2dece 100644 --- a/modules/opus/config.py +++ b/modules/opus/config.py @@ -1,5 +1,5 @@  def can_build(env, platform): -    return True +    return env.module_check_dependencies("opus", ["ogg"])  def configure(env): diff --git a/modules/theora/config.py b/modules/theora/config.py index 413acce2df..b063ed51f9 100644 --- a/modules/theora/config.py +++ b/modules/theora/config.py @@ -1,5 +1,5 @@  def can_build(env, platform): -    return True +    return env.module_check_dependencies("theora", ["ogg", "vorbis"])  def configure(env): diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py index d22f9454ed..8a384e3066 100644 --- a/modules/vorbis/config.py +++ b/modules/vorbis/config.py @@ -1,5 +1,5 @@  def can_build(env, platform): -    return True +    return env.module_check_dependencies("vorbis", ["ogg"])  def configure(env): diff --git a/modules/webm/config.py b/modules/webm/config.py index 93b49d177a..99f8ace114 100644 --- a/modules/webm/config.py +++ b/modules/webm/config.py @@ -1,5 +1,8 @@  def can_build(env, platform): -    return platform not in ["iphone"] +    if platform in ["iphone"]: +        return False + +    return env.module_check_dependencies("webm", ["ogg", "opus", "vorbis"])  def configure(env): diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index a57408b83b..d5c065bd55 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -646,7 +646,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &  				}  				if (p_mode == PROCESS_DRAW && visible) { -					img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size)); +					img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size), false, img->color);  				}  				p_char_count++; @@ -1443,6 +1443,46 @@ void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack  	}  } +Color RichTextLabel::_get_color_from_string(const String &p_color_str, const Color &p_default_color) { +	if (p_color_str.begins_with("#")) { +		return Color::html(p_color_str); +	} else if (p_color_str == "aqua") { +		return Color(0, 1, 1); +	} else if (p_color_str == "black") { +		return Color(0, 0, 0); +	} else if (p_color_str == "blue") { +		return Color(0, 0, 1); +	} else if (p_color_str == "fuchsia") { +		return Color(1, 0, 1); +	} else if (p_color_str == "gray" || p_color_str == "grey") { +		return Color(0.5, 0.5, 0.5); +	} else if (p_color_str == "green") { +		return Color(0, 0.5, 0); +	} else if (p_color_str == "lime") { +		return Color(0, 1, 0); +	} else if (p_color_str == "maroon") { +		return Color(0.5, 0, 0); +	} else if (p_color_str == "navy") { +		return Color(0, 0, 0.5); +	} else if (p_color_str == "olive") { +		return Color(0.5, 0.5, 0); +	} else if (p_color_str == "purple") { +		return Color(0.5, 0, 0.5); +	} else if (p_color_str == "red") { +		return Color(1, 0, 0); +	} else if (p_color_str == "silver") { +		return Color(0.75, 0.75, 0.75); +	} else if (p_color_str == "teal") { +		return Color(0, 0.5, 0.5); +	} else if (p_color_str == "white") { +		return Color(1, 1, 1); +	} else if (p_color_str == "yellow") { +		return Color(1, 1, 0); +	} else { +		return p_default_color; +	} +} +  bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) {  	Item *item = p_item; @@ -1636,7 +1676,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub  	}  } -void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height) { +void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color) {  	if (current->type == ITEM_TABLE) {  		return;  	} @@ -1645,6 +1685,7 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,  	ItemImage *item = memnew(ItemImage);  	item->image = p_image; +	item->color = p_color;  	if (p_width > 0) {  		// custom width @@ -2034,7 +2075,32 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {  		String tag = p_bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);  		Vector<String> split_tag_block = tag.split(" ", false); -		String bbcode = !split_tag_block.empty() ? split_tag_block[0] : ""; + +		// Find optional parameters. +		String bbcode_name; +		typedef Map<String, String> OptionMap; +		OptionMap bbcode_options; +		if (!split_tag_block.empty()) { +			bbcode_name = split_tag_block[0]; +			for (int i = 1; i < split_tag_block.size(); i++) { +				const String &expr = split_tag_block[i]; +				int value_pos = expr.find("="); +				if (value_pos > -1) { +					bbcode_options[expr.substr(0, value_pos)] = expr.substr(value_pos + 1); +				} +			} +		} else { +			bbcode_name = tag; +		} + +		// Find main parameter. +		String bbcode_value; +		int main_value_pos = bbcode_name.find("="); +		if (main_value_pos > -1) { +			bbcode_value = bbcode_name.substr(main_value_pos + 1); +			bbcode_name = bbcode_name.substr(0, main_value_pos); +		} +  		if (tag.begins_with("/") && tag_stack.size()) {  			bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length()); @@ -2160,7 +2226,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {  			push_meta(url);  			pos = brk_end + 1;  			tag_stack.push_front("url"); -		} else if (tag == "img") { +		} else if (bbcode_name == "img") {  			int end = p_bbcode.find("[", brk_end);  			if (end == -1) {  				end = p_bbcode.length(); @@ -2170,80 +2236,42 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {  			Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D");  			if (texture.is_valid()) { -				add_image(texture); -			} - -			pos = end; -			tag_stack.push_front(tag); -		} else if (tag.begins_with("img=")) { -			int width = 0; -			int height = 0; - -			String params = tag.substr(4, tag.length()); -			int sep = params.find("x"); -			if (sep == -1) { -				width = params.to_int(); -			} else { -				width = params.substr(0, sep).to_int(); -				height = params.substr(sep + 1, params.length()).to_int(); -			} +				Color color = Color(1.0, 1.0, 1.0); +				OptionMap::Element *color_option = bbcode_options.find("color"); +				if (color_option) { +					color = _get_color_from_string(color_option->value(), color); +				} -			int end = p_bbcode.find("[", brk_end); -			if (end == -1) { -				end = p_bbcode.length(); -			} +				int width = 0; +				int height = 0; +				if (!bbcode_value.empty()) { +					int sep = bbcode_value.find("x"); +					if (sep == -1) { +						width = bbcode_value.to_int(); +					} else { +						width = bbcode_value.substr(0, sep).to_int(); +						height = bbcode_value.substr(sep + 1).to_int(); +					} +				} else { +					OptionMap::Element *width_option = bbcode_options.find("width"); +					if (width_option) { +						width = width_option->value().to_int(); +					} -			String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1); +					OptionMap::Element *height_option = bbcode_options.find("height"); +					if (height_option) { +						height = height_option->value().to_int(); +					} +				} -			Ref<Texture2D> texture = ResourceLoader::load(image, "Texture"); -			if (texture.is_valid()) { -				add_image(texture, width, height); +				add_image(texture, width, height, color);  			}  			pos = end; -			tag_stack.push_front("img"); +			tag_stack.push_front(bbcode_name);  		} else if (tag.begins_with("color=")) { -			String col = tag.substr(6, tag.length()); -			Color color; - -			if (col.begins_with("#")) { -				color = Color::html(col); -			} else if (col == "aqua") { -				color = Color(0, 1, 1); -			} else if (col == "black") { -				color = Color(0, 0, 0); -			} else if (col == "blue") { -				color = Color(0, 0, 1); -			} else if (col == "fuchsia") { -				color = Color(1, 0, 1); -			} else if (col == "gray" || col == "grey") { -				color = Color(0.5, 0.5, 0.5); -			} else if (col == "green") { -				color = Color(0, 0.5, 0); -			} else if (col == "lime") { -				color = Color(0, 1, 0); -			} else if (col == "maroon") { -				color = Color(0.5, 0, 0); -			} else if (col == "navy") { -				color = Color(0, 0, 0.5); -			} else if (col == "olive") { -				color = Color(0.5, 0.5, 0); -			} else if (col == "purple") { -				color = Color(0.5, 0, 0.5); -			} else if (col == "red") { -				color = Color(1, 0, 0); -			} else if (col == "silver") { -				color = Color(0.75, 0.75, 0.75); -			} else if (col == "teal") { -				color = Color(0, 0.5, 0.5); -			} else if (col == "white") { -				color = Color(1, 1, 1); -			} else if (col == "yellow") { -				color = Color(1, 1, 0); -			} else { -				color = base_color; -			} - +			String color_str = tag.substr(6, tag.length()); +			Color color = _get_color_from_string(color_str, base_color);  			push_color(color);  			pos = brk_end + 1;  			tag_stack.push_front("color"); @@ -2261,113 +2289,90 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {  			pos = brk_end + 1;  			tag_stack.push_front("font"); -		} else if (bbcode == "fade") { -			int startIndex = 0; -			int length = 10; +		} else if (bbcode_name == "fade") { +			int start_index = 0; +			OptionMap::Element *start_option = bbcode_options.find("start"); +			if (start_option) { +				start_index = start_option->value().to_int(); +			} -			if (split_tag_block.size() > 1) { -				split_tag_block.remove(0); -				for (int i = 0; i < split_tag_block.size(); i++) { -					String expr = split_tag_block[i]; -					if (expr.begins_with("start=")) { -						String start_str = expr.substr(6, expr.length()); -						startIndex = start_str.to_int(); -					} else if (expr.begins_with("length=")) { -						String end_str = expr.substr(7, expr.length()); -						length = end_str.to_int(); -					} -				} +			int length = 10; +			OptionMap::Element *length_option = bbcode_options.find("length"); +			if (length_option) { +				length = length_option->value().to_int();  			} -			push_fade(startIndex, length); +			push_fade(start_index, length);  			pos = brk_end + 1;  			tag_stack.push_front("fade"); -		} else if (bbcode == "shake") { +		} else if (bbcode_name == "shake") {  			int strength = 5; -			float rate = 20.0f; +			OptionMap::Element *strength_option = bbcode_options.find("level"); +			if (strength_option) { +				strength = strength_option->value().to_int(); +			} -			if (split_tag_block.size() > 1) { -				split_tag_block.remove(0); -				for (int i = 0; i < split_tag_block.size(); i++) { -					String expr = split_tag_block[i]; -					if (expr.begins_with("level=")) { -						String str_str = expr.substr(6, expr.length()); -						strength = str_str.to_int(); -					} else if (expr.begins_with("rate=")) { -						String rate_str = expr.substr(5, expr.length()); -						rate = rate_str.to_float(); -					} -				} +			float rate = 20.0f; +			OptionMap::Element *rate_option = bbcode_options.find("rate"); +			if (rate_option) { +				rate = rate_option->value().to_float();  			}  			push_shake(strength, rate);  			pos = brk_end + 1;  			tag_stack.push_front("shake");  			set_process_internal(true); -		} else if (bbcode == "wave") { +		} else if (bbcode_name == "wave") {  			float amplitude = 20.0f; -			float period = 5.0f; +			OptionMap::Element *amplitude_option = bbcode_options.find("amp"); +			if (amplitude_option) { +				amplitude = amplitude_option->value().to_float(); +			} -			if (split_tag_block.size() > 1) { -				split_tag_block.remove(0); -				for (int i = 0; i < split_tag_block.size(); i++) { -					String expr = split_tag_block[i]; -					if (expr.begins_with("amp=")) { -						String amp_str = expr.substr(4, expr.length()); -						amplitude = amp_str.to_float(); -					} else if (expr.begins_with("freq=")) { -						String period_str = expr.substr(5, expr.length()); -						period = period_str.to_float(); -					} -				} +			float period = 5.0f; +			OptionMap::Element *period_option = bbcode_options.find("freq"); +			if (period_option) { +				period = period_option->value().to_float();  			}  			push_wave(period, amplitude);  			pos = brk_end + 1;  			tag_stack.push_front("wave");  			set_process_internal(true); -		} else if (bbcode == "tornado") { +		} else if (bbcode_name == "tornado") {  			float radius = 10.0f; -			float frequency = 1.0f; +			OptionMap::Element *radius_option = bbcode_options.find("radius"); +			if (radius_option) { +				radius = radius_option->value().to_float(); +			} -			if (split_tag_block.size() > 1) { -				split_tag_block.remove(0); -				for (int i = 0; i < split_tag_block.size(); i++) { -					String expr = split_tag_block[i]; -					if (expr.begins_with("radius=")) { -						String amp_str = expr.substr(7, expr.length()); -						radius = amp_str.to_float(); -					} else if (expr.begins_with("freq=")) { -						String period_str = expr.substr(5, expr.length()); -						frequency = period_str.to_float(); -					} -				} +			float frequency = 1.0f; +			OptionMap::Element *frequency_option = bbcode_options.find("freq"); +			if (frequency_option) { +				frequency = frequency_option->value().to_float();  			}  			push_tornado(frequency, radius);  			pos = brk_end + 1;  			tag_stack.push_front("tornado");  			set_process_internal(true); -		} else if (bbcode == "rainbow") { +		} else if (bbcode_name == "rainbow") {  			float saturation = 0.8f; +			OptionMap::Element *saturation_option = bbcode_options.find("sat"); +			if (saturation_option) { +				saturation = saturation_option->value().to_float(); +			} +  			float value = 0.8f; -			float frequency = 1.0f; +			OptionMap::Element *value_option = bbcode_options.find("val"); +			if (value_option) { +				value = value_option->value().to_float(); +			} -			if (split_tag_block.size() > 1) { -				split_tag_block.remove(0); -				for (int i = 0; i < split_tag_block.size(); i++) { -					String expr = split_tag_block[i]; -					if (expr.begins_with("sat=")) { -						String sat_str = expr.substr(4, expr.length()); -						saturation = sat_str.to_float(); -					} else if (expr.begins_with("val=")) { -						String val_str = expr.substr(4, expr.length()); -						value = val_str.to_float(); -					} else if (expr.begins_with("freq=")) { -						String freq_str = expr.substr(5, expr.length()); -						frequency = freq_str.to_float(); -					} -				} +			float frequency = 1.0f; +			OptionMap::Element *frequency_option = bbcode_options.find("freq"); +			if (frequency_option) { +				frequency = frequency_option->value().to_float();  			}  			push_rainbow(saturation, value, frequency); @@ -2634,7 +2639,7 @@ void RichTextLabel::_bind_methods() {  	ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);  	ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);  	ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text); -	ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0)); +	ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)));  	ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);  	ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);  	ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 019edf5d45..4cec435568 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -149,6 +149,7 @@ private:  	struct ItemImage : public Item {  		Ref<Texture2D> image;  		Size2 size; +		Color color;  		ItemImage() { type = ITEM_IMAGE; }  	}; @@ -381,6 +382,8 @@ private:  	bool _find_by_type(Item *p_item, ItemType p_type);  	void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack); +	static Color _get_color_from_string(const String &p_color_str, const Color &p_default_color); +  	void _update_scroll();  	void _update_fx(ItemFrame *p_frame, float p_delta_time);  	void _scroll_changed(double); @@ -406,7 +409,7 @@ protected:  public:  	String get_text();  	void add_text(const String &p_text); -	void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0); +	void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0));  	void add_newline();  	bool remove_line(const int p_line);  	void push_font(const Ref<Font> &p_font); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 5588d1bd97..2d0e2daf41 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -154,6 +154,7 @@  #include "scene/resources/physics_material.h"  #include "scene/resources/polygon_path_finder.h"  #include "scene/resources/primitive_meshes.h" +#include "scene/resources/ray_shape_2d.h"  #include "scene/resources/ray_shape_3d.h"  #include "scene/resources/rectangle_shape_2d.h"  #include "scene/resources/resource_format_text.h" diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 3b4e4b73f8..3d99556a10 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -567,7 +567,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_ch  	if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) {  		goto cleanup_glyph;  	} -	if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, nullptr, 1) != 0) { +	if (FT_Glyph_To_Bitmap(&glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, nullptr, 1) != 0) {  		goto cleanup_glyph;  	} diff --git a/scene/resources/ray_shape_2d.cpp b/scene/resources/ray_shape_2d.cpp new file mode 100644 index 0000000000..67c4f84749 --- /dev/null +++ b/scene/resources/ray_shape_2d.cpp @@ -0,0 +1,105 @@ +/*************************************************************************/ +/*  ray_shape_2d.cpp                                                     */ +/*************************************************************************/ +/*                       This file is part of:                           */ +/*                           GODOT ENGINE                                */ +/*                      https://godotengine.org                          */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ +/* Copyright (c) 2014-2020 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 "ray_shape_2d.h" + +#include "servers/physics_server_2d.h" +#include "servers/rendering_server.h" + +void RayShape2D::_update_shape() { +	Dictionary d; +	d["length"] = length; +	d["slips_on_slope"] = slips_on_slope; +	PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), d); +	emit_changed(); +} + +void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) { +	Vector2 tip = Vector2(0, get_length()); +	RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3); +	Vector<Vector2> pts; +	float tsize = 4; +	pts.push_back(tip + Vector2(0, tsize)); +	pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0)); +	pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0)); +	Vector<Color> cols; +	for (int i = 0; i < 3; i++) { +		cols.push_back(p_color); +	} +	RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID()); +} + +Rect2 RayShape2D::get_rect() const { +	Rect2 rect; +	rect.position = Vector2(); +	rect.expand_to(Vector2(0, length)); +	rect = rect.grow(Math_SQRT12 * 4); +	return rect; +} + +real_t RayShape2D::get_enclosing_radius() const { +	return length; +} + +void RayShape2D::_bind_methods() { +	ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length); +	ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length); + +	ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope); +	ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope); + +	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length"); +	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope"); +} + +void RayShape2D::set_length(real_t p_length) { +	length = p_length; +	_update_shape(); +} + +real_t RayShape2D::get_length() const { +	return length; +} + +void RayShape2D::set_slips_on_slope(bool p_active) { +	slips_on_slope = p_active; +	_update_shape(); +} + +bool RayShape2D::get_slips_on_slope() const { +	return slips_on_slope; +} + +RayShape2D::RayShape2D() : +		Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) { +	length = 20; +	slips_on_slope = false; +	_update_shape(); +} diff --git a/scene/resources/ray_shape_2d.h b/scene/resources/ray_shape_2d.h new file mode 100644 index 0000000000..9a209d2907 --- /dev/null +++ b/scene/resources/ray_shape_2d.h @@ -0,0 +1,61 @@ +/*************************************************************************/ +/*  ray_shape_2d.h                                                       */ +/*************************************************************************/ +/*                       This file is part of:                           */ +/*                           GODOT ENGINE                                */ +/*                      https://godotengine.org                          */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ +/* Copyright (c) 2014-2020 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 RAY_SHAPE_2D_H +#define RAY_SHAPE_2D_H + +#include "scene/resources/shape_2d.h" + +class RayShape2D : public Shape2D { +	GDCLASS(RayShape2D, Shape2D); + +	real_t length; +	bool slips_on_slope; + +	void _update_shape(); + +protected: +	static void _bind_methods(); + +public: +	void set_length(real_t p_length); +	real_t get_length() const; + +	void set_slips_on_slope(bool p_active); +	bool get_slips_on_slope() const; + +	virtual void draw(const RID &p_to_rid, const Color &p_color); +	virtual Rect2 get_rect() const; +	virtual real_t get_enclosing_radius() const; + +	RayShape2D(); +}; + +#endif // RAY_SHAPE_2D_H diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp index e13c4c67c4..b1001203a1 100644 --- a/scene/resources/segment_shape_2d.cpp +++ b/scene/resources/segment_shape_2d.cpp @@ -98,77 +98,3 @@ SegmentShape2D::SegmentShape2D() :  	b = Vector2(0, 10);  	_update_shape();  } - -//////////////////////////////////////////////////////////// - -void RayShape2D::_update_shape() { -	Dictionary d; -	d["length"] = length; -	d["slips_on_slope"] = slips_on_slope; -	PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), d); -	emit_changed(); -} - -void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) { -	Vector2 tip = Vector2(0, get_length()); -	RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3); -	Vector<Vector2> pts; -	float tsize = 4; -	pts.push_back(tip + Vector2(0, tsize)); -	pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0)); -	pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0)); -	Vector<Color> cols; -	for (int i = 0; i < 3; i++) { -		cols.push_back(p_color); -	} - -	RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID()); -} - -Rect2 RayShape2D::get_rect() const { -	Rect2 rect; -	rect.position = Vector2(); -	rect.expand_to(Vector2(0, length)); -	rect = rect.grow(Math_SQRT12 * 4); -	return rect; -} - -real_t RayShape2D::get_enclosing_radius() const { -	return length; -} - -void RayShape2D::_bind_methods() { -	ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length); -	ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length); - -	ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope); -	ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope); - -	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length"); -	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope"); -} - -void RayShape2D::set_length(real_t p_length) { -	length = p_length; -	_update_shape(); -} - -real_t RayShape2D::get_length() const { -	return length; -} - -void RayShape2D::set_slips_on_slope(bool p_active) { -	slips_on_slope = p_active; -	_update_shape(); -} - -bool RayShape2D::get_slips_on_slope() const { -	return slips_on_slope; -} - -RayShape2D::RayShape2D() : -		Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) { -	length = 20; -	slips_on_slope = false; -	_update_shape(); -} diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h index ca10c24f07..39c297b040 100644 --- a/scene/resources/segment_shape_2d.h +++ b/scene/resources/segment_shape_2d.h @@ -60,29 +60,4 @@ public:  	SegmentShape2D();  }; -class RayShape2D : public Shape2D { -	GDCLASS(RayShape2D, Shape2D); - -	real_t length; -	bool slips_on_slope; - -	void _update_shape(); - -protected: -	static void _bind_methods(); - -public: -	void set_length(real_t p_length); -	real_t get_length() const; - -	void set_slips_on_slope(bool p_active); -	bool get_slips_on_slope() const; - -	virtual void draw(const RID &p_to_rid, const Color &p_color); -	virtual Rect2 get_rect() const; -	virtual real_t get_enclosing_radius() const; - -	RayShape2D(); -}; -  #endif // SEGMENT_SHAPE_2D_H  |