Browse Source

Merge pull request #367 from donandren/expander

new expander control
Steven Kirk 10 years ago
parent
commit
35e87f2b10

+ 74 - 0
src/Perspex.Controls/Expander.cs

@@ -0,0 +1,74 @@
+using Perspex.Animation;
+using Perspex.Controls.Primitives;
+
+namespace Perspex.Controls
+{
+    public enum ExpandDirection
+    {
+        Down,
+        Up,
+        Left,
+        Right
+    }
+
+    public class Expander : HeaderedContentControl
+    {
+        public static readonly PerspexProperty<bool> IsExpandedProperty =
+            PerspexProperty.Register<Expander, bool>(nameof(IsExpanded), true);
+
+        public static readonly PerspexProperty<ExpandDirection> ExpandDirectionProperty =
+            PerspexProperty.Register<Expander, ExpandDirection>(nameof(ExpandDirection), ExpandDirection.Down);
+
+        public static readonly PerspexProperty<IPageTransition> ContentTransitionProperty =
+            PerspexProperty.Register<Expander, IPageTransition>(nameof(ContentTransition));
+
+        static Expander()
+        {
+            PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Down, ":down");
+            PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Up, ":up");
+            PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Left, ":left");
+            PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Right, ":right");
+
+            PseudoClass(IsExpandedProperty, ":expanded");
+
+            IsExpandedProperty.Changed.AddClassHandler<Expander>(x => x.OnIsExpandedChanged);
+        }
+
+        public bool IsExpanded
+        {
+            get { return GetValue(IsExpandedProperty); }
+            set { SetValue(IsExpandedProperty, value); }
+        }
+
+        public ExpandDirection ExpandDirection
+        {
+            get { return GetValue(ExpandDirectionProperty); }
+            set { SetValue(ExpandDirectionProperty, value); }
+        }
+
+        public IPageTransition ContentTransition
+        {
+            get { return GetValue(ContentTransitionProperty); }
+            set { SetValue(ContentTransitionProperty, value); }
+        }
+
+        protected virtual void OnIsExpandedChanged(PerspexPropertyChangedEventArgs e)
+        {
+            IVisual visualContent = Presenter;
+
+            if (Content != null && ContentTransition != null && visualContent != null)
+            {
+                bool forward = ExpandDirection == ExpandDirection.Left ||
+                                ExpandDirection == ExpandDirection.Up;
+                if (IsExpanded)
+                {
+                    ContentTransition.Start(null, visualContent, forward);
+                }
+                else
+                {
+                    ContentTransition.Start(visualContent, null, !forward);
+                }
+            }
+        }
+    }
+}

+ 1 - 0
src/Perspex.Controls/Perspex.Controls.csproj

@@ -44,6 +44,7 @@
     </Compile>
     <Compile Include="Classes.cs" />
     <Compile Include="DockPanel.cs" />
+    <Compile Include="Expander.cs" />
     <Compile Include="Generators\ItemContainer.cs" />
     <Compile Include="HotkeyManager.cs" />
     <Compile Include="INameScope.cs" />

+ 1 - 0
src/Perspex.Themes.Default/DefaultTheme.paml

@@ -23,6 +23,7 @@
   <StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TabStripItem.paml"/>
   <StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TextBox.paml"/>
   <StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ToggleButton.paml"/>
+  <StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.Expander.paml"/>
   <StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ToolTip.paml"/>
   <StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TreeView.paml"/>
   <StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TreeViewItem.paml"/>

+ 123 - 0
src/Perspex.Themes.Default/Expander.paml

@@ -0,0 +1,123 @@
+<Styles xmlns="https://github.com/perspex">
+
+  <Style Selector="Expander">
+    <Setter Property="ContentTransition">
+      <Setter.Value>
+        <CrossFade Duration="00:00:00.25" />
+      </Setter.Value>
+    </Setter>
+  </Style>
+  <Style Selector="Expander[ExpandDirection=Down]">
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Border Background="{TemplateBinding Background}">
+          <Grid RowDefinitions="Auto,*">
+            <ToggleButton Name="PART_toggle" Grid.Row="0"  Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
+            <ContentPresenter Name="PART_ContentPresenter"
+                              Grid.Row="1"
+                              IsVisible="{TemplateBinding IsExpanded}"
+                              Content="{TemplateBinding Content}"
+                              HorizontalAlignment="Stretch"
+                              VerticalAlignment="Stretch" />
+          </Grid>
+        </Border>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+  <Style Selector="Expander[ExpandDirection=Up]">
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Border Background="{TemplateBinding Background}">
+          <Grid RowDefinitions="*,Auto">
+            <ToggleButton Name="PART_toggle" Grid.Row="1"  Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
+            <ContentPresenter Name="PART_ContentPresenter"
+                              Grid.Row="0"
+                              IsVisible="{TemplateBinding IsExpanded}"
+                              Content="{TemplateBinding Content}"
+                              HorizontalAlignment="Stretch"
+                              VerticalAlignment="Stretch" />
+          </Grid>
+        </Border>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+  <Style Selector="Expander[ExpandDirection=Right]">
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Border Background="{TemplateBinding Background}">
+          <Grid ColumnDefinitions="Auto,*">
+            <ToggleButton Name="PART_toggle" Grid.Column="0"  Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
+            <ContentPresenter Name="PART_ContentPresenter"
+                              Grid.Column="1"
+                              IsVisible="{TemplateBinding IsExpanded}"
+                              Content="{TemplateBinding Content}"
+                              HorizontalAlignment="Stretch"
+                              VerticalAlignment="Stretch" />
+          </Grid>
+        </Border>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+  <Style Selector="Expander[ExpandDirection=Left]">
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Border Background="{TemplateBinding Background}">
+          <Grid ColumnDefinitions="*,Auto">
+            <ToggleButton Name="PART_toggle" Grid.Column="1"  Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
+            <ContentPresenter Name="PART_ContentPresenter"
+                              Grid.Column="0"
+                              IsVisible="{TemplateBinding IsExpanded}"
+                              Content="{TemplateBinding Content}"
+                              HorizontalAlignment="Stretch"
+                              VerticalAlignment="Stretch" />
+          </Grid>
+        </Border>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+  <Style Selector="Expander /template/ ToggleButton#PART_toggle">
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Border BorderThickness="1">
+          <Grid ColumnDefinitions="Auto,Auto">
+            <Border Grid.Column="0" Width="20" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center">
+              <Path Fill="Black"
+                      HorizontalAlignment="Center"
+                      VerticalAlignment="Center"
+                      Data="M 0 2 L 4 6 L 0 10 Z" />
+            </Border>
+            <ContentPresenter Grid.Column="1" Content="{TemplateBinding Content}" VerticalAlignment="Center" />
+          </Grid>
+        </Border>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+  <Style Selector="Expander /template/ ToggleButton#PART_toggle:pointerover /template/ Border">
+    <Setter Property="BorderBrush" Value="#ffaaaaaa" />
+  </Style>
+  <Style Selector="Expander:down:expanded /template/ ToggleButton#PART_toggle /template/ Path">
+    <Setter Property="RenderTransform">
+      <RotateTransform Angle="90" />
+    </Setter>
+  </Style>
+  <Style Selector="Expander:up:expanded /template/ ToggleButton#PART_toggle /template/ Path">
+    <Setter Property="RenderTransform">
+      <RotateTransform Angle="-90" />
+    </Setter>
+  </Style>
+  <Style Selector="Expander:left:expanded /template/ ToggleButton#PART_toggle /template/ Path">
+    <Setter Property="RenderTransform">
+      <RotateTransform Angle="180" />
+    </Setter>
+  </Style>
+  <Style Selector="Expander:right /template/ ToggleButton#PART_toggle /template/ Path">
+    <Setter Property="RenderTransform">
+      <RotateTransform Angle="180" />
+    </Setter>
+  </Style>
+  <Style Selector="Expander:right:expanded /template/ ToggleButton#PART_toggle /template/ Path">
+    <Setter Property="RenderTransform">
+      <RotateTransform Angle="0" />
+    </Setter>
+  </Style>
+</Styles>

+ 1 - 0
src/Perspex.Themes.Default/Perspex.Themes.Default.csproj

@@ -143,6 +143,7 @@
     <EmbeddedResource Include="ToolTip.paml">
       <SubType>Designer</SubType>
     </EmbeddedResource>
+    <EmbeddedResource Include="Expander.paml" />
     <None Include="packages.config" />
     <EmbeddedResource Include="PopupRoot.paml">
       <SubType>Designer</SubType>