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

Add 3D Shadow Effect for Button and other views #2144

Closed
heinrich-ulbricht opened this issue Oct 31, 2022 · 40 comments
Closed

Add 3D Shadow Effect for Button and other views #2144

heinrich-ulbricht opened this issue Oct 31, 2022 · 40 comments
Assignees
Milestone

Comments

@heinrich-ulbricht
Copy link

heinrich-ulbricht commented Oct 31, 2022

Is your feature request related to a problem? Please describe.
Nope, just feature request I guess

Describe the solution you'd like
I'd like to add buttons like Norton Commander used back in the day. They had a half-height shadow at the bottom. But currently with Terminal.GUI it only seems to be possible to add a full-height shadow at the bottom. This is kind of fat for a small button. The shadow also needs to be set off vertically only half-height (or is it like 1/3?) on the right.

Here's what it should look like:
image

I looked at all the border samples in UICatalog but did not see such a feature. It might be impossible. Or is there some rune to configure? I'm not so deep in the code.

I'm currently playing around with color schemes and the 3D effect - not very shadowy for a small button:
image

Describe alternatives you've considered
Using no shadow for buttons.

@tznind
Copy link
Collaborator

tznind commented Oct 31, 2022

I agree that this would be a great core feature for the library. But in the mean time here is what you can do with the current release and overriding the Button redraw method.

image

using Terminal.Gui;

Application.Init();
var win = new Window("Example App (Ctrl+Q to quit)");

win.Add(new ShadowButton("Button 1"){
    X = 2,
    Y = 1
});

win.Add(new ShadowButton("Button 2")
{
    X = 20,
    Y = 1
});

Application.Run(win);
Application.Shutdown();

class ShadowButton : Button
{
    public ShadowButton(string text):base(text + " ") /*put a space on to leave 'shadow' room*/
    {
        Height = 2;
    }
    public override void Redraw(Rect bounds)
    {
        // draw regular button
        base.Redraw(bounds);

        // draw the 'end' button symbol one in
        AddRune(bounds.Width - 2,0, ']');

        // shadow color
        Driver.SetAttribute(new Terminal.Gui.Attribute(Color.Black, 
                Colors.Base.Normal.Background));

        // end shadow (right)
        AddRune(bounds.Width - 1, 0, '▄');

        // leave whitespace in lower left in parent/default background color
        Driver.SetAttribute(new Terminal.Gui.Attribute(Color.Black, 
                Colors.Base.Normal.Background));
        AddRune(0, 1, ' ');

        // The color for rendering shadow is 'black' + parent/default background color
        Driver.SetAttribute(new Terminal.Gui.Attribute(Colors.Base.Normal.Background,
                Color.Black));

        // underline shadow                
        for (int x = 1;x<bounds.Width;x++)
        {
            AddRune(x,1, '▄');
        }       
    }
}

UPDATE: From a little quick experimenting the 'three quarter block' renders as a question mark in PowerShell (out of the box windows 10). Only the 'half blocks' are there default. Same applies to some of the other fancier 'block' sizes.

Theres also a little 'bleed' on the right of the button where 1 pixel of terminal is black. Don't know if that is a font thing or a bug in powershell/visual studio console.

@tznind
Copy link
Collaborator

tznind commented Oct 31, 2022

For reference these are the blocks available (not all of which are supported by all terminals)

Block elements
2580 ▀ UPPER HALF BLOCK
2581 ▁ LOWER ONE EIGHTH BLOCK
2582 ▂ LOWER ONE QUARTER BLOCK
2583 ▃ LOWER THREE EIGHTHS BLOCK
2584 ▄ LOWER HALF BLOCK
2585 ▅ LOWER FIVE EIGHTHS BLOCK
2586 ▆ LOWER THREE QUARTERS BLOCK
2587 ▇ LOWER SEVEN EIGHTHS BLOCK
2588 █ FULL BLOCK
= solid
→ 25A0 ■ black square
2589 ▉ LEFT SEVEN EIGHTHS BLOCK
258A ▊ LEFT THREE QUARTERS BLOCK
258B ▋ LEFT FIVE EIGHTHS BLOCK
258C ▌ LEFT HALF BLOCK
258D ▍ LEFT THREE EIGHTHS BLOCK
258E ▎ LEFT ONE QUARTER BLOCK
258F ▏ LEFT ONE EIGHTH BLOCK
2590 ▐ RIGHT HALF BLOCK
Shade characters
2591 ░ LIGHT SHADE
• 25%
2592 ▒ MEDIUM SHADE
= speckles fill, dotted fill
• 50%
• used in mapping to cp949
→ 1FB90 🮐 inverse medium shade
2593 ▓ DARK SHADE
• 75%
Block elements
2594 ▔ UPPER ONE EIGHTH BLOCK
2595 ▕ RIGHT ONE EIGHTH BLOCK
Terminal graphic characters
2596 ▖ QUADRANT LOWER LEFT
2597 ▗ QUADRANT LOWER RIGHT
2598 ▘ QUADRANT UPPER LEFT
2599 ▙ QUADRANT UPPER LEFT AND LOWER LEFT
AND LOWER RIGHT
259A ▚ QUADRANT UPPER LEFT AND LOWER RIGHT
→ 1F67F 🙿 reverse checker board
→ 1FB95 🮕 checker board fill
259B ▛ QUADRANT UPPER LEFT AND UPPER RIGHT
AND LOWER LEFT
259C ▜ QUADRANT UPPER LEFT AND UPPER RIGHT
AND LOWER RIGHT
259D ▝ QUADRANT UPPER RIGHT
259E ▞ QUADRANT UPPER RIGHT AND LOWER LEFT
→ 1F67E 🙾 checker board
→ 1FB96 🮖 inverse checker board fill
259F ▟ QUADRANT UPPER RIGHT AND LOWER LEFT
AND LOWER RIGHT

http://www.unicode.org/charts/PDF/U2580.pdf

@BDisp
Copy link
Collaborator

BDisp commented Oct 31, 2022

I think setting the Border property with the Effect3D enabled on Button will do the trick.

@tznind
Copy link
Collaborator

tznind commented Oct 31, 2022

I think setting the Border property with the Effect3D enabled on Button will do the trick.

Effect3D uses a full border element and only has it below the Button.

Button3 uses the Effect3D while Button1 and Button2 use the ShadowButton implementation. Both look ok but I think the half box rendering looks nicer. But there are definetly issues:

  • How widely supported is 'half block'
  • How complicated do things get when we have to look at parents background color (shadow is 50% black + 50% 'background color'
  • How do we expose the new style nicely with API. It looks good for buttons but does it look good for Window? Do some controls want half border while others want full
  • The thin shadow effect shows the background color but not any text. That is going to look strange when the background the button 'floats' over has text on it.

Also the ShadowButton click area includes the shadow (clicks in shadow will focus/click the button) which is different... not sure if better or worse but definetly different.

image

win.Add(new Button("Button 3")
{
    X = 40,
    Y = 1,
    Border = new Border
    {
        Effect3D = true,
        Effect3DBrush = new Attribute(Color.Black,Color.Black),
    }
});

Heres what the shadows look like when theres a background that isn't just solid color. You can see the eye expects to see half an 'x' where that half shadow ends.

image

@tznind
Copy link
Collaborator

tznind commented Oct 31, 2022

I have to say the Norton Commander query box in OP does look awesome. I'm getting inspired to ressurect this failed PR in the Designer gui-cs/TerminalGuiDesigner#111 I like the grey/white and yellow/red (focus).

@tig
Copy link
Collaborator

tig commented Oct 31, 2022

I agree the Norton style looks great.

I'd love to see us tackle a new visual style as part of v2. See #1940

@heinrich-ulbricht
Copy link
Author

The ShadowButton already looks pretty good! If just the 1 pixel black line wasn't there 😑

@BDisp
Copy link
Collaborator

BDisp commented Oct 31, 2022

You can see the eye expects to see half an 'x' where that half shadow ends.

I think printing half of a letter or digit on a terminal is impossible.

@tznind
Copy link
Collaborator

tznind commented Oct 31, 2022

You can see the eye expects to see half an 'x' where that half shadow ends.

I think printing half of a letter or digit on a terminal is impossible.

Yeah haha sorry I didn't mean it as a solution. Was just weighing up the pros and cons of each of them. The half height shadow looks wierd when hovering over background stuff but theres not much that can be done about it.

I guess if we add it we should make it feature toggle. Thick or thin shadows. As theres not likely to always be a clear 'best'

@tznind
Copy link
Collaborator

tznind commented Oct 31, 2022

The ShadowButton already looks pretty good! If just the 1 pixel black line wasn't there 😑

Its so wierd! when you zoom in it doesn't get any bigger and it's there on cmd, powershell and visual studio dev terminal. I'm going to test this on my linux machine asap - see if it is something about my desktop resolution or something.

image
When zoomed in the bleed is still single pixel

@tznind
Copy link
Collaborator

tznind commented Oct 31, 2022

Yup, as I thought. Ubuntu with Terminator does not have this artifact, neither does Terminology console.

nobleed

Is anyone please able to test to see if this line artifact appears for them on Windows? I'm hoping this is a hardware issue.

Source code is in my initial reply.

@BDisp
Copy link
Collaborator

BDisp commented Oct 31, 2022

I confirm that doesn't appears on "Windows Terminal". Only with Windows Host Console that line artifact appears.

@tig tig added the enhancement label Nov 1, 2022
@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Nov 1, 2022

Windows 11 Console Window Host 😞 - the artifact is there.
image

Console in 2022 starts to seem like rocket science.

UX-related: when clicking the button I felt that I expected it to go down when pressed.

@BDisp
Copy link
Collaborator

BDisp commented Nov 1, 2022

UX-related: when clicking the button I felt that I expected it to go down when pressed.

It only go down on click and not on button pressed. So if you press the mouse button and move it before released, the button click will not be fired.

@tznind
Copy link
Collaborator

tznind commented Nov 1, 2022

How about this? Works with keyboard or mouse because it responds to the Click event not the mouse down.

pushbuttons

I think it looks a little off since it drops lower than the shadow indicates but I think that is the best your going to get with the limitations of console column height/resolution. Making the shadow thicker will make the buttons look worse.

Its also going to be tough for the 'depressed' button to reveal any background View content (at the moment it draws ' ' over the revealed area).

Heres the code:

using Terminal.Gui;
using Attribute = Terminal.Gui.Attribute;

Application.Init();
var win = new Window("Example App (Ctrl+Q to quit)");

win.Add(new ShadowButton("Button 1")
{
    X = 2,
    Y = 1
});

win.Add(new ShadowButton("Button 2")
{
    X = 20,
    Y = 1
});


win.Add(new Button("Button 3")
{
    X = 40,
    Y = 1,
    Border = new Border
    {
        Effect3D = true,
        Effect3DBrush = new Attribute(Color.Black, Color.Black),
    }
});

Application.Run(win);
Application.Shutdown();

class ShadowButton : Button
{
    public ShadowButton(string text) : base(text + " ") /*put a space on to leave 'shadow' room*/
    {
        Height = 2;
    }


    public bool Depressed { get; private set; }
    public override void OnClicked()
    {
        base.OnClicked();

        Depressed = true;
        SetNeedsDisplay();

        Application.MainLoop.AddTimeout(TimeSpan.FromMilliseconds(500), (m) =>
        {
            Depressed = false;
            Application.MainLoop.Invoke(() =>
            {
                SetNeedsDisplay();
            });
            return false;
        });

    }


    public override void Redraw(Rect bounds)
    {
        if (Depressed)
        {
            DrawDepressed(bounds);
        }
        else
        {
            DrawRegular(bounds);
        }
    }

    private void DrawRegular(Rect bounds)
    {
        // draw regular button
        base.Redraw(bounds);


        // draw the 'end' button symbol one in
        AddRune(bounds.Width - 2, 0, ']');

        // shadow color
        Driver.SetAttribute(new Terminal.Gui.Attribute(Color.Black, Colors.Base.Normal.Background));

        // end shadow (right)
        AddRune(bounds.Width - 1, 0, '▄');

        Driver.SetAttribute(new Terminal.Gui.Attribute(Color.Black, Colors.Base.Normal.Background));
        AddRune(0, 1, ' ');

        Driver.SetAttribute(new Terminal.Gui.Attribute(Colors.Base.Normal.Background, Color.Black));

        // underline shadow                
        for (int x = 1; x < bounds.Width; x++)
        {
            AddRune(x, 1, '▄');
        }
    }

    private void DrawDepressed(Rect bounds)
    {
        // area revealed on the background control by pushing Button down
        Driver.SetAttribute(
            new Terminal.Gui.Attribute(Colors.Base.Normal.Foreground, 
                Colors.Base.Normal.Background));
        
        // clear top line so button sinks to bottom line
        for (int x = 0; x < bounds.Width; x++)
        {
            AddRune(x,0,' ');
        }

        // render button as down
        Driver.SetAttribute(
            HasFocus ?
            new Terminal.Gui.Attribute(ColorScheme.Focus.Foreground,
                Colors.Base.Focus.Background):
            new Terminal.Gui.Attribute(ColorScheme.Normal.Foreground,
                Colors.Base.Normal.Background));

        var buttonRenderText = TextFormatter.Text;

        var textWidth = buttonRenderText.Length;

        for (int x = 1; x < textWidth; x++)
        {
            AddRune(x, 1, buttonRenderText[x-1]);
        }
        
        AddRune(textWidth-1, 1, ']');

    }
}

@BDisp
Copy link
Collaborator

BDisp commented Nov 1, 2022

UX-related: when clicking the button I felt that I expected it to go down when pressed.

It only go down on click and not on button pressed. So if you press the mouse button and move it before released, the button click will not be fired.

Ah ok sorry, you were meaning about visually effect.

@heinrich-ulbricht
Copy link
Author

While googling for Norton Commander button animations I came across this repo: https://github.com/magiblot/tvision - there is a screenshot of a button also showing those vertical lines in the button shadow, but between the shadow blocks. On purpose? Maybe another block type?
image

@tznind
Copy link
Collaborator

tznind commented Nov 1, 2022

I have sometimes seen those appear when resizing or moving terminal around. I think we shouldn't worry about these artifacts (bleed, seperation lines etc). They are pretty minor and are not really our responsibility to resolve.

@BDisp
Copy link
Collaborator

BDisp commented Nov 1, 2022

I have sometimes seen those appear when resizing or moving terminal around. I think we shouldn't worry about these artifacts (bleed, seperation lines etc). They are pretty minor and are not really our responsibility to resolve.

You are right. With Windows Terminal on Windows 11 that doesn't happens and probably M$ will not worry with that on previous versions.

@heinrich-ulbricht
Copy link
Author

Sounds reasonable. I'm nevertheless curious how the actual animation looks in either Turbo Vision or Norton Commander. They must have had the same challenges. Couldn't find something so far.

@BDisp
Copy link
Collaborator

BDisp commented Nov 1, 2022

@tznind and how about only hide the shadows when the button go down, instead of redraw the button bellow? How will be the effect?

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Nov 3, 2022

@BDisp Your suggestion looks pretty nice. The button still moves one to the right, giving good visual feedback:

ShadowButton.mp4

(The gray text appears because I disable the button when being clicked. This might require more tuning with regard to timing.) And the button does not retain its focus color, yet. It flickers, then it's gone. Focus is still on the button, though.

    class ShadowButton : Button
    {
        public ShadowButton(string text) : base(text + " ") /*put a space on to leave 'shadow' room*/
        {
            Height = 2;
        }


        public bool Depressed { get; private set; }
        public override void OnClicked()
        {
            base.OnClicked();

            Depressed = true;
            SetNeedsDisplay();

            Application.MainLoop.AddTimeout(TimeSpan.FromMilliseconds(180), (m) =>
            {
                Depressed = false;
                Application.MainLoop.Invoke(() =>
                {
                    SetNeedsDisplay();
                });
                return false;
            });

        }


        public override void Redraw(Rect bounds)
        {
            if (Depressed)
            {
                DrawDepressed(bounds);
            }
            else
            {
                DrawRegular(bounds);
            }
        }

        private void DrawRegular(Rect bounds)
        {
            // draw regular button
            base.Redraw(bounds);


            // draw the 'end' button symbol one in
            AddRune(bounds.Width - 2, 0, ']');

            // shadow color
            Driver.SetAttribute(new Terminal.Gui.Attribute(Color.Black, Colors.Base.Normal.Background));

            // end shadow (right)
            AddRune(bounds.Width - 1, 0, '▄');

            Driver.SetAttribute(new Terminal.Gui.Attribute(Color.Black, Colors.Base.Normal.Background));
            AddRune(0, 1, ' ');

            Driver.SetAttribute(new Terminal.Gui.Attribute(Colors.Base.Normal.Background, Color.Black));

            // underline shadow                
            for (int x = 1; x < bounds.Width; x++)
            {
                AddRune(x, 1, '▄');
            }
        }

        private void DrawDepressed(Rect bounds)
        {
            // area revealed on the background control by pushing Button down
            Driver.SetAttribute(
                new Terminal.Gui.Attribute(Colors.Base.Normal.Foreground,
                    Colors.Base.Normal.Background));

            // clear bottom line (shadow)
            for (int x = 0; x < bounds.Width; x++)
            {
                AddRune(x, 2, ' ');
            }

            // render button as down
            Driver.SetAttribute(
                HasFocus ?
                new Terminal.Gui.Attribute(ColorScheme.Focus.Foreground,
                    Colors.Base.Focus.Background) :
                new Terminal.Gui.Attribute(ColorScheme.Normal.Foreground,
                    Colors.Base.Normal.Background));

            var buttonRenderText = TextFormatter.Text;

            var textWidth = buttonRenderText.Length;

            for (int x = 1; x < textWidth; x++)
            {
                AddRune(x, 0, buttonRenderText[x - 1]);
            }

            AddRune(textWidth - 1, 0, ']');

        }
    }

@BDisp
Copy link
Collaborator

BDisp commented Nov 3, 2022

Thanks. I almost have an half border implementation in the Border class when the height is equal to 1. I think there is no sense to make it if the width is equal to 1. Let's me know.

@tznind
Copy link
Collaborator

tznind commented Nov 3, 2022

Very nice effect @heinrich-ulbricht . Definetly better than jumping down a line 🎉

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Nov 3, 2022

@tznind Cannot get enough of it :D

ShadowButton2.mp4

@BDisp
Copy link
Collaborator

BDisp commented Nov 3, 2022

I only removed the shadow but this effects is better. I'm leverage the existing Border class to make it more reused to another views. So, this additional move must be implemented in each view that want to implement it.

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Nov 3, 2022

Unfortunately the focus color seems lost after selecting the button. Is this expected in this proof of concept stage or should it be there?
AH nevermind. It only happens when disabling/enabling the button during the animation. Works great if not disabling as can be seen in the last video. (But is it normal...? See first video...)
Nevermind 2: this seems to be normal button behavior, nothing to do with the animation.

@tznind
Copy link
Collaborator

tznind commented Nov 3, 2022

Just thought I'd mention that we can do this without subclassing using the DrawContentComplete event. That is what I have done in designer (but not the animation yet). The main reason I did it was so could have the View work in TerminalGuiDesigner (doesn't currently support user subclass views) but also because avoiding inheritence is often a good choice when its for subtle stuff.

https://github.com/gui-cs/TerminalGuiDesigner/blob/60e853d57acb633e47e65867274a97221f47d607/src/UI/Windows/ConfirmDialog.cs#L36-L42

I know @BDisp is creating a border style that will do most of the drawing work in this.

Hopefullly after that, we can create a simple 5/10 line class ShadowStyler that registers events and adjusts borders to achieve this in a much simpler way?

@heinrich-ulbricht
Copy link
Author

Note: removing the start and end rune from the 3D button seems to reduce the visual noise a bit. Experimenting how it feels.

@tig
Copy link
Collaborator

tig commented Nov 4, 2022

Question for y'all:

Is it realistic to think this could be done/tested before next Tuesday for inclusion in v1.9.0 (https://github.com/gui-cs/Terminal.Gui/milestone/5)?

@tznind
Copy link
Collaborator

tznind commented Nov 4, 2022

Question for y'all:

Is it realistic to think this could be done/tested before next Tuesday for inclusion in v1.9.0 (https://github.com/gui-cs/Terminal.Gui/milestone/5)?

I think it depends on @BDisp availability as his PR #2166 is adding the functionality. I think if we can squeeze it in that would be great as its a great 'killer feature' for the patch.

@BDisp
Copy link
Collaborator

BDisp commented Nov 4, 2022

Question for y'all:

Is it realistic to think this could be done/tested before next Tuesday for inclusion in v1.9.0 (https://github.com/gui-cs/Terminal.Gui/milestone/5)?

I'll try to add at least the functionality to work on whatever border size, but only using the current glyphs, ok?

@tig tig added this to the v1.9 milestone Nov 4, 2022
@BDisp
Copy link
Collaborator

BDisp commented Nov 4, 2022

The 2588 █ FULL BLOCK isn't print, but it print in the Character Map. @tznind can you test please. Thanks.

@tig tig modified the milestones: v1.9, v2.0 Dec 4, 2022
@tig tig removed this from the v2.0 milestone Feb 28, 2023
@tig tig moved this to 🏗 In progress in Terminal.Gui V2 Beta Feb 28, 2023
@heinrich-ulbricht
Copy link
Author

@tig Greetings! You removed this from the v2.0 milestone - is this shadow-for-button feature being scrapped or just included in another feature?

@BDisp
Copy link
Collaborator

BDisp commented May 16, 2023

@heinrich-ulbricht with the new Frame class which the View class now have 3 Frame's for Margin, Border and Padding, it's now possible manipulating his Thickness and ColorScheme properties to make the shadow effect.

@heinrich-ulbricht
Copy link
Author

@BDisp Wonderful ❤️

@tznind
Copy link
Collaborator

tznind commented May 16, 2023

I'm interested in how it will work in the new API so I had an experiment. You can do this:

Application.Init();
var w = new Window();
var btn = new Button("Click me"){
	X = 2,
	Y = 2
};

btn.Margin.Thickness = new Thickness{
	Bottom = 1,
	Right = 1,
};
btn.Margin.ColorScheme = new ColorScheme(){
	Normal = new Attribute(Color.Black)
};

w.Add(btn);
Application.Run(w);
Application.Shutdown();

But if you want half height effect you need to do a bit more work in Draw. I did try adding draw code to Margin draw events but I don't think they are hooked up yet.

btn.DrawContentComplete += (s,e)=>
{
	Application.Driver.SetAttribute(
		new Attribute(
			Color.Black,
			w.ColorScheme.Normal.Background
			));

	for(int x = 0 ; x <= btn.Margin.Bounds.Width ;x++)
		btn.AddRune(x,1,'▀');
};

shot-2023-05-16_22-47-14

@tig tig moved this from 🏗 In progress to 🆕 New in Terminal.Gui V2 Beta May 13, 2024
@tig tig added this to the V2 Beta milestone May 25, 2024
@tig tig self-assigned this May 25, 2024
@tig tig changed the title Norton Commander style buttons: Add half-height bottom shadow for Effect3D Add 3D Shadow Effect for Button and other views May 25, 2024
@tig
Copy link
Collaborator

tig commented May 25, 2024

I am addressing this issue in

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented May 25, 2024

@tig Looking at my older videos above I notice that in those the button just slightly moves to the right, but stays in the same "row", not moving down. At the same time the shadow disappears. Overall this gives the illusion of movement.

You chose a different approach and the button moves a "row" down to where the shadow was. Is this a deliberate choice (because it looks better in your eyes), or is there a technical necessity?

For my eye it looks more pleasing if the button stays right where the mouse is and doesn't move a "row" down, although this might not be physically correct. Somehow with your approach I expect the mouse cursor to stick to the button and move as well - as it would be when pressing a button with the finger. Hope it's clear what I mean :D

@tig
Copy link
Collaborator

tig commented May 26, 2024

@tig Looking at my older videos above I notice that in those the button just slightly moves to the right, but stays in the same "row", not moving down. At the same time the shadow disappears. Overall this gives the illusion of movement.

You chose a different approach and the button moves a "row" down to where the shadow was. Is this a deliberate choice (because it looks better in your eyes), or is there a technical necessity?

For my eye it looks more pleasing if the button stays right where the mouse is and doesn't move a "row" down, although this might not be physically correct. Somehow with your approach I expect the mouse cursor to stick to the button and move as well - as it would be when pressing a button with the finger. Hope it's clear what I mean :D

Much better! Thanks for pointing that out.

7o1Zd6L 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: ✅ Done
Status: 🆕 Not Triaged
Development

Successfully merging a pull request may close this issue.

4 participants