|
@@ -833,11 +833,12 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner
|
|
ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified.");
|
|
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.
|
|
// First, look through each control or window node in the branch, until no valid parent can be found.
|
|
- // For each control iterate through its inheritance chain and see if p_name exists in any of them.
|
|
|
|
|
|
+ // Only nodes with a theme resource attached are considered.
|
|
Control *theme_owner = p_theme_owner;
|
|
Control *theme_owner = p_theme_owner;
|
|
Window *theme_owner_window = p_theme_owner_window;
|
|
Window *theme_owner_window = p_theme_owner_window;
|
|
|
|
|
|
while (theme_owner || 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) {
|
|
for (const StringName &E : p_theme_types) {
|
|
if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) {
|
|
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);
|
|
return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E);
|
|
@@ -888,11 +889,12 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow
|
|
ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified.");
|
|
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.
|
|
// First, look through each control or window node in the branch, until no valid parent can be found.
|
|
- // For each control iterate through its inheritance chain and see if p_name exists in any of them.
|
|
|
|
|
|
+ // Only nodes with a theme resource attached are considered.
|
|
Control *theme_owner = p_theme_owner;
|
|
Control *theme_owner = p_theme_owner;
|
|
Window *theme_owner_window = p_theme_owner_window;
|
|
Window *theme_owner_window = p_theme_owner_window;
|
|
|
|
|
|
while (theme_owner || 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) {
|
|
for (const StringName &E : p_theme_types) {
|
|
if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) {
|
|
if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) {
|
|
return true;
|
|
return true;
|
|
@@ -1130,6 +1132,150 @@ bool Control::has_theme_constant(const StringName &p_name, const StringName &p_t
|
|
return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
|
|
return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+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_theme_base_scale()) {
|
|
|
|
+ return theme_owner->data.theme->get_default_theme_base_scale();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (theme_owner_window && theme_owner_window->theme->has_default_theme_base_scale()) {
|
|
|
|
+ return theme_owner_window->theme->get_default_theme_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 (Theme::get_project_default().is_valid()) {
|
|
|
|
+ if (Theme::get_project_default()->has_default_theme_base_scale()) {
|
|
|
|
+ return Theme::get_project_default()->get_default_theme_base_scale();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Lastly, fall back on the default Theme.
|
|
|
|
+ return Theme::get_default()->get_default_theme_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_theme_font()) {
|
|
|
|
+ return theme_owner->data.theme->get_default_theme_font();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (theme_owner_window && theme_owner_window->theme->has_default_theme_font()) {
|
|
|
|
+ return theme_owner_window->theme->get_default_theme_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 (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();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+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_theme_font_size()) {
|
|
|
|
+ return theme_owner->data.theme->get_default_theme_font_size();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (theme_owner_window && theme_owner_window->theme->has_default_theme_font_size()) {
|
|
|
|
+ return theme_owner_window->theme->get_default_theme_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 (Theme::get_project_default().is_valid()) {
|
|
|
|
+ if (Theme::get_project_default()->has_default_theme_font_size()) {
|
|
|
|
+ return Theme::get_project_default()->get_default_theme_font_size();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Lastly, fall back on the default Theme.
|
|
|
|
+ return Theme::get_default()->get_default_theme_font_size();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int Control::get_theme_default_font_size() const {
|
|
|
|
+ return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window);
|
|
|
|
+}
|
|
|
|
+
|
|
Rect2 Control::get_parent_anchorable_rect() const {
|
|
Rect2 Control::get_parent_anchorable_rect() const {
|
|
if (!is_inside_tree()) {
|
|
if (!is_inside_tree()) {
|
|
return Rect2();
|
|
return Rect2();
|
|
@@ -2789,6 +2935,10 @@ void Control::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Control::has_theme_color, DEFVAL(""));
|
|
ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Control::has_theme_color, DEFVAL(""));
|
|
ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Control::has_theme_constant, DEFVAL(""));
|
|
ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Control::has_theme_constant, DEFVAL(""));
|
|
|
|
|
|
|
|
+ ClassDB::bind_method(D_METHOD("get_theme_default_base_scale"), &Control::get_theme_default_base_scale);
|
|
|
|
+ ClassDB::bind_method(D_METHOD("get_theme_default_font"), &Control::get_theme_default_font);
|
|
|
|
+ ClassDB::bind_method(D_METHOD("get_theme_default_font_size"), &Control::get_theme_default_font_size);
|
|
|
|
+
|
|
ClassDB::bind_method(D_METHOD("get_parent_control"), &Control::get_parent_control);
|
|
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);
|
|
ClassDB::bind_method(D_METHOD("set_h_grow_direction", "direction"), &Control::set_h_grow_direction);
|