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

Show a preview of the control in the SUI #9527

Merged
merged 34 commits into from
May 17, 2021
Merged

Conversation

PankajBhojwani
Copy link
Contributor

@PankajBhojwani PankajBhojwani commented Mar 17, 2021

In the 'Appearance' tab of a profile, show a preview of what the control looks like

PR Checklist

@ghost ghost added Area-Settings UI Anything specific to the SUI Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. labels Mar 17, 2021
@zadjii-msft
Copy link
Member

  • We probably want more things in PreviewConnection

Thoughts:

  • We could just go with the text that was in the old propsheet preview:
    image
    but we could probably do better than that
  • We could do the whole color table,
    image
    but that requires 80 columns to display right, which is a lot. Plus that's maybe better suited for the color scheme page
  • What if we had something simple with default, red, and green text in it, like some git output?
    image

@zadjii-msft
Copy link
Member

Other random thought - should the preview be above the scroll viewer, so the preview is always visible as you scroll through the list of settings 🤔? @cinnamon-msft for design help here

Copy link
Member

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

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

Great work! Concerned about a few scenarios that I want to make sure we handle:

  • Resizing
    • Please resize the window and make sure it feels natural. We'll want some padding on the left and right side so that the TermControl is always visible.
    • If possible, reflow would be awesome. But I bet that's hard. I'm ok with that being a follow-up, if we even want to pursue it.
    • Make sure to test the smallest possible size of the window.
  • Interactivity
    • Can you select text in the TermControl? Originally, I thought we should. But we wouldn't be able to copy/paste, right? So maybe we should disable selection, and if people are interested, throw in selection/copy/paste via the mouse later?
  • Misc settings
    • Do the following profile settings do anything?
      • Retro terminal effects
      • Cursor shape & height
      • Acrylic and acrylic opacity
      • scrollbar visibility
  • Accessibility
    • Can you tab in/out of the TermControl?
    • What does the screen reader say when you are focused on the TermControl? (I can probably check this one after the PR is out of draft)
  • Preview Connection
    • Probably better for a future consideration, but it would be cool if we could have the header for the shell pop up. Like, CMD would do the "Microsoft Windows [Version..." and Pwsh would do "PowerShell 7.1.3 Copyright". But we'd need a way to figure out what the output is and that just sounds messy.
    • I'd also like it if we could get powerline in there, since that's really colorful. But again, that doesn't sound possible tbh.
    • Honestly, I'm tempted to say that we should just open a real terminal connection in there? It might be overkill, but it would allow users to display whatever they want. That said, I think I'm ok with some simple output like this for now, then doing a more complex one in a follow-up task.

src/cascadia/TerminalControl/TermControl.h Show resolved Hide resolved
Comment on lines +40 to +42
void PreviewConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept
{
}
Copy link
Member

Choose a reason for hiding this comment

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

Be sure to test what happens when you resize the window and the TermControl doesn't fit (or resizes). Idk how difficult it would be to add reflow, but I'm guessing we need something here?

Copy link
Member

Choose a reason for hiding this comment

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

Reflow will be impossible. On resize, the connection should simply clear the terminal and re-print the entire preview text.

Copy link
Member

Choose a reason for hiding this comment

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

The reason for this is that resize is a destructive operation when content is pushed off the top of the screen.

Copy link
Member

Choose a reason for hiding this comment

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

This method still needs to be implemented for that right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method still needs to be implemented for that right?

Ah it actually doesn't! The connection doesn't need to do anything

Copy link
Member

Choose a reason for hiding this comment

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

Wait, no.. on resize, the connection must re-print the entire preview text. Resize with reflow destroys the content that goes off the top of the screen, and the connection needs to clear the screen and put it back. Now, since we never resize the control this isn't going to be a problem... but do keep it in mind.

Comment on lines 216 to 218
<Border x:Name="ControlPreview"
Height="200"
Width="600"/>
Copy link
Member

Choose a reason for hiding this comment

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

A few things here:

  1. add a comment saying that this is where the terminal preview goes
  2. What happens if you resize the window? Maybe you'll want to set the MaxWidth instead?

Copy link
Member

@DHowett DHowett Mar 18, 2021

Choose a reason for hiding this comment

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

If only we had a normal constructor for the control, we could use <tc:TermControl Height="200"...

src/cascadia/TerminalSettingsEditor/Profiles.cpp Outdated Show resolved Hide resolved
@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Mar 18, 2021
@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

real connection

snippet from the shell

ABSOLUTELY NOT.

Imagine I make a profile that runs...

wsl -d Ubuntu rm -rf /home/dustin/profile_launched or whatever?
I'm typing it in, and I get to wsl -d Ubuntu rm -rf /home and well, there you go. Terminal decided to RUN THE COMMAND just to give me, what, a preview?

We don't want to spawn TWO NEW PROCESSES for every preview update, either.

The connection needs to be representative of what people use Terminal for. Powerline is not guaranteed (in the font); a shell is, emoji may be, etc.

I'm imagining that we have emoji in there, and some characters that might ligature together, and some colors. Not a lot of them (check the color scheme page for that). The emoji will change when you toggle colored emoji, etc.

@cinnamon-msft
Copy link
Contributor

Other random thought - should the preview be above the scroll viewer, so the preview is always visible as you scroll through the list of settings 🤔? @cinnamon-msft for design help here

Yeah I think this makes sense. I think it'll look okay once we change the Pivot to the horizontal NavView.

@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Mar 22, 2021
@mdtauk
Copy link

mdtauk commented Mar 22, 2021

Other random thought - should the preview be above the scroll viewer, so the preview is always visible as you scroll through the list of settings 🤔? @cinnamon-msft for design help here

Yeah I think this makes sense. I think it'll look okay once we change the Pivot to the horizontal NavView.

You may experience weirdness nesting a NavigationView inside another NavigationView

@PankajBhojwani
Copy link
Contributor Author

Misc settings
Do the following profile settings do anything?

  • Retro terminal effects
  • Cursor shape & height
  • Acrylic and acrylic opacity
  • scrollbar visibility

They all work except acrylic!

@carlos-zamora
Copy link
Member

They all work except acrylic!

I'm a bit conflicted on this. Definitely not blocking the PR for this, but we should probably file a follow-up to be able to provide a preview of the acrylic (if that's even possible).

But if it's not too much work for you to do it now, that'd be cool too ;) haha.

@github-actions

This comment has been minimized.

@PankajBhojwani
Copy link
Contributor Author

PankajBhojwani commented Apr 5, 2021

A few updates:

  • The preview connection now automatically sends the default text, as well as red/green/blue text
  • The preview connection no longer allows any input from the user
  • The control preview is now above the General/Appearance/Advanced tabs (so this automatically gives us the ability to scroll without losing sight of the control)
  • When the window width is <640 px, the control preview will resize itself to fit the window width (with a small margin on both sides), otherwise the control preview width is set at 640 - we probably want to do something similar for the height

@PankajBhojwani PankajBhojwani marked this pull request as ready for review April 7, 2021 16:26
@PankajBhojwani
Copy link
Contributor Author

Can you tab in/out of the TermControl?
What does the screen reader say when you are focused on the TermControl? (I can probably check this one after the PR is out of draft)

The preview term control is not focusable and cannot be tabbed in/out of! Also the height of the preview has been reduced by half so that the scroller below the pivot has more space. (can't post a screenshot because of secrets)

@carlos-zamora
Copy link
Member

Notes from Demo w/ @cinnamon-msft

  • Add a border to the preview (probably with the accent color?)
    • This'll help distinguish the preview background from the page background.
  • Cursor should just stay on (no blinking)
    • This'll make it look like it's not interactive.
  • Move terminal preview to be under the pivot control/selector
    • The space between the page header and the preview looks a little weird. This might fix that problem and make it look more natural.
  • Move the preview to be inside the "Appearance" pivot item
    • There's no need for us to be able to see the preview when in "General" or "Advanced", really. The entire purpose of this is to be a preview of the appearance, so it'll look nice if it's only in the "Appearance" item.
  • Align the preview to the left
    • I disagree with Kayla on this one, but who knows, maybe it'll look good. She has a better eye for this stuff than I do, generally.

Content inside the preview

  • People probably want to see something more like a prompt. Kayla and I came up with this...
Windows Terminal
Copyright (c) Microsoft Corporation.

C:\Windows\Terminal>  <CURSOR>

I think it'll look nice and kinda match the initial output of PowerShell/CMD.

  • [punt] figure out a way to show selected text. Some ideas:
    • let you select text (I feel like this is the least appealing option here)
    • have some pre-selected text on the preview?
  • [punt] show colored text:
    • This one is weird. The preview in the ColorSchemes page is going to show this off a lot better with a full color table. So I think we should just revisit this topic once we get a preview in the ColorSchemes page
    • I'm not really too sure what the best approach here is, so that's why I think it's better to punt on it and get this in.
  • [punt + feature idea?] Allow multiple customizable previews:
    • Realistically, we'll never be able to make everybody happy, especially when you start taking into account that some people have a powerline theme (and it might be a custom one too). Maybe we should eventually allow users to import their own preview output? Like, they can import some kind of text file that is just gets output via the preview connection, and any color changing VT sequences get handled too?
    • This would be a huge undertaking and is definitely off topic, but I think this is a good example of future work that we can do after this feature goes in and we get some user feedback. 😊

Miscellaneous notes

  • "scrollbar visibility" doesn't do anything
    • It makes sense that it doesn't. We only show it if we're scrolled down.
  • good job on the scrolling behavior
    • the preview should always be visible, so it's nice that you can just make changes and immediately see them without having to scroll up. LOVE IT!
  • Acrylic works!!!!

@DHowett
Copy link
Member

DHowett commented Apr 9, 2021

  • The space between the page header and the preview looks a little weird. This might fix that problem and make it look more natural.

This is incompatible with keeping it visible while you scroll, which you loved.

  • Move the preview to be inside the "Appearance" pivot item

    • There's no need for us to be able to see the preview when in "General" or "Advanced", really. The entire purpose of this is to be a preview of the appearance, so it'll look nice if it's only in the "Appearance" item.

What about Advanced > Text Antialiasing, Advanced > Bell Notification Style, General > Tab Title, General > Tab Color (when we have tab preview), General > Icon?

  • Align the preview to the left

    • I disagree with Kayla on this one, but who knows, maybe it'll look good. She has a better eye for this stuff than I do, generally.

I think this will look bad.

Content inside the preview

  • People probably want to see something more like a prompt. Kayla and I came up with this...
Windows Terminal
Copyright (c) Microsoft Corporation.

C:\Windows\Terminal>  <CURSOR>

I think it'll look nice and kinda match the initial output of PowerShell/CMD.

The initial output of PowerShell/CMD is atrocious, and I see no reason for us to make that mistake again. We've been showing people how to customize
their shells for two years now, and it seems shortsighted for us to display a preview of what it used to look like in 1985.

We need to display, at the minimum: Colors. Emoji (because we will have a [disable emoji] [(x) use color emoji] switch, per user request). Italic text. Bold text (when we have bold.)
I don't care if Color is covered by the Color Schemes preview: it doesn't show up oiver a background image or over acrylic, because those aren't part of a color scheme.

All of those are not represented in the shell preamble.

...

  • [punt + feature idea?] Allow multiple customizable previews:

    • Realistically, we'll never be able to make everybody happy, especially when you start taking into account that some people have a powerline theme (and it might be a custom one too). Maybe we should eventually allow users to import their own preview output? Like, they can import some kind of text file that is just gets output via the preview connection, and any color changing VT sequences get handled too?
    • This would be a huge undertaking and is definitely off topic, but I think this is a good example of future work that we can do after this feature goes in and we get some user feedback. 😊

Hard veto. Absolutely not. There's no purpose apart from making ourselves feel accomplished.
We should make the preview as inclusive of normal person scenarios as we possibly can.

...

  • good job on the scrolling behavior

    • the preview should always be visible, so it's nice that you can just make changes and immediately see them without having to scroll up. LOVE IT!

This is incompatible with moving the preview under the pivot, as you suggested.

/cc @cinnamon-msft, since some of the refuted opinions might have been hers

@carlos-zamora
Copy link
Member

Move terminal preview to be under the pivot control/selector

This should be possible by doing the following:

<PivotItem x:Uid="Profile_Appearance">
	<Grid>
    	<Grid.RowDefinitions>
			<RowDefinition Height="Auto"/>
			<RowDefinition Height="*"/>
		</Grid.RowDefinitions>

		<Border x:Name="ControlPreview"
				Height="320"
            	Margin="8,0,8,0"
            	HorizontalAlignment="Stretch"
            	Grid.Row="0"/>

		<ScrollViewer Grid.Row="1">
			<StackPanel>
				<!-- All of the settings controls -->
		</ScrollViewer>
	</Grid>
</PivotItem

Tested it out myself, and that doesn't break the scrolling.

Now, the only question left is...

What about Advanced > Text Antialiasing, Advanced > Bell Notification Style, General > Tab Title, General > Tab Color (when we have tab preview), General > Icon?

This'll require a broader discussion on the design. Let's talk about this at our next sync meeting.

Align the preview to the left

I agree that this'll look bad too (sorry Kayla haha). But it should be a quick one-line change.

@PankajBhojwani mind making that change and sending it over to @cinnamon-msft (or even the team over email if you want). I think it's just a matter of visualizing it tbh.

Content inside the preview

This'll require a broader discussion on the design. Let's talk about this at our next sync meeting.

Copy link
Member

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

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

Honestly, it seems like most of the issues left are design-related.

Blocking for two reasons...

  1. we need consensus on the design (we'll talk about that in the upcoming sync meeting)
  2. resolution on using TerminalSettings::ApplyProfileSettings instead of TermControl::Settings setter

Also, don't forget to update the PR description.

Comment on lines 116 to 117
WINRT_PROPERTY(IControlSettings, Settings);

Copy link
Member

Choose a reason for hiding this comment

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

Mildly concerned here. I'm worried that somebody later will come along and call the setter, then accidentally completely break the TerminalSettings inheritance line this way.

Can we just expose TerminalSettings::_ApplyProfileSettings() and use that instead?

Copy link
Member

Choose a reason for hiding this comment

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

Omg, I'm realizing that I told you earlier to change this to WINRT_PROPERTY. I was looking at the code, not the architecture. Sorry! haha

Copy link
Member

Choose a reason for hiding this comment

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

I don't necessarily think this should be part of TS's public API.

Copy link
Member

Choose a reason for hiding this comment

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

Eh, fine. But I'm curious, why not?

Copy link
Member

Choose a reason for hiding this comment

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

I'm firmly opposed to the idea that TermControl has any concept of a Profile. It should be given a fully-constructed IControlSettings, and it's up to the application hosting the control to decide how to populate that object.

I agree that exposing the Settings setter is definitely a footgun. I don't have a better idea right now though...

Copy link
Member

Choose a reason for hiding this comment

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

I'm still confused about your (plural "you") hesitance on exposing TerminalSettings::ApplyProfileSettings and going with exposing a setter on TermControl::Settings. An inheritable TerminalSettings was designed to be that you would never have to set anything, just add children. TermControl does/should not have any knowledge of a TerminalSettings; it's only working with IControlSettings, I agree with that.

My proposal is that TerminalSettingsEditor (the "application hosting the control") calls control.Settings().as<TerminalSettings>().ApplyProfileSettings(preview). That's how we generally interact with a TermControl's settings anyways so it's not a crazy idea.

This proposal also doesn't expose the setter. In exposing the setter, there's a risk that someone will inevitably call the setter in TermApp and break the inheritance tree for TerminalSettings. The inheritance tree is becoming more and more important, especially as we added in AppearanceConfig (a great example of UnfocusedAppearance inheriting from DefaultAppearance, and how calling the setter could easily break everything).

If you don't feel that this shouldn't be a part of TS's public API, fine. But please give me more of a response than "nah" so I can learn from this.

Comment on lines 785 to 801
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<!--
Official guidance states that 640 is the breakpoint between small and medium devices.
Since MinWindowWidth is an inclusive range, we need to add 1 to it.
-->
<AdaptiveTrigger MinWindowWidth="641" />
</VisualState.StateTriggers>

<VisualState.Setters>
<Setter Target="ControlPreview.Width" Value="640" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
Copy link
Member

Choose a reason for hiding this comment

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

You can't do this by adding MinWidth="640" to the Border?
(or would it be MaxWidth="640"? I always get confused with visual states haha)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Omg you are completely right, we don't need this visual state manager at all! Thanks :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Had to add this back in because we now change the horizontal alignment with this, and for some reason that causes the preview to disappear into oblivion unless we also set the width

Comment on lines +40 to +42
void PreviewConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept
{
}
Copy link
Member

Choose a reason for hiding this comment

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

This method still needs to be implemented for that right?

@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Apr 9, 2021
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

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

I'm seeing a crash -- blocking for bug bash

@ghost ghost added Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Apr 23, 2021
@DHowett
Copy link
Member

DHowett commented May 11, 2021

Let's get the conflicts resolved! 😄

@PankajBhojwani
Copy link
Contributor Author

I am a bit concerned about using the TSF control's settings size here? We're a control -- we have a size of our own.

We use the control's width and height now!

What happens when the window is resized?

Nothing, the control's width and height are fixed

Please avoid hardcoding colors.

We use a system theme resource colour now :)

@zadjii-msft zadjii-msft assigned DHowett and unassigned cinnamon-msft May 12, 2021
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

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

Future design notes:

Having the TermSettings come out of the viewmodel is a good idea. If you embrace this, you can make the viewmodel send a settings change notification for TermSettings, and you can delete all of the UpdateSettings calls from Profiles itself. This would be letting the VM do the work for you.

For now, though: I'm going to apply my comments and merge this. Excellent work, and thank you for doing it!

Comment on lines +40 to +42
void PreviewConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept
{
}
Copy link
Member

Choose a reason for hiding this comment

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

Wait, no.. on resize, the connection must re-print the entire preview text. Resize with reflow destroys the content that goes off the top of the screen, and the connection needs to clear the screen and put it back. Now, since we never resize the control this isn't going to be a problem... but do keep it in mind.

src/cascadia/TerminalSettingsEditor/PreviewConnection.cpp Outdated Show resolved Hide resolved
BorderBrush="#333333"
BorderThickness="1" />
BorderThickness="1"
BorderBrush="{ThemeResource ToggleButtonDisabledBorderThemeBrush}"/>
Copy link
Member

Choose a reason for hiding this comment

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

As long as this.. uh, looks fine. I guess. It's a weird one to use-- we're not a toggle button 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an older commit! It uses SystemControlForegroundBaseMediumLowBrush

@DHowett DHowett merged commit f3cf321 into main May 17, 2021
@DHowett DHowett deleted the dev/pabhoj/sui_control_preview branch May 17, 2021 02:26
@ghost
Copy link

ghost commented May 25, 2021

🎉Windows Terminal Preview v1.9.1445.0 has been released which incorporates this pull request.:tada:

Handy links:

@ghost
Copy link

ghost commented Jul 14, 2021

🎉Windows Terminal v1.9.1942.0 has been released which incorporates this pull request.:tada:

Handy links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Settings UI Anything specific to the SUI Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a preview of your terminal to the Settings UI
6 participants