Jump to content

Bug or Feature?

Recommended Posts

As the title says, I can't really tell if it's a bug or feature of IndirectUI, so I'm posting it here rather than under Bug Reports. The ColorWheelControl (possibly other controls as well, but I wasn't testing them for this behavior) seems to be extremely limited in accepting programmatic feed-forward state control, (as opposed to feed-back of user selections). In case that's too impenetrable, I'll try to explain what I mean.

While I was working out the best way to categorize all of my plugin's controls into different tabs (so that the UI looks less overwhelming AND fits on a screen w/o scrolling) I thought of adding a checkbox to randomly assign colors other than pre-selected primary/secondary (or, black and white, by default) to the ornament and the background. Inevitably, while flipping through these random combinations, some looked better than others, making me want to tweak either value or saturation to "fix" the look. However, I quickly discovered this was actually impossible to achieve: so long as the "random" color option is selected, you can only accept or reject the generated combination, while deselecting the "random" option resets the preview colors back to the default values.

At first, I thought this was fixable: a matter of setting the "internal" value of ColorWheel controls every time a new color pair is generated. But it turned out that the controls ignore any and all attempts to change their value that don't come from a user click. Actually, I couldn't even find a way to display the numeric RGB or HSV values of the randomly generated combinations, so they could be manually entered/selected in the ColorWheelControls (and adjusted from there).

This may well be the intended behavior - I really can't tell, but since it disallows something a user might reasonably want, I thought I ought to bring it up. For all I know, I could just be missing something.

Here's what I tried to get the controls to display another value:
in OnSetRenderInfo():

   scrollColor = ColorBgra.FromBgra((byte)colorPair[0][2], (byte)colorPair[0][1], (byte)colorPair[0][0], 255);
    backgroundColor = ColorBgra.FromBgra((byte)colorPair[1][2], (byte)colorPair[1][1], (byte)colorPair[1][0], 255);

    ColorBgra _scrollColor = ColorBgra.FromBgra((byte)colorPair[0][2], (byte)colorPair[0][1], (byte)colorPair[0][0], 255);
    ColorBgra _backgroundColor = ColorBgra.FromBgra((byte)colorPair[1][2], (byte)colorPair[1][1], (byte)colorPair[1][0], 255);
    token.SetPropertyValue(PropertyNames.ScrollColor, ColorBgra.ToOpaqueInt32(_scrollColor));
    token.SetPropertyValue(PropertyNames.BackgroundColor, ColorBgra.ToOpaqueInt32(_backgroundColor));
    //the following two lines are just to double check that the value ColorWheelControls really changed - they did, and showed up in preview
    //but were re-set by debugger-inaccessible code before the next call to OnSetRenderInfo
    scrollColor = ColorBgra.FromUInt32(unchecked((uint)token.GetProperty<Int32Property>(PropertyNames.ScrollColor).Value)).NewAlpha(255);
    backgroundColor = ColorBgra.FromUInt32(unchecked((uint)token.GetProperty<Int32Property>(PropertyNames.BackgroundColor).Value)).NewAlpha(255);

in OnCreatePropertyCollection():

//works as intended according to the debugger: i.e. control values change
    //but the values are not reflected by the visible state of the controls themselves
    propRules.Add(new SetTargetWhenSourceEqualsAnyValueRule(PropertyNames.ScrollColor, unchecked((int)scrollColor.Bgra), PropertyNames.ChkRandColor, true));
    propRules.Add(new SetTargetWhenSourceEqualsAnyValueRule(PropertyNames.BackgroundColor, unchecked((int)backgroundColor.Bgra), PropertyNames.ChkRandColor, true));


Anyway, it's hardly vital, but a nice-to-have I was kind of disappointed not to be able to provide. The rest is done and will be published shortly.

Link to comment
Share on other sites

IndirectUI is a closed, declarative system. You're trying to mix in some imperative logic, which it does not support. This is working exactly as intended.


Only the user, through the UI, is able to directly change the property values. Whenever you receive a PropertyCollection or a token, it is a copy of the data that the UI is using. Writing to it will never have any effect.


This is to ensure that there are no feedback loops -- it's very easy to produce a runaway loop where you see that property A equals B, so you set A to C ... and then elsewhere you see that A equals C, so you set it to B ... that's a contrived example, of course, but the complexity scales up very quickly with the number of properties and adjustments. And as for debugging these feedback loops? Good luck!

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...