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

Composite (multiple) selections are now available #387

Merged
merged 33 commits into from Feb 18, 2022

Conversation

tannerhelland
Copy link
Owner

Relates to #310

Over a year in the making, this giant overhaul of PhotoDemon's selection tools is finally ready for wider testing.

All selection tools now support "combine" modes, including Add, Subtract, and Intersect behavior. You can combine any type of selection with any other type of selection, and all PhotoDemon brushes, tools, filters, and effects - including Select menu filters ("grow", "shrink", "feather", etc) - work with these new "combined" selections.

As a huge improvement over many other photo editors, PhotoDemon still allows you to interactively edit the last selection you created. When you release the mouse, your selection is not instantly "merged" - instead, you can continue to move, resize, or reshape it to your liking. This works even when combining multiple selections, which is something even Photoshop does not offer.

As part of this massive overhaul, PhotoDemon's selection tools now come with an updated rendering engine. Unlike the old engine - which required you to choose between rendering modes like "marching ants" or "highlight", the new engine allows you to mix and match rendering features to your liking. You can now easily turn outline animation on or off, and you can toggle interior and exterior region highlighting (with full control over color and opacity) in combination with the selection's outline. By default, PhotoDemon will highlight selected regions only when combining selections, but will otherwise stick to a plain "outline" mode to avoid obscuring your images.

I have spent an enormous amount of time testing and debugging this new engine, but given its extreme complexity, there is always some potential for bugs. Please notify me if you encounter any unexpected behavior, or if any selection features don't behave how you expected.

Thank you to all PhotoDemon users for their patience as I've tackled this extremely challenging project - and an extra special thanks to PhotoDemon's Patreon supporters. I am grateful for all of you.

I'm gonna call 2+ merged selections "composite" selections for coding convenience.  Parts of the selection interface that return composite selection data will now be titled accordingly
…revious selection (if any)

Also, enable the UI elements for combine mode.  Eek!
...so we can add a new step at the beginning that caches the old selection data
This commit is just a placeholder, and only "add" combine mode is implemented, but for the first time in PhotoDemon history, the program is capable of functional multiple selection support.

This is a placeholder commit because there are a billion details still to work out, including a lot of critical feature work, but the core fundamentals are all in place and they work without crashing the app.  I honestly had my doubts that I would ever make it this far... but hey, hope springs eternal!

This commit may not look like it contains much code, but there are approximately two thousand rounds of work that were written then deleted as I tried to to graft multiple selection behavior onto PD's ancient selection engine.  A lot of attempts didn't go well so I had to back up and start over, but I finally think I've arrived at a solution that won't require a total rewrite of the app.  (In a perfect world, that would be lovely and probably produce a much tidier selection engine core, but I don't have infinite time so I have to be practical about how I implement new features.)

A lot of debug messaging is strewn throughout this commit, but don't worry - I'll deal with these as I work through the known bugs associated with those program areas.

Next up is getting border rendering working correctly when multiple selections are active (only masks are calculated right now), then I need to get "subtract" and "intersect" modes working.  Then there are a ton of UI issues left to solve.... but the worst of this project is finally in the past, I think.
…mposite selections

Looks gooooood and it's fast!  Woohoo!
This was mostly just flipping some internal switches, but omg YES IT ACTUALLY WORKS
Composite selections now work with Undo/Redo, allowing you to move forward/backward through selection assembly steps.
… them

This behavior was always weird because it doesn't work between other selections (e.g. why couldn't you hot-swap a rectangular selection to a polygon one?).  It also causes issues with the new multiple-selection support.

So this special case has now been removed, and switching between rectangular and elliptical selection tools now behaves like swapping between all other selection tools.

I've also added a new technique for converting a composite selection to a "normal" selection.  This frees up a lot of memory and improves selection performance when e.g. painting onto a composite selection.  I will be triggering this technique from many more places as work on this feature continues.
…lections

Before this commit, it only worked if you clicked within the last selection added.  Now it's working correctly!

(another bug solved, 99 more to go...)
…posite mode

In the past, doing something invalid like creating a selection that lies entirely off-image would simply end by erasing the selection when you release the mouse.  But this approach is bad when composite selections are involved, because you potentially erased other valid selection regions.

So instead, PD now erases only the last interaction but retains previous ones.

As of now, rectangular and elliptical composite selections appear to be working quite well.  Time to tackle polygon selections next!
Placeholder commit only

(I had to break this to make square and elliptical selections work, and I want to be able to back-up here if the next phase of work goes horribly)
Polygon selection transforms are broken, however (ugh).
Oh boy, this project is getting close to completion!
Many other bug-fixes in this commit (as I test various esoteric setting combinations).  This feature is looking more and more solid!
There are a lot of edge cases still to test (like creating selections that do not intersect at all), but "normal" interactions are working well.
Buttons with icons, like all other software!  This reduces the need for two clicks to change combine mode (one to drop the dropdown, another to select).
Probably gonna need a few rounds of this before going live with the new selection feature(s)
We have enough information to fill the region created by the merged selections (old and new) and can display it in real-time, which is neat!

I'm currently debating wider changes to the appearance of PD's selections, but these will likely wait until this branch is merged.
This is critical for "subtract" and "intersect" combine modes, as you could e.g. create a small rectangle selection, then create a large rectangle around it in subtract mode - which effectively causes "select none" behavior.

PD will now auto-detect this state at _MouseUp and trigger "Select None" accordingly.
Shift: Add to selection
Alt: Subtract from selection
Shift+Alt: Intersect with selection

This is the same behavior as Photoshop, GIMP, etc
If shift is pressed BEFORE _MouseDown, it signifies "add to existing selection" combine mode.

If shift is pressed AFTER _MouseDown, it signifies "constrain to square proportions" (for rectangular and elliptical selections).

This mirrors identical behavior in Photoshop
New selection tools call for a new rendering engine.  With this comes an overhaul of PD's exposed "selection UI" toggles on the various selection toolbars.

The previous exclusive modes (highlight OR marching ants OR lightbox OR outline) are now condensed into one rendering model.  Selections are always drawn as outlines by default, but you can also "add" interior or exterior fills to the UI.

By default, interior fills activate *only* when combining selections.  This is useful for seeing what the final result of e.g. an Intersect combine operation will be (without obscuring your view otherwise).

If you want a constant interior fill mode, a la Paint.NET, just set the "fill interior" setting to "always".

Similarly, you can now toggle a "fill exterior" mode to mimic Photoshop's "Quick Mask" mode.  (This behavior is turned off, by default.)  I expect this to be useful when I add a "selection brush" tool in the future.

A lot of new user preferences were required for these new features.  Also, the new rendering code is ugly and chaotic.  I will clean it up soon - promise!
Interactive performance of composite selections is now even closer to standalone selections, and I've still got a few tricks left to attempt.  But this commit includes some critical bug-fixes for magic wand selections so please switch to it ASAP!
Performance on 20+ megapixel images is looking pretty good now (for a single-threaded implementation, anyway).

Time to move onto fixing up the Select menu "filters"!
Selection filters (like grow, shrink) need to merge composite selection data into a single mask before they run
...I think this branch is almost ready to merge?  All that's left on my todo list is generating new localization files...

*nervous breathing commences*
Combine mode tooltips also show their corresponding hotkeys now.
@tannerhelland tannerhelland merged commit 1eeb35f into master Feb 18, 2022
@tannerhelland tannerhelland deleted the multiple-selections branch February 18, 2022 18:11
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.

None yet

1 participant