benruehl / adonis-ui

Lightweight UI toolkit for WPF applications offering classic but enhanced windows visuals
https://benruehl.github.io/adonis-ui/
MIT License
1.71k stars 143 forks source link

Button with custom shape #97

Closed DonKadaj closed 4 years ago

DonKadaj commented 4 years ago

Goal Create a button that inherits the Adonis style (with cursor spotlight hover effect and ripple effect) with a personalized shape (here, an ellipse).

Problem With the implementation suggested in the documentation (https://benruehl.github.io/adonis-ui/docs/guides/cursor-spotlight/) and a custom shape, the behavior isn't as expected. When the cursor is outside the button, the button is invisible and, conversely, when the cursor is over it, the spotlight hover effect is reversed (see image below).

Code

  <Button Width="70" Height="70"
          adonisExtensions:CursorSpotlightExtension.MouseEventSource="{Binding RelativeSource={RelativeSource Mode=Self}}">
    <Button.Template>
      <ControlTemplate TargetType="Button">
        <Grid>
          <Ellipse StrokeThickness="0" Fill="{DynamicResource {x:Static adonisUi:Brushes.AccentBrush}}"/>
          <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
          <Image Source="/Assets/play_rounded.png" Margin="25,15,15,15" RenderOptions.BitmapScalingMode="HighQuality"/>
        </Grid>
      </ControlTemplate>
    </Button.Template>
  </Button>

Screenshot

AdonisEllipseButton

benruehl commented 4 years ago

Try it like that:

<Button Width="70" Height="70">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Grid>
                <Ellipse Fill="{DynamicResource {x:Static adonisUi:Brushes.AccentBrush}}"/>

                <Ellipse Fill="{DynamicResource {x:Static adonisUi:Brushes.AccentHighlightBrush}}"
                         adonisExtensions:CursorSpotlightExtension.MouseEventSource="{Binding RelativeSource={RelativeSource Mode=Self}}"/>

                <Image Source="/Assets/play_rounded.png" Margin="25,15,15,15" RenderOptions.BitmapScalingMode="HighQuality"/>
            </Grid>
        </ControlTemplate>
    </Button.Template>
</Button>

Explanation:

Setting CursorSpotlightExtension.MouseEventSource on an element makes this element the spotlight. The element is hidden until hovered and then revealed around the cursor. This allows for laying two completely different controls over each other and revealing the top one only when hovered. In your case you have converted the whole button to a spotlight layer instead of just some highlight layer inside the button. The ContentPresenter has nothing to do with this. I just removed it because it is unnecessary here. But you can re-add it if you like.

To improve your solution even further:

I'd like to suggest to use a built-in style for your use case because it is not necessary to create your own style. This would look like the following:

<Button Width="70"
        Height="70"
        BorderThickness="0"
        Style="{DynamicResource {x:Static adonisUi:Styles.AccentButton}}"
        adonisExtensions:CornerRadiusExtension.CornerRadius="35">
    <Button.ContentTemplate>
        <DataTemplate>
            <Image Source="/Assets/play_rounded.png" Margin="25,15,15,15" RenderOptions.BitmapScalingMode="HighQuality"/>
        </DataTemplate>
    </Button.ContentTemplate>
</Button>

The advantage with this approach is that you get all the features of AccentButton for free. You don't have to select the correct brushes yourself. Cursor spotlight and ripple effect are already working. Also, it is future prove because in case you upgrade to a newer version of Adonis UI you don't have to check if your style still works.

Additional notes:

DonKadaj commented 4 years ago

This works really fine! Thanks for your answer and your explanation! You're a right, the second solution is better.