Kreout
Topic Author
Posts: 12
Joined: 02 Feb 2014, 15:35

Button with custom style and clipping [Unity]

11 Mar 2014, 21:16

Hello again,

I'm experimenting with visual states in Blend.
I've created a new style as such:

	<Style x:Key="StackingButton" TargetType="{x:Type Button}">
		<Setter Property="ClipToBounds">
			<Setter.Value>False</Setter.Value>
		</Setter>
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type Button}">
					<Grid x:Name="grid">
						<VisualStateManager.VisualStateGroups>
							<VisualStateGroup x:Name="CommonStates">
								<VisualStateGroup.Transitions>
									<VisualTransition GeneratedDuration="0:0:0.5">
										<VisualTransition.GeneratedEasingFunction>
											<CubicEase EasingMode="EaseInOut"/>
										</VisualTransition.GeneratedEasingFunction>
									</VisualTransition>
								</VisualStateGroup.Transitions>
								<VisualState x:Name="Normal"/>
								<VisualState x:Name="MouseOver"/>
								<VisualState x:Name="Pressed">
									<Storyboard>
										<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="canvas">
											<EasingDoubleKeyFrame KeyTime="0" Value="2"/>
										</DoubleAnimationUsingKeyFrames>
										<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="canvas">
											<EasingDoubleKeyFrame KeyTime="0" Value="2"/>
										</DoubleAnimationUsingKeyFrames>
										<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="canvas">
											<EasingDoubleKeyFrame KeyTime="0" Value="-150"/>
										</DoubleAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="Disabled"/>
							</VisualStateGroup>
						</VisualStateManager.VisualStateGroups>
						<Viewbox>
							<Canvas x:Name="canvas" Height="100" Width="100" RenderTransformOrigin="0.5,0.5">
								<Canvas.RenderTransform>
									<TransformGroup>
										<ScaleTransform/>
										<SkewTransform/>
										<RotateTransform/>
										<TranslateTransform Y="0"/>
									</TransformGroup>
								</Canvas.RenderTransform>
								<Path Data="M1,1 L83,1 L83,19.598 L1,19.598 z" Fill="{DynamicResource ControlUnselectedBrush}" Height="20.598" Canvas.Left="8" Stretch="Fill" Stroke="#FF9B9797" StrokeThickness="2" Canvas.Top="64.689" Width="84"/>
								<Path Data="M1,1 L83,1 L83,18.54 L1,18.54 z" Height="19.54" Canvas.Left="8" Stretch="Fill" Stroke="#FF9B9797" StrokeThickness="2" Canvas.Top="41.149" Width="84" Fill="{DynamicResource ControlUnselectedBrush}" />
								<Path Data="M1,1 L83,1 L83,18.541 L1,18.541 z" Height="19.541" Canvas.Left="8" Stretch="Fill" Stroke="#FF9B9797" StrokeThickness="2" Canvas.Top="17.608" Width="84" Fill="{DynamicResource ControlUnselectedBrush}" />
							</Canvas>
						</Viewbox>
						<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
					</Grid>
					<ControlTemplate.Triggers>
						<Trigger Property="IsFocused" Value="True"/>
						<Trigger Property="IsDefaulted" Value="True"/>
						<Trigger Property="IsMouseOver" Value="True"/>
						<Trigger Property="IsPressed" Value="True"/>
						<Trigger Property="IsEnabled" Value="False"/>
					</ControlTemplate.Triggers>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
It's used like this:
		<Grid x:Name="GUIGrid" Height="768" Width="1024">
			<Grid.RowDefinitions>
				<RowDefinition Height="0.086*"/>
				<RowDefinition Height="0.737*"/>
				<RowDefinition Height="0.177*"/>
			</Grid.RowDefinitions>
			<Grid x:Name="TopGrid"/>
			<StackPanel x:Name="ButtonPanel" Grid.Row="2" HorizontalAlignment="Center" Orientation="Horizontal">				
				<Button Content="" Style="{DynamicResource StackingButton}"/>				
			</StackPanel>
		</Grid>
It works as expected if I build the project in Blend. The canvas is scaled and translated when I press the button, and then transitions back when the mouse leaves the control.

When imported into Unity, the button seems to clip the vector graphics when transitioning to the pressed state.

Is this intended? If so, what can I do to get around the problem?
I've tried to style a Control instead of a Button, but then I don't get access to the default visual states such as normal, pressed and so on.

I know that I didn't have this problem when I styled a Control and used a storyboard instead of visual states, but then I don't get the same smooth transitions, especially if the mouse leaves the control while the storyboard is playing.

Any hints or help is welcome!
 
User avatar
sfernandez
Site Admin
Posts: 2908
Joined: 22 Dec 2011, 19:20

Re: Button with custom style and clipping [Unity]

13 Mar 2014, 20:55

I found a problem in the layout process when mixing elements with UseLayoutRounding a true and others a false, that is generating unnecessary clip regions.

You can avoid this problem now by setting UseLayoutRounding="True" in the root element:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  UseLayoutRounding="True">

    <!-- ... -->

</Grid>
 
Kreout
Topic Author
Posts: 12
Joined: 02 Feb 2014, 15:35

Re: Button with custom style and clipping [Unity]

14 Mar 2014, 06:50

Thank's, that did the trick!

Edit:
While testing, I also found one interesting thing; If I have a setter for "ClipToBounds" with the value "False", Noesis still clips the content of the children.
In order to remove that extra clipping, I have to remove the property. The value doesn't seem to be taken into account.

Also, the pressed visual-state doesn't seem to work the same on Android as on PC.
If I press a button on PC and drag the cursor out of the controls area, the button instantly changes to it's normal state.
On android, the pressed state is still active if I drag my finger out of the button, and I have to press another element to reset the visual state of the first button.

Best regards,
Anders
 
User avatar
sfernandez
Site Admin
Posts: 2908
Joined: 22 Dec 2011, 19:20

Re: Button with custom style and clipping [Unity]

14 Mar 2014, 19:33

While testing, I also found one interesting thing; If I have a setter for "ClipToBounds" with the value "False", Noesis still clips the content of the children.
In order to remove that extra clipping, I have to remove the property. The value doesn't seem to be taken into account.
In my tests, having a Setter for ClipToBounds property with the value "False" doesn't add extra clips. Could you please confirm it again?
Also, the pressed visual-state doesn't seem to work the same on Android as on PC.
If I press a button on PC and drag the cursor out of the controls area, the button instantly changes to it's normal state.
On android, the pressed state is still active if I drag my finger out of the button, and I have to press another element to reset the visual state of the first button.
I was able to reproduce it, so we will fix it for next version. Thanks for reporting it.
 
Kreout
Topic Author
Posts: 12
Joined: 02 Feb 2014, 15:35

Re: Button with custom style and clipping [Unity]

15 Mar 2014, 07:34

Great that you were able to reproduce the problem with pressed state on android! I'm really looking forward to next version of Noesis!
In my tests, having a Setter for ClipToBounds property with the value "False" doesn't add extra clips. Could you please confirm it again?
I just tried it again, and I wasn't able to reproduce it either. I've made some changes to the code since I reported it, and I'm unsure of exactly what combination of properties I used when it happened.
Treat it as a user-error for now, and I'll let you know if the same thing happens again down the road.

Who is online

Users browsing this forum: Semrush [Bot] and 5 guests