Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add StyleBoxMulti that draws other style boxes #79046

Closed
wants to merge 1 commit into from

Conversation

aaronfranke
Copy link
Member

@aaronfranke aaronfranke commented Jul 5, 2023

Implements and closes godotengine/godot-proposals#7203

EDIT: Actually, does not need to be in the engine, I made a mistake when concluding it can't be done in an add-on.

@fire
Copy link
Member

fire commented Jul 5, 2023

The crash report failure is confusing. Any ideas?

@theraot
Copy link
Contributor

theraot commented Jul 5, 2023

@fire Isn't it this: #78749 ?

}

void StyleBoxMulti::set_style_boxes(const TypedArray<StyleBox> &p_styleboxes) {
style_boxes = p_styleboxes;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setter probably should have a cyclic reference check to make sure one of the items is not this or another StyleBoxMulti with this as a child style, or it can get stuck it the infinite draw loop.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check for that in debug mode https://github.com/aaronfranke/godot/blob/style-box-multi/scene/resources/style_box.cpp#L159-L185

GitHub isn't showing the change on the PR for some reason. I could push again to see if that works but I will need to push again anyway for the docs after the version bump to 4.2 so I'll just wait.

@MewPurPur
Copy link
Contributor

<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><linearGradient x2="0" y2="16" gradientUnits="userSpaceOnUse" id="a"><stop offset=".188" stop-color="#ff4545"/><stop stop-color="#ffe345"/><stop offset=".313" stop-color="#ffe345"/><stop stop-color="#80ff45"/><stop offset=".438" stop-color="#80ff45"/><stop stop-color="#45ffa2"/><stop offset=".563" stop-color="#45ffa2"/><stop stop-color="#45d7ff"/><stop offset=".688" stop-color="#45d7ff"/><stop stop-color="#8045ff"/><stop offset=".813" stop-color="#8045ff"/><stop stop-color="#ff4596"/></linearGradient><path d="M10.268 6c.77-1.334 2.695-1.334 3.465 0 .188.327.428.66.685 1 .186.246.38.494.582.75V2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v5h2V3h5v3H6v1H5v1H4v1h4zM12 7c-.429.746-.946 1.387-1.429 2-.571.69-1.066 1.342-1.34 2-.138.326-.231.656-.231 1s.072.686.184 1c.413 1.163 1.512 2 2.816 2s2.402-.837 2.816-2c.112-.314.184-.656.184-1s-.094-.674-.231-1c-.275-.658-.77-1.31-1.34-2-.484-.613-1-1.254-1.43-2zM1 9v2h2V9zm0 4v1a1 1 0 0 0 1 1h1v-2zm4 0v2h2v-2z" fill="url(#a)"/></svg>

^ Smaller SVG

@YuriSizov
Copy link
Contributor

From the technical POV, one thing that is not resolved here is sizing resolution. The way it behaves currently basically means that the StyleBoxMulti itself needs to have margins configured, and that the default minimum size resolution is used. Internal styleboxes do not contribute to it in any way and their possibly custom ways to resolve the minimum size are ignored. I'm not sure that would be the expected behavior.

@aaronfranke aaronfranke deleted the style-box-multi branch August 17, 2023 16:42
@AThousandShips AThousandShips removed this from the 4.x milestone Aug 17, 2023
@rainlizard
Copy link
Contributor

@aaronfranke did you ever finish a StyleBoxMulti addon? I'd love to use it.
Or maybe there's already something similar inside the asset library? It's difficult to browse.

@aaronfranke
Copy link
Member Author

aaronfranke commented Feb 21, 2024

@rainlizard Here you go:

@tool
@icon("style_box_multi.svg")
## Style box that can draw multiple style boxes.
## It can be used to combine multiple style boxes into one.
class_name StyleBoxMulti
extends StyleBox

@export var style_boxes: Array[StyleBox] = []

func _draw(canvas_item: RID, rect: Rect2) -> void:
	for style_box in style_boxes:
		style_box.draw(canvas_item, rect)

And here is an SVG icon: style_box_multi

@rainlizard
Copy link
Contributor

@aaronfranke it works but there's a big problem in the editor, when you adjust one of the array's stylebox's values it's not updating instantly in the editor. You have to switch scenes then switch back in order for it to update it.

For example you set the border color to green, then nothing will change in the editor, so you switch to a blank scene then switch back and now the border color will be green.

v4.3.dev3.official [36e943b]

@theraot
Copy link
Contributor

theraot commented Feb 21, 2024

Here you go

@tool
@icon("style_box_multi.svg")
## Style box that can draw multiple style boxes.
## It can be used to combine multiple style boxes into one.
class_name StyleBoxMulti
extends StyleBox


@export var style_boxes: Array[StyleBox] = []:
	set(mod_value):
		if style_boxes == mod_value:
			return

		for style_box in style_boxes:
			if style_box == null or mod_value.has(style_box):
				continue

			if style_box.changed.is_connected(emit_changed):
				style_box.changed.disconnect(emit_changed)

		style_boxes = mod_value
		for style_box in style_boxes:
			if style_box == null:
				continue

			if not style_box.changed.is_connected(emit_changed):
				style_box.changed.connect(emit_changed)

		emit_changed()


func _draw(canvas_item: RID, rect: Rect2) -> void:
	for style_box in style_boxes:
		if style_box == null:
			continue

		style_box.draw(canvas_item, rect)

@rainlizard
Copy link
Contributor

Works perfectly, thanks theraot. This emit_changed stuff is tricky business.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a new type of StyleBox that draws other StyleBoxes
8 participants