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

Fixes #2114. 3D Effect #3376

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

Fixes #2114. 3D Effect #3376

wants to merge 237 commits into from

Conversation

tig
Copy link
Collaborator

@tig tig commented Apr 2, 2024

Fixes

Todo

  • Extend Margin to have a "Shadow" Style - When enabled draws the correct half-height block glyphs in the right places
  • Extend HighlightStyle to support shadow animation on Pressed
  • Enable Button to use Margin.EnableShadow
  • Figure out how to make Button with shadow work reliably and automatically.
  • Figure out how to have the shadow account for whatever was drawn below. Right now, it blindly overwrites and thus doesn't look right in some situations. I think the right design is to have Margin.Draw get called by Application, not the View's SuperView.
  • Test & Enable EnableShadow on other Views where it may make sense visually.

Background

When I created Frames (now Adornments) i had a vision that Margin could be used to enable the 3D effect that we had mostly working in v1, but got negated with all the changes to v2.

I had a shower thought recently on this and decided to quickly code a prototype up to see if my instincts were right.

This PR demonstrates that I was. The concept is leveraging Margin like this:

 var button = new Button
 {
     X = Pos.Center (),
     Y = Pos.Center (), Text = "Press me!"
 };
 button.Margin.Thickness = new Thickness (0, 0, 1, 1);
 button.Margin.Add (
                    new View ()
                    {
                        X = Pos.AnchorEnd (1),
                        Y = 1,
                        Width = 1,
                        Height = Dim.Fill (),
                        ColorScheme = new ColorScheme (new Attribute (ColorName.DarkGray))
                    },
                    new View ()
                    {
                        X = 1,
                        Y = Pos.AnchorEnd (1),
                        Width = Dim.Fill(),
                        Height = 1,
                        ColorScheme = new ColorScheme (new Attribute (ColorName.DarkGray))
                    }
                    );

 bool pressed = false;
 button.Accept += (s, e) =>
                  {
                      pressed = !pressed;

                      if (pressed)
                      {
                          button.Margin.Thickness = new Thickness (1, 1, 0, 0);
                      }
                      else
                      {
                          button.Margin.Thickness = new Thickness (0, 0, 1, 1);
                      }
                  };

XZjxkvE 1

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
Copy link
Collaborator Author

tig commented May 27, 2024

This illustrates an issue with my current design here:

OXKUNLd 1

Need to figure out how to have the shadow account for whatever was drawn below. Right now, it blindly overwrites and thus doesn't look right in some situations. I think the right design is to have Margin.Draw get called by Application, not the View's SuperView.

@dodexahedron
Copy link
Collaborator

That's kinda been a long-standing conundrum, hasn't it?

What order to draw things in, I mean.

Since we don't have an explicit concept of Z index, it's all just order dependent, which is something that can change at runtime as views are created and destroyed.

As far as what color to use, I've got blend code that's aimed at true color but works for lame color too. I may have even put at least some of it in when I did that work on the Color type a while back. 🤔

@@ -198,6 +198,9 @@ public LineStyle LineStyle

private bool _showTitle = true;

/// <summary>
/// Gets or sets whether the title should be shown. The default is <see langword="true"/>.
/// </summary>
public bool ShowTitle
Copy link
Collaborator

Choose a reason for hiding this comment

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

I just had a thought about this (in general - not just for this property on this class) that I want to test out at some point.

Since we do not have constructors and are thus using a property-based dependency model, I wonder how these might behave if set to a different value in an initializer, especially if other properties any property setter depends on may have already been set. 🤔

My thinking is that it's a potential for strange NullReferenceExceptions and potential slow resource leakage due to event subscriptions from objects whose references haven't even been pushed onto the evaluation stack yet.

Purely theoretical but making the note both for myself and in case anyone already has specific insight on that behavior in the CLR.

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

3 participants