-
-
Notifications
You must be signed in to change notification settings - Fork 22.3k
Add inline color pickers to script editor #105724
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
base: master
Are you sure you want to change the base?
Conversation
I think we should have a corresponding setting in the editor settings to turn this display mode on and off |
Actually it's probably fine, but a note should be added to the documentation to mention that if it's |
7a046ab
to
06e3ad7
Compare
Ok I applied all the changes by @bruvzg, and added an editor setting to enable / disable this. Also rebased just in case. (Also the parse and string functions were moved upwards to be available in |
scene/gui/text_edit.cpp
Outdated
inline_color_start = i_start; | ||
inline_color_end = i_end; | ||
|
||
Vector2 xf_mpos = mb->get_global_position(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vector2 xf_mpos = mb->get_global_position(); | |
Vector2 xf_mpos = mb->get_position() + get_screen_position(); |
Or it will be off if the editor window is not maximized/not on the primary screen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I know, this looks to be the first feature that makes it so that what is displayed in the TextEdit does not exactly match its underlying text.
This could open the door for more personalized displays, such as parameter names, akin to other IDEs. There was a proposal about this but I cannot find it at the moment.
Either way, I think this is a bit too niche to be exposed to the scripting API, and it's a good thing it's not in this PR...
Isn't the code for this too invasive? It affects TextEdit directly for no justifiable reason, I feel.
doc/classes/EditorSettings.xml
Outdated
@@ -1216,6 +1216,9 @@ | |||
<member name="text_editor/appearance/caret/type" type="int" setter="" getter=""> | |||
The shape of the caret to use in the script editor. [b]Line[/b] displays a vertical line to the left of the current character, whereas [b]Block[/b] displays an outline over the current character. | |||
</member> | |||
<member name="text_editor/appearance/enable_inline_color_picker" type="bool" setter="" getter=""> | |||
If [code]true[/code], colored buttons will appear before color constructors. Clicking them will popup a color picker for visually editing the color's parameters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A link to the Color Variant type is important, I feel.
If [code]true[/code], colored buttons will appear before color constructors. Clicking them will popup a color picker for visually editing the color's parameters. | |
If [code]true[/code], displays a colored button before any [Color] constructor in the script editor. Clicking on them allows the color to be modified through a color picker. |
Perhaps ColorPicker, too, but not as much, and it does not parse right for localization.
Well all TextServer access happens in TextEdit, so objects need to be added in there. But I get what you mean that its weird for color picker code to be in TextEdit. Maybe I can generalize it a bit and move the color related stuff into ScriptTextEditor or CodeEdit, and have TextEdit only call it through Callables
Yeah I'll move color picker to that or CodeEdit too |
1e90fb9
to
f99a6f3
Compare
Ok I generalized everything in TextEdit, so it can be used for adding any inline objects with 0 span. All color related functionality was moved to ScriptTextEditor. I added enums and validation functions to make it easier to understand & build off of in the future. Also applied the suggestions. (I'm not sure why the tests are failing. That line passed before and I haven't changed anything in color_picker.h or color_picker.cpp) |
It looks like in #105892 ColorPicker's |
c380b1f
to
a921f7e
Compare
Ok that worked. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Supersedes Editor: add gutter to preview and update inline colors in the script and shader editors #76171
Ideally the color parsing and text replacing would be separated to GDScript ScriptLanguage or somewhere, but there are lots of other GDScript specific things in the script editor, so it's fine for now.
Parsing should make sure that it only gets color constructors and not functions that end with Color
:
The mouse cursor should change to indicate the color box can be clicked.
Selecting color objects should probably show the selection background behind it.
scene/gui/text_edit.h
Outdated
enum InlineInfo { | ||
INFO_LINE, | ||
INFO_COLUMN, | ||
INFO_WIDTH_RATIO, // Used to determine the object's width given a line height. | ||
INFO_MAX | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if we use enums like these very often, as array indexes.
Its probably better to use a Dictionary instead of Array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not odd. If you think about it this is akin to the constants used for PopupMenu items. Not sure of the context here, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PopupMenu constants are used to distinguish which action to do based on the button, so only one callback is needed, but here it's used to transfer data generically in an Array with various types.
Like this:
Array color_info;
color_info.resize(INFO_COLOR_MAX);
color_info[TextEdit::INFO_LINE] = p_line;
color_info[TextEdit::INFO_COLUMN] = i_start;
color_info[TextEdit::INFO_WIDTH_RATIO] = 1.0;
color_info[INFO_COLOR_END] = i_par_end;
color_info[INFO_COLOR] = Color(color_string);
So it's already basically being used like a dictionary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it even have to be either one of the two? Can it not be a struct here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has to be a variant to be added as a object to TextServer. A struct can't do that (as far as I know)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion using Arrays here is okay, as a strictly "server-sided" operation. It occupies less memory and doesn't need to be dynamic. It reminds me of the way ArrayMesh works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with either if array is better for memory / performance, though I did already transition to Dictionary locally. It might also be better in case it gets exposed in the future
There is another syntax supported for Colors, but it's probably the least used - integer colors, e.g. |
Still, if not supported it may be deemed to be a bug down the line. |
There's more constructors that aren't supported, I thought it was intentional. |
I have an updated commit ready for all kitbdev's fixes, but my wifi is out so I'll have to push tomorrow or something
The way I have it set up now, the used syntax is just whatever tab is selected in the color picker, and if the hex toggle is enabled it uses a hex string. But that limits it to just those 4 constructors. Would it be better to just ignore the tab, and instead repurpose the hex button to cycle between all the constructors. I think vscode does that |
a921f7e
to
12e9f9f
Compare
Alright wifi came back. Summary of fixes:
It seems that ScriptTextEditor already forces hover tooltip to enabled anyways (not based on some setting like I thought), so I got rid of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous issues are fixed.
When using word wrap and a line with a color object is wrapped, I get this error:
ERROR: modules\text_server_adv\text_server_adv.cpp:7137 - Condition "!sd->objects.has(p_key)" is true. Returning: Rect2()
12e9f9f
to
09f31e5
Compare
Ok new commit implementing the fixes, and added support for hex integers. I changed it so that you now choose a constructor from a dropdown, rather than it being tied to which tab the color picker is on. This enables any number of constructors in the future. I also simplified the code a bit to make adding & reordering constructors easier. Here's a demo: 2025-05-04.21-17-35.-.Trim.mp4Also after testing more while considering word wrap, I found a few bugs relating to object hover / click position, so had to rework that a bit. The weird indentation offset code is just how its calculated in other places too |
09f31e5
to
5aadb88
Compare
5aadb88
to
bba34b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works well.
editor/plugins/script_text_editor.h
Outdated
MODE_STRING, | ||
MODE_HEX, | ||
MODE_RGB, | ||
MODE_HSV, | ||
MODE_OKHSL, | ||
MODE_RGB8, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MODE_STRING, | |
MODE_HEX, | |
MODE_RGB, | |
MODE_HSV, | |
MODE_OKHSL, | |
MODE_RGB8, | |
MODE_RGB, | |
MODE_STRING, | |
MODE_HSV, | |
MODE_OKHSL, | |
MODE_RGB8, | |
MODE_HEX, |
Or something like this, so the more common ones are first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delayed this a bit but I just pushed with the updated order. Also made the option list's font the same as the code editor, for readability
bba34b6
to
84b4deb
Compare
Implements godotengine/godot-proposals#6653
The proposal already had a linked PR which added color buttons to the gutter.
This PR instead adds color buttons directly in the text area, and supports multiple colors per line, like in VSCode. Had to make some
text_server_adv
fixes to support objects with 0 span length.The following constructors are supported:
Color()
(Empty, an html color string, or 3-4 rgba values)Color.from_hsv()
Color.from_rgba8()
Color.from_ok_hsl
The mode / format of the constructor will match which mode is selected in the color picker. Video demo:
script_editor_color_picker.mp4