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

Styling doesn't apply based on ControlState #263

Open
giulianob opened this issue Jun 19, 2022 · 1 comment
Open

Styling doesn't apply based on ControlState #263

giulianob opened this issue Jun 19, 2022 · 1 comment

Comments

@giulianob
Copy link

giulianob commented Jun 19, 2022

Styles with ControlState don't seem to actually apply. For example:

public class AppStyle : Style
{
    public AppStyle()
    {
        Button = new ButtonStyle
        {
            BackgroundColor = new StyleAwareValue<ControlState, Color>
            {
                [ControlState.Disabled] = Color.Grey,
                [ControlState.Default] = Color.Green,
                [ControlState.Hovered] = Colors.Red,
                [ControlState.Pressed] = Color.Black,
            }
        };
    }
}

// Then using it:
View body() =>
    new VStack
    {
         new Button("Enabled"),
         new Button("Disabled")
	    .Enabled(false),
     }.ApplyStyle(new AppStyle());

The second button should be grey. The first button should be red/black when hovered/pressed. The source generators are just getting the default value and doesn't seem like they apply the control state:

// Button.g.cs
Microsoft.Maui.Graphics.Color Microsoft.Maui.ITextStyle.TextColor => this.GetEnvironment<Microsoft.Maui.Graphics.Color>("Color") ?? default;

I can look at helping PR a change to implement this but would need some guidance on how to implement it. What I am thinking:

  1. CometGenerator attribute needs a list of states supported by each control. I believe by default every control supports at least Disabled, Default, and Hovered states but ITextButton needs to specify it also supports Pressed.
  2. ITextButton would need to generate a bool IsPressed which is updated based on Pressed/Released actions. Not sure how to best model this in the CometGenerateAttribute. Is this a one off case? Is it better to omit Pressed/Released from being generated and create a Button.cs with this logic?
  3. Source generator would emit a switch statement to fetch the correct value based on state. This could be done in a VisualState property. For example, if the ITextButton has states [ Pressed ] (default/hovered/disabled don't need to be specified) then the following switch would be created:
Microsoft.Maui.Graphics.Color Microsoft.Maui.ITextStyle.TextColor => this.GetEnvironment<Microsoft.Maui.Graphics.Color>("Color", VisualState) ?? default;

ControlState VisualState {
   get {
// not sure if order matters here
       if (IsPressed)
       {
          return ControlState.IsPressed;
       }
       if (IsFocused)
       {
          return ControlState.Hovered;
       }
       if (IsEnabled)
       {
         return ControlState.Default;
       }
       return ControlState.Disabled;
   }
}

Another option would be to add the switch inside of the GetEnvironment call. This would support the IsFocused/IsEnabled states but not sure how that would support IsPressed

@saint4eva
Copy link

For the StyleAwareValue dictionary, the value - Color -, is it supposed to be Colors?

When initializing the StyleAwareValue, there is inconsistency

Color. Green and Colors.Red

Color or Colors? Which one?

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

No branches or pull requests

2 participants