浏览代码

Expose API to retrieve Theme's default font

Yuri Sizov 3 年之前
父节点
当前提交
98cf645258
共有 6 个文件被更改,包括 59 次插入4 次删除
  1. 7 0
      doc/classes/Control.xml
  2. 8 1
      doc/classes/Theme.xml
  3. 34 0
      scene/gui/control.cpp
  4. 2 0
      scene/gui/control.h
  5. 7 3
      scene/resources/theme.cpp
  6. 1 0
      scene/resources/theme.h

+ 7 - 0
doc/classes/Control.xml

@@ -362,6 +362,13 @@
 				See [method get_color] for details.
 			</description>
 		</method>
+		<method name="get_theme_default_font" qualifiers="const">
+			<return type="Font" />
+			<description>
+				Returns the default font from the first matching [Theme] in the tree if that [Theme] has a valid [member Theme.default_font] value.
+				See [method get_color] for details.
+			</description>
+		</method>
 		<method name="get_tooltip" qualifiers="const">
 			<return type="String" />
 			<argument index="0" name="at_position" type="Vector2" default="Vector2( 0, 0 )" />

+ 8 - 1
doc/classes/Theme.xml

@@ -238,6 +238,12 @@
 				Returns [code]false[/code] if the theme does not have [code]node_type[/code].
 			</description>
 		</method>
+		<method name="has_default_font" qualifiers="const">
+			<return type="bool" />
+			<description>
+				Returns [code]true[/code] if this theme has a valid [member default_font] value.
+			</description>
+		</method>
 		<method name="has_font" qualifiers="const">
 			<return type="bool" />
 			<argument index="0" name="name" type="String" />
@@ -403,7 +409,8 @@
 	</methods>
 	<members>
 		<member name="default_font" type="Font" setter="set_default_font" getter="get_default_font">
-			The theme's default font.
+			The default font of this [Theme] resource. Used as a fallback value for font items defined in this theme, but having invalid values. If this value is also invalid, the global default value is used.
+			Use [method has_default_font] to check if this value is valid.
 		</member>
 	</members>
 	<constants>

+ 34 - 0
scene/gui/control.cpp

@@ -1299,6 +1299,37 @@ bool Control::has_constant(const StringName &p_name, const StringName &p_theme_t
 	return Theme::get_default()->has_constant(p_name, type);
 }
 
+Ref<Font> Control::get_theme_default_font() const {
+	// 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 = data.theme_owner;
+
+	while (theme_owner) {
+		if (theme_owner && theme_owner->data.theme->has_default_theme_font()) {
+			return theme_owner->data.theme->get_default_theme_font();
+		}
+
+		Node *parent = theme_owner->get_parent();
+		Control *parent_c = Object::cast_to<Control>(parent);
+		if (parent_c) {
+			theme_owner = parent_c->data.theme_owner;
+		} else {
+			theme_owner = nullptr;
+		}
+	}
+
+	// Secondly, check the project-defined Theme resource.
+	if (Theme::get_project_default().is_valid()) {
+		if (Theme::get_project_default()->has_default_theme_font()) {
+			return Theme::get_project_default()->get_default_theme_font();
+		}
+	}
+
+	// Lastly, fall back on the default Theme.
+	return Theme::get_default()->get_default_theme_font();
+}
+
 Rect2 Control::get_parent_anchorable_rect() const {
 	if (!is_inside_tree()) {
 		return Rect2();
@@ -2793,6 +2824,8 @@ void Control::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("has_color", "name", "theme_type"), &Control::has_color, DEFVAL(""));
 	ClassDB::bind_method(D_METHOD("has_constant", "name", "theme_type"), &Control::has_constant, DEFVAL(""));
 
+	ClassDB::bind_method(D_METHOD("get_theme_default_font"), &Control::get_theme_default_font);
+
 	ClassDB::bind_method(D_METHOD("get_parent_control"), &Control::get_parent_control);
 
 	ClassDB::bind_method(D_METHOD("set_h_grow_direction", "direction"), &Control::set_h_grow_direction);
@@ -2991,6 +3024,7 @@ void Control::_bind_methods() {
 
 	BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_point", PropertyInfo(Variant::VECTOR2, "point")));
 }
+
 Control::Control() {
 	data.parent = nullptr;
 

+ 2 - 0
scene/gui/control.h

@@ -446,6 +446,8 @@ public:
 	bool has_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
 	bool has_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
 
+	Ref<Font> get_theme_default_font() const;
+
 	/* TOOLTIP */
 
 	void set_tooltip(const String &p_tooltip);

+ 7 - 3
scene/resources/theme.cpp

@@ -221,6 +221,10 @@ Ref<Font> Theme::get_default_theme_font() const {
 	return default_theme_font;
 }
 
+bool Theme::has_default_theme_font() const {
+	return default_theme_font.is_valid();
+}
+
 // Icons.
 void Theme::set_icon(const StringName &p_name, const StringName &p_node_type, const Ref<Texture> &p_icon) {
 	if (icon_map[p_node_type].has(p_name) && icon_map[p_node_type][p_name].is_valid()) {
@@ -451,7 +455,7 @@ void Theme::set_font(const StringName &p_name, const StringName &p_node_type, co
 Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_node_type) const {
 	if (font_map.has(p_node_type) && font_map[p_node_type].has(p_name) && font_map[p_node_type][p_name].is_valid()) {
 		return font_map[p_node_type][p_name];
-	} else if (default_theme_font.is_valid()) {
+	} else if (has_default_theme_font()) {
 		return default_theme_font;
 	} else {
 		return default_font;
@@ -1354,10 +1358,9 @@ void Theme::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_constant_list", "node_type"), &Theme::_get_constant_list);
 	ClassDB::bind_method(D_METHOD("get_constant_types"), &Theme::_get_constant_types);
 
-	ClassDB::bind_method(D_METHOD("clear"), &Theme::clear);
-
 	ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_theme_font);
 	ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_theme_font);
+	ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_theme_font);
 
 	ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "node_type", "value"), &Theme::set_theme_item);
 	ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "node_type"), &Theme::get_theme_item);
@@ -1374,6 +1377,7 @@ void Theme::_bind_methods() {
 	ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme);
 	ClassDB::bind_method(D_METHOD("copy_theme", "other"), &Theme::copy_theme);
 	ClassDB::bind_method(D_METHOD("merge_with", "other"), &Theme::merge_with);
+	ClassDB::bind_method(D_METHOD("clear"), &Theme::clear);
 
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "default_font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_default_font", "get_default_font");
 

+ 1 - 0
scene/resources/theme.h

@@ -120,6 +120,7 @@ public:
 
 	void set_default_theme_font(const Ref<Font> &p_default_font);
 	Ref<Font> get_default_theme_font() const;
+	bool has_default_theme_font() const;
 
 	void set_icon(const StringName &p_name, const StringName &p_node_type, const Ref<Texture> &p_icon);
 	Ref<Texture> get_icon(const StringName &p_name, const StringName &p_node_type) const;