Skip to content

Color pickers for SimpleEffectDialog#1611

Merged
cameronwhite merged 31 commits into
PintaProject:masterfrom
Lehonti:feature/simpleeffectdialog_color
Jul 22, 2025
Merged

Color pickers for SimpleEffectDialog#1611
cameronwhite merged 31 commits into
PintaProject:masterfrom
Lehonti:feature/simpleeffectdialog_color

Conversation

@Lehonti
Copy link
Copy Markdown
Contributor

@Lehonti Lehonti commented Jul 10, 2025

Could close #1501 , or should we wait for further milestones?

It is using a Gtk.ColorButton, which opens the standard (and quite limited) Gtk color selection dialog. In the future, we might want to use Pinta's amazing color picker dialog. The main stopper is that it still needs a lot of refactoring to be viable

The first commit is the change itself.

The second commit is the demo.

The third commit is the reversal of the demo.

grafik

Copy link
Copy Markdown
Member

@cameronwhite cameronwhite left a comment

Choose a reason for hiding this comment

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

IMO we really should be using the same color picker dialog here - what are the issues blocking that from being doable? From what I recall it can be launched to edit a single color, like when you middle-click on a palette color

? c
: ColorBgra.FromBgra (0, 0, 0, 255);

Gdk.RGBA initialColorGdk = new () {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Gdk.RGBA is unpremultiplied alpha, like Cairo.Color, so these conversions aren't correct if the ColorBgra has premultiplied alpha (which it should - see also #1553)

Alpha = initialColor.A / 255f,
};

Gtk.ColorButton colorButton = Gtk.ColorButton.NewWithRgba (initialColorGdk);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd be interested to see how it looks with some maximum width, so that it doesn't stretch across the entire dialog.

};

Gtk.ColorButton colorButton = Gtk.ColorButton.NewWithRgba (initialColorGdk);
colorButton.OnColorSet += (_, _) => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

One other note is that Gtk.ColorButton was deprecated in GTK 4.10, with Gtk.ColorDialogButton as its replacement. Although, I'm not sure if either can be used to launch our own color picker dialog

@Lehonti
Copy link
Copy Markdown
Contributor Author

Lehonti commented Jul 11, 2025

@cameronwhite I tried to address your concerns in the last three commits.

As for your question about the color picker dialog, I haven't checked in detail (it's a very long piece of code and haven't found the time), but the palette service gets passed to the constructor, and events get hooked to it, and that makes me think the dialog is tightly coupled to the palette. I might be wrong, though.

Part of the longer-term vision of my cumulative refactorings is to make it obvious if some component is safe to use or not.

As for using ColorDialogButton to open our dialog, I think it's possible. If no ColorDialog has been assigned, it won't open it, and then we could hook to the Click signal/event

@cameronwhite
Copy link
Copy Markdown
Member

Thanks, I think my only additional suggestion would be putting the ColorBgra -> Gdk.RGBA conversion functions as methods on those types, so that we don't reinvent the code if it's needed elsewhere in the future.

Re: color picker dialog, I'm pretty sure those event handlers are only set up when the live palette mode is being used, so I suspect it wouldn't be a large project to make that more clear with some refactoring.
I really think we should be using the same color picker dialog here - being inconsistent and using a different color picker UI in the effect dialog isn't something I want to introduce

@Lehonti
Copy link
Copy Markdown
Contributor Author

Lehonti commented Jul 14, 2025

Thanks @cameronwhite. I just moved the conversions to extension methods. I will look into using our color picker dialog as soon as I can find the time.

@cameronwhite
Copy link
Copy Markdown
Member

Thanks!
For the extension methods, how about shifting them to GdkExtensions.cs (or a sub-file) since they're specific to converting to Gdk types?

@Lehonti
Copy link
Copy Markdown
Contributor Author

Lehonti commented Jul 15, 2025

Yeah, GdkExtensions looks like an appropriate place for them :)

@Lehonti
Copy link
Copy Markdown
Contributor Author

Lehonti commented Jul 17, 2025

I just checked, and I think it's unlikely that we can use the GTK ColorDialogButton for this (since it appears not to have a Click signal/event), so I created a custom button.

The methods that convert to Gdk.RGBA are no longer needed, so I removed them.

An issue (that should go away with time and refactoring) is that PintaCore was re-introduced in SimpleEffectDialog


ImageSurface tileSurface = new (Format.Rgb24, TILE_SIZE, TILE_SIZE);

using (Context sc = new (tileSurface)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could this use CairoExtensions.CreateTransparentBackgroundPattern?

cr.SetSource (checkeredPattern);
cr.Paint ();

cr.SetSourceRgba (
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cr.setSourceColor(display_color) should work here to be a bit more concise

? c
: ColorBgra.Black;

Color currentColorCairo = currentColorBgra.ToCairoColor ();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this also needs to convert the alpha :)
For now it's fine to just do currentColorBgra.ToStraightAlpha().ToCairoColor() and the inverse afterwards - as part of #1553 we'll fix ToCairoColor() to always convert

@Lehonti
Copy link
Copy Markdown
Contributor Author

Lehonti commented Jul 20, 2025

I tried to address each of your points in their own commit @cameronwhite. I haven't had a lot of time to check, but isn't considerable precision lost when doing this conversion?

ColorBgra newColorBgra =
	newColorCairo
	.ToColorBgra ()
	.ToPremultipliedAlpha ();

@cameronwhite
Copy link
Copy Markdown
Member

Thanks! Will do some more testing later

Re: premultiplied alpha, that's correct that less precision is available for the channels when alpha goes toward zero

@cameronwhite
Copy link
Copy Markdown
Member

Thinking about this more, perhaps we should only support Cairo.Color here for simplicity, and avoiding any confusion from users about why transparent colors can be different when you close and then re-open the effect dialog

It's pretty easy for an effect to convert to ColorBgra, and isn't any different from how e.g. the palette colors are stored

@Lehonti
Copy link
Copy Markdown
Contributor Author

Lehonti commented Jul 21, 2025

I just removed the handling of ColorBgra properties @cameronwhite.

I'm thinking that, longer-term, we would probably be able to re-add it if no conversions need to take place, but for that to happen lots of refactoring still need to take place, of course

@cameronwhite
Copy link
Copy Markdown
Member

Thanks!

I think the conversion is inevitable though - since we want the user to select a color using straight alpha in the color dialog, the setting should also be stored in straight alpha and only converted to premultiplied alpha when going into the Cairo surface

@cameronwhite cameronwhite merged commit 199c382 into PintaProject:master Jul 22, 2025
6 checks passed
@Lehonti Lehonti deleted the feature/simpleeffectdialog_color branch July 22, 2025 05:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Color picker control for SimpleEffectDialog

2 participants