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

Refactor code so selection highlighting does not depend on platform supporting inverted blit mode. #123

Merged
merged 2 commits into from
Feb 1, 2022

Conversation

dmalec
Copy link
Collaborator

@dmalec dmalec commented Jan 17, 2022

Summary

This is one possible approach for handling text selection highlighting. Instead of using wxINVERT as a post-process step, it handles selection highlighting by setting the foreground and background when doing the initial draw of the characters. This brings it in line with the new approach for STANDOUT. This looks like it should work on OSX, Windows, and Linux.

Color Selection

One point that might particularly be worth discussing further - selection of colors for highlighting. It looks like it's possible to get the system preferred highlight colors using:

    wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
    wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);

This does carry the risk that the system background doesn't contrast with the current terminal background. This particularly caught me off guard on Ubuntu when I put the system in high contrast mode and found that the system's selection colors were identical to the terminal's default ones... so there's was no indication of what was selected. @brianharvey had touched on the point about contrast between the various colors in the discussion about STANDOUT.

This approach proposes trusting that the system will have adequate contrast between the two colors for highlighting; but, that we might have to dynamically decide which is foreground and background based on contrast with the current terminal background. It also treats selection highlighting as distinct from STANDOUT. This is just one approach I thought I'd put out there - I think there are other valid ways we could decide on the colors for this.

Examples from OSX Build

Default:
Screen Shot 2022-01-17 at 4 45 52 PM

With the background at a light blue (demonstrating the swap in system colors when highlighting):
Screen Shot 2022-01-17 at 5 05 28 PM

System setting for highlighting set to orange:
Screen Shot 2022-01-17 at 5 04 03 PM

Test Environments

  • OSX Catalina (10.15.7) w/ wxWidgets 3.0.5
  • Ubuntu Bionic (18.04.5) w/ wxWidgets 3.0.5

  • Windows 10 Home (1909) w/ wxWidgets 3.0.5

…upporting inverted blit mode.

Selection highlighting is now handled by checking when drawing characters if they are inside the
currently selected area or not. An appropriate foreground/background color is then selected for
drawing the character.
@jrincayc
Copy link
Owner

This sounds and looks reasonable (I'll review it later this week.)

Thanks.

Copy link
Owner

@jrincayc jrincayc left a comment

Choose a reason for hiding this comment

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

I think UpdateNormalizedTextSelection could be simplified, otherwise it looks fine.

wxTerminal.cpp Outdated
Comment on lines 1801 to 1820
{
if (m_sely1 == m_sely2 && m_selx1 > m_selx2) {
// Single row selection, from right to left
m_normalized_sel_x1 = m_selx2;
m_normalized_sel_y1 = m_sely1;
m_normalized_sel_x2 = m_selx1;
m_normalized_sel_y2 = m_sely2;
} else if (m_sely1 > m_sely2) {
// Multi-row selection, from bottom to top
m_normalized_sel_x1 = m_selx2;
m_normalized_sel_y1 = m_sely2;
m_normalized_sel_x2 = m_selx1;
m_normalized_sel_y2 = m_sely1;
} else {
// Single or multi-row selection, from top-left to bottom-right
m_normalized_sel_x1 = m_selx1;
m_normalized_sel_y1 = m_sely1;
m_normalized_sel_x2 = m_selx2;
m_normalized_sel_y2 = m_sely2;
}
Copy link
Owner

Choose a reason for hiding this comment

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

Hm, shouldn't this be something like:

if (m_selx1 > m_selx2) {
    m_normalized_sel_x1 = m_selx2;
    m_normalized_sel_x2 = m_selx1;
} else {
    m_normalized_sel_x1 = m_selx1;
    m_normalized_sel_x2 = m_selx2;
}
if (m_sely1 > m_sely2) {
    m_normalized_sel_y1 = m_sely2;
    m_normalized_sel_y2 = m_sely1;
 } else {
    m_normalized_sel_y1 = m_sely1;
    m_normalized_sel_y2 = m_sely2;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That specific approach won't quite work as it's not actually normalizing the rectangle (this was part of the original code that took me a bit to grok the mental model). If the selection is a single line, it does need to normalize the x values and things work reasonably intuitively. However, it gets interesting in multi-line.

For multi-line, the code will highlight:

  • from m_selx1 to the end of the first line
  • the entirety of all middle lines
  • from the beginning of the last line to m_selx2

So, for the multi-line case, m_selx_1 and m_selx_2 are independent of each other and dependent on the y values.

All that said, I could add additional commenting (or see if I can rework the variable names / code a bit more) in order to make this clearer. It's something it definitely took me a while to puzzle out when reading the original code as I was thinking along the same lines about normalizing the rectangle :)

Copy link
Owner

@jrincayc jrincayc Feb 1, 2022

Choose a reason for hiding this comment

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

Ah, in that case can you update the comment? (I made the mistake of assuming the comment "selection coordinates to be from top-left to bottom-right" was just for a box.) Thanks.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, good call out there - I suspect the method comment particularly dates from my early understanding and I forgot to update it as my understanding changed, mea culpa. Will do :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've updated the comments to try and better capture what's going on in the method - that said, game to revise further if needed.

@jrincayc
Copy link
Owner

(Also, I apologize for not getting to it in the week that I said I would.)

@dmalec
Copy link
Collaborator Author

dmalec commented Feb 1, 2022

No worries on timing :)

Copy link
Owner

@jrincayc jrincayc left a comment

Choose a reason for hiding this comment

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

Reviewed and tested, and I approve.

@jrincayc jrincayc merged commit 7834966 into jrincayc:master Feb 1, 2022
@jrincayc
Copy link
Owner

jrincayc commented Feb 1, 2022

Thank you for making selection work :)

@dmalec
Copy link
Collaborator Author

dmalec commented Feb 1, 2022

You're welcome, no worries :)

@dmalec dmalec deleted the wip_highlight_selection branch January 18, 2023 18:12
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.

2 participants