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

Rewrite of TabView using modern v2 capabilities #3832

Draft
wants to merge 4 commits into
base: v2_develop
Choose a base branch
from

Conversation

tig
Copy link
Collaborator

@tig tig commented Nov 19, 2024

(this was originally in #3808, but that got screwed up. So this is a new PR with just the changes).

TabView is a great control for testing the library. It has a lot of capabilities that stretch the library. The v1 version was internally very complex in order to work around limitations in TG. In theory, v2 should enable making this control a lot simpler.

This PR is a WIP/Prototype that I started to determine if we're on the right track with these v2 capabilities:

  • Content scrolling - The TabRowView can/should just be a horizontally scrolling View where each Tab is just a subview. All the complex TabView logic for renering the Tabs and supporting scrolling can go away.
  • Layout - Dim.Auto, deferred layout, etc... should reduce the need for a lot of the internal complexity. Especially the complex layout math scattered around.
  • Drawing - There should be no need for TabView to draw lines directly. Each element can just be a View and leverage Border an automatic line joins currently enabled by SuperViewRendersLineCanvas
  • Navigation - How a user navs with the keyboard across Tabs, TabRowView, and the tab content is complex. The new v2 Nav system should make this easier.

Depends on

In #3798 auto-line join across Views is currently broken. I'm pausing work on this PR until I fix that.

Fixes

Proposed Changes/Todos

  • Prototype TabRowView that just uses content scrolling
  • Remove ContentView
  • Remove all complex LineCanvas stuff and just rely on Border

Pull Request checklist:

  • I've named my PR in the form of "Fixes #issue. Terse description."
  • My code follows the style guidelines of Terminal.Gui - if you use Visual Studio, hit CTRL-K-D to automatically reformat your files before committing.
  • My code follows the Terminal.Gui library design guidelines
  • I ran dotnet test before commit
  • I have made corresponding changes to the API documentation (using /// style comments)
  • My changes generate no new warnings
  • I have checked my code and corrected any poor grammar or misspellings
  • I conducted basic QA to assure all features are working

@tig tig self-assigned this Nov 19, 2024
@tig
Copy link
Collaborator Author

tig commented Nov 19, 2024

The design:

  • TabView - A host of mutiple Tabs which are displayed horizontally above or below. One tab at a time can have focus, and when it does, that tab's content is displayed and the user can interact. The TabView class has ONE subview of type TabRowView. This subview is aligned either at the top (Y = 0) or bottom (Y = Pos.AnchorEnd) and fills the TabView horizontally.
    • Uses an int based system for indexing on the tabs (e.g. SelectedTabIndex)
    • Listens to the Selecting event on TabRow - the index of the tab that was clicked on is passed in the CommandContext. The SelectedTabIndex is set based on this.
  • **TabRow ** - The host of the Tab objects for a TabView. Each Tab is simply added as a Subview, thus the list of Tabs is stored in this class (and accessable via the strongly typed TabRow.Tabs). Scrolls the Tabs horizontally within it's Viewport (the ContentSize is set to the sum of the widths of all the Tabs). Includes two scroll buttons that are made visible when needed to enable mouse scrolling across the tabs.
    • When the user clicks on a tab, presses it's hotkey, or changes focus to a tab and presses Space, the Selecting event is raised (see above).
  • Tab - Represents one of the tabs in the TabView. Holds a reference to a developer provided View as Tab.View that is activated when the Tab has focus.
    • When added to TabView via TabView.AddTab the Tab gets added to TabView._tabRow as a subview. TabRow takes care of changing the Tab.Border and Tab.Margin (as well as dimensions) such that the tabs render nicely as "tabs" simply leveraging the Border line rendering code. (Not complete in current WIP).

Screenshot of current code:
image

This is in AllViewsTester utilizing this

    public bool EnableForDesign ()
    {
        AddTab (new () { Text = "Tab_1", Id = "tab1", View = new Label { Text = "Label in Tab1" } }, false);
        AddTab (new () { Text = "Tab _2", Id = "tab2", View = new TextField { Text = "TextField in Tab2", Width = 10 } }, false);
        AddTab (new () { Text = "Tab _Three", Id = "tab3", View = new Label { Text = "Label in Tab3" } }, false);
        AddTab (new () { Text = "Tab _Quattro", Id = "tab4", View = new TextField { Text = "TextField in Tab4", Width = 10 } }, false);

        return true;
    }

This is vastly different design than the old design that SHOULD result in a far simpler and performant system. It aslo completely leverages new v2 infrastructure.

The current prototype has the following issues that need to be addressed:

  • The bottom line in the TabRow does not go all the way to the right past the last tab.
  • Scrolling of the Tabs in TabRow is not quite right. Needs tweaking.
  • A bunch of legacy code still exists in TabView

@tig tig mentioned this pull request Nov 19, 2024
9 tasks
@BDisp
Copy link
Collaborator

BDisp commented Nov 19, 2024

That is how the PR #3828 does. The image is similar than I included in SetLayoutTests.cs unit test. That ugly initially and I want to see how you'll handle this without hacking line canvas.

@tig
Copy link
Collaborator Author

tig commented Nov 19, 2024

That is how the PR #3828 does.

No, #3828 does not do what this PR does. Not even close. Please study this PR first.

The image is similar than I included in SetLayoutTests.cs unit test. That ugly initially and I want to see how you'll handle this without hacking line canvas.

Ahhh, you didn't notice this:

https://gui-cs.github.io/Terminal.GuiV2Docs/api/Terminal.Gui.LineCanvas.Exclude.html#Terminal_Gui_LineCanvas_Exclude_Region_

In addition, auto-linejoin/SuperViewRendersLineCanvas is still not working quite right.

PLUS, Border is still doing custom LineCanvas work which makes it inflexible for this use: #3407

If each side of the Border is a Line that can be separately configured we should be able to nail this easily.

@BDisp
Copy link
Collaborator

BDisp commented Nov 19, 2024

But I'm still curious how you will accommodate a Tab.View property as TabView subview with border but with a limited height, as TextField has, for the case where the available TabView height is grater.

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