<HorizontalStack Margin="2" Left="{./TabOffset}"
Name="TabTitle"
HorizontalAlignment="Left"
- Height="{./TabThickness}"
- Width="Fit">
+ Height="{./TabHeight}"
+ Width="{./TabWidth}">
<Label Name="caption" Text="{./Caption}" Foreground="Gray"/>
<Border CornerRadius="5" BorderWidth="1" Foreground="Transparent" Height="12" Width="12"
MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
Background="{./Background}"
MouseEnter="{/caption.Foreground=White}"
MouseLeave="{/caption.Foreground=Gray}">
- <HorizontalStack Margin="2" Left="{./TabOffset}"
- Name="TabTitle" Background="{./Background}"
+ <HorizontalStack Left="{./TabOffset}"
+ Name="TabTitle"
HorizontalAlignment="Left"
- Height="{./TabThickness}"
- Width="Fit">
+ Height="{./TabHeight}"
+ Width="{./TabWidth}">
<Label Name="caption" Text="{./Caption}" Foreground="Gray"/>
<Label Text="{./ViewIndex}" Foreground="Green"/>
<Label Text="{./TabOffset}" Foreground="Red"/>
+ <GraphicObject Height="1"/>
<Border CornerRadius="5" BorderWidth="1" Foreground="Transparent" Height="12" Width="12"
MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
<Image Focusable="true" Name="Image" Margin="0" Width="Stretched" Height="Stretched" Path="#Crow.Images.Icons.exit2.svg"
MouseClick="./butCloseTabClick"/>
</Border>
</HorizontalStack>
- <Container Name="Content"/>
+ <Container Margin="20">
+ <Container Background="Jet" Name="Content"/>
+ </Container>
</GenericStack>
<?xml version="1.0" encoding="UTF-8" ?>
-<VerticalStack Height="50%" Width="80%">
+<VerticalStack Height="90%" Width="95%">
<HorizontalStack Height="Fit">
<Label Text="Selected Tab:"/>
<Label Text="{../../tabview1.SelectedTab}"/>
</HorizontalStack>
- <TabView Name="tabview1" Background="Onyx" Orientation="Horizontal" Spacing="14" Margin="50">
+ <TabView Name="tabview1" Background="Onyx" Orientation="Horizontal" Margin="20">
<TabItem Name="TabItem1" Caption="tab item 1" Background="Onyx">
<VerticalStack Margin="20">
<CheckBox/>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<HorizontalStack Height="90%" Width="99%">
+ <VerticalStack Width="50%">
+ <HorizontalStack Height="Fit">
+ <Label Text="Selected Tab:"/>
+ <Label Text="{../../tabview1.SelectedTab}"/>
+ </HorizontalStack>
+ <TabView Name="tabview1" Background="Onyx" Orientation="Horizontal" Spacing="-10" Margin="50">
+ <TabItem Name="TabItem1" Caption="tab-1.1" Background="Onyx">
+ <VerticalStack Margin="20">
+ <CheckBox/>
+ <CheckBox/>
+ <CheckBox/>
+ <CheckBox/>
+ </VerticalStack>
+ </TabItem>
+ <TabItem Name="TabItem2" Caption="tab-1.2" Background="Onyx">
+ <VerticalStack Height="Fit" Margin="10">
+ <RadioButton Fit="true"/>
+ <RadioButton/>
+ <RadioButton/>
+ <RadioButton/>
+ </VerticalStack>
+ </TabItem>
+ <TabItem Name="TabItem3" Background="Onyx" Caption="tab-1.3">
+ <Container Margin="5" CornerRadius="2" >
+ <TextBox Margin="5" Multiline="true" TextAlignment="TopLeft"/>
+ </Container>
+ </TabItem>
+ </TabView>
+ <Button Background="vgradient|0:DimGray|1:Black" HorizontalAlignment="Right"
+ Caption="Add new tab" Width="Fit" Height="30" MouseDown="onAddTabButClick"/>
+ </VerticalStack>
+ <VerticalStack Width="50%">
+ <HorizontalStack Height="Fit">
+ <Label Text="Selected Tab:"/>
+ <Label Text="{../../tabview2.SelectedTab}"/>
+ </HorizontalStack>
+ <TabView Name="tabview2" Background="Onyx" Orientation="Horizontal" Spacing="-10" Margin="50">
+ <TabItem Name="TabItem1" Caption="tab-2.1" Background="Onyx">
+ <VerticalStack Margin="20">
+ <CheckBox/>
+ <CheckBox/>
+ <CheckBox/>
+ <CheckBox/>
+ </VerticalStack>
+ </TabItem>
+ <TabItem Name="TabItem2" Caption="tab-2.2" Background="Onyx">
+ <VerticalStack Height="Fit" Margin="10">
+ <RadioButton Fit="true"/>
+ <RadioButton/>
+ <RadioButton/>
+ <RadioButton/>
+ </VerticalStack>
+ </TabItem>
+ <TabItem Name="TabItem3" Background="Onyx" Caption="tab-2.3">
+ <Container Margin="5" CornerRadius="2" >
+ <TextBox Margin="5" Multiline="true" TextAlignment="TopLeft"/>
+ </Container>
+ </TabItem>
+ </TabView>
+ <Button Background="vgradient|0:DimGray|1:Black" HorizontalAlignment="Right"
+ Caption="Add new tab" Width="Fit" Height="30" MouseDown="onAddTabButClick2"/>
+ </VerticalStack>
+</HorizontalStack>
<None Include="Interfaces\Experimental\testDock2.crow">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+ <None Include="Interfaces\TemplatedContainer\testTabView2.crow">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
</ItemGroup>
<ItemGroup>
<Folder Include="Interfaces\" />
using System.Diagnostics;
using System.Xml.Serialization;
using System;
+using System.Linq;
namespace Crow
{
}
protected override int measureRawSize (LayoutingType lt)
{
- int totSpace = 0;
- for (int i = 0; i < Children.Count; i++) {
- if (Children [i].Visible)
- totSpace += Spacing;
- }
- if (totSpace > 0)
- totSpace -= Spacing;
+ int totSpace = Spacing * (Children.Count (c => c.Visible) - 1);
+
if (lt == LayoutingType.Width) {
if (Orientation == Orientation.Horizontal)
return contentSize.Width + totSpace + 2 * Margin;
public event EventHandler QueryClose;
+ internal TabView tview = null;
+
#region Private fields
GraphicObject titleWidget;
int tabOffset;
NotifyValueChanged ("ViewIndex", viewIndex);
}
}
-
- [XmlAttributeAttribute][DefaultValue("18")]
- public virtual Measure TabThickness {
- get { return tabThickness; }
- set {
- if (tabThickness == value)
- return;
- tabThickness = value;
- NotifyValueChanged ("TabThickness", tabThickness);
- RegisterForGraphicUpdate ();
- }
- }
+
[XmlAttributeAttribute][DefaultValue(0)]
- public virtual int TabOffset {
+ public int TabOffset {
get { return tabOffset; }
set {
if (tabOffset == value)
RegisterForGraphicUpdate ();
}
}
-
+ public Measure TabHeight {
+ get { return tview == null ? Measure.Fit : tview.TabHeight; }
+ }
+ public Measure TabWidth {
+ get { return tview == null ? Measure.Fit : tview.TabWidth; }
+ }
[XmlAttributeAttribute][DefaultValue(false)]
public virtual bool IsSelected {
get { return isSelected; }
{
gr.Save ();
- int spacing = (Parent as TabView).Spacing;
+ TabView tv = Parent as TabView;
- gr.MoveTo (0.5, TabTitle.Slot.Bottom-0.5);
- gr.LineTo (TabTitle.Slot.Left - spacing, TabTitle.Slot.Bottom-0.5);
+ Rectangle r = TabTitle.Slot;
+ r.Width = TabWidth;
+
+ gr.MoveTo (0.5, r.Bottom-0.5);
+ gr.LineTo (r.Left - tv.LeftSlope, r.Bottom-0.5);
gr.CurveTo (
- TabTitle.Slot.Left - spacing / 2, TabTitle.Slot.Bottom-0.5,
- TabTitle.Slot.Left - spacing / 2, 0.5,
- TabTitle.Slot.Left, 0.5);
- gr.LineTo (TabTitle.Slot.Right, 0.5);
+ r.Left - tv.LeftSlope / 2, r.Bottom-0.5,
+ r.Left - tv.LeftSlope / 2, 0.5,
+ r.Left, 0.5);
+ gr.LineTo (r.Right, 0.5);
gr.CurveTo (
- TabTitle.Slot.Right + spacing / 2, 0.5,
- TabTitle.Slot.Right + spacing / 2, TabTitle.Slot.Bottom-0.5,
- TabTitle.Slot.Right + spacing, TabTitle.Slot.Bottom-0.5);
- gr.LineTo (Slot.Width-0.5, TabTitle.Slot.Bottom-0.5);
+ r.Right + tv.RightSlope / 2, 0.5,
+ r.Right + tv.RightSlope / 2, r.Bottom-0.5,
+ r.Right + tv.RightSlope, r.Bottom-0.5);
+ gr.LineTo (Slot.Width-0.5, r.Bottom-0.5);
gr.LineTo (Slot.Width-0.5, Slot.Height-0.5);
gr.LineWidth = 1;
Foreground.SetAsSource (gr);
gr.StrokePreserve ();
-
gr.Clip ();
base.onDraw (gr);
gr.Restore ();
if (!base.PointIsIn (ref m))
return false;
- if (m.Y < tabThickness)
+ if (m.Y < tview.TabHeight)
return TabTitle.Slot.ContainsOrIsEqual (m);
else
return this.isSelected;
{
base.onMouseUp (sender, e);
HoldCursor = false;
- (Parent as TabView).UpdateLayout (LayoutingType.ArrangeChildren);
+ tview.UpdateLayout (LayoutingType.ArrangeChildren);
}
public override void onMouseMove (object sender, MouseMoveEventArgs e)
{
if (!(HasFocus && HoldCursor))
return;
TabView tv = Parent as TabView;
- TabItem previous = null, next = null;
+ Rectangle cb = ClientRectangle;
+
int tmp = TabOffset + e.XDelta;
- if (tmp < tv.Spacing)
- TabOffset = tv.Spacing;
- else if (tmp > Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing)
- TabOffset = Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing;
+ if (tmp < tview.LeftSlope)
+ TabOffset = tview.LeftSlope;
+ else if (tmp > cb.Width - tv.RightSlope - tv.TabWidth)
+ TabOffset = cb.Width - tv.RightSlope - tv.TabWidth;
else{
TabItem[] tabItms = tv.Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray();
if (ViewIndex > 0 && e.XDelta < 0) {
- previous = tabItms [ViewIndex - 1];
- if (tmp < previous.TabOffset + previous.TabTitle.Slot.Width / 2) {
+ TabItem previous = tabItms [ViewIndex - 1];
+ if (tmp < previous.TabOffset + tview.TabWidth / 2) {
previous.ViewIndex = ViewIndex;
ViewIndex--;
tv.UpdateLayout (LayoutingType.ArrangeChildren);
}
}else if (ViewIndex < tabItms.Length - 1 && e.XDelta > 0) {
- next = tabItms [ViewIndex + 1];
- if (tmp > next.TabOffset - next.TabTitle.Slot.Width / 2){
+ TabItem next = tabItms [ViewIndex + 1];
+ if (tmp > next.TabOffset - tview.TabWidth / 2){
next.ViewIndex = ViewIndex;
ViewIndex++;
tv.UpdateLayout (LayoutingType.ArrangeChildren);
#endregion
#region Private fields
- int _spacing;
- Measure tabThickness;
+ int spacing;
+ int leftSlope;
+ int rightSlope;
+ Measure tabHeight, tabWidth;
Orientation _orientation;
- int selectedTab = 0;
+ int selectedTab;
#endregion
#region public properties
- [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
+ [DefaultValue(Orientation.Horizontal)]
public virtual Orientation Orientation
{
get { return _orientation; }
if (_orientation == Orientation.Horizontal)
NotifyValueChanged ("TabOrientation", Orientation.Vertical);
else
- NotifyValueChanged ("TabOrientation", Orientation.Horizontal);
+ NotifyValueChanged ("TabOrientation", Orientation.Horizontal);
+ this.RegisterForLayouting (LayoutingType.ArrangeChildren);
+ }
+ }
+ [DefaultValue(16)]
+ public int LeftSlope
+ {
+ get { return leftSlope; }
+ set {
+ if (leftSlope == value)
+ return;
+ leftSlope = value;
+ NotifyValueChanged ("leftSlope", leftSlope);
+ tabSizeHasChanged = true;
+ //RegisterForLayouting (LayoutingType.ArrangeChildren);
}
}
- [XmlAttributeAttribute()][DefaultValue(16)]
- public int Spacing
+ bool tabSizeHasChanged = false;
+ [DefaultValue(16)]
+ public int RightSlope
{
- get { return _spacing; }
+ get { return rightSlope; }
set {
- if (_spacing == value)
+ if (rightSlope == value)
return;
- _spacing = value;
- NotifyValueChanged ("Spacing", Spacing);
+ rightSlope = value;
+ NotifyValueChanged ("RightSlope", rightSlope);
+ tabSizeHasChanged = true;
+ //RegisterForLayouting (LayoutingType.ArrangeChildren);
+ }
+ }
+ [DefaultValue("18")]
+ public Measure TabHeight {
+ get { return tabHeight; }
+ set {
+ if (tabHeight == value)
+ return;
+ tabHeight = value;
+ NotifyValueChanged ("TabHeight", tabHeight);
+// childrenRWLock.EnterReadLock ();
+// foreach (GraphicObject ti in Children) {
+// ti.NotifyValueChanged ("TabHeight", tabHeight);
+// }
+// childrenRWLock.ExitReadLock ();
+ RegisterForLayouting (LayoutingType.ArrangeChildren);
+ }
+ }
+ [DefaultValue("120")]
+ public Measure TabWidth {
+ get { return tabWidth; }
+ set {
+ if (tabWidth == value)
+ return;
+ tabWidth = value;
+ NotifyValueChanged ("TabWidth", tabWidth);
+//
+// childrenRWLock.EnterReadLock ();
+// foreach (GraphicObject ti in Children) {
+// ti.NotifyValueChanged ("TabWidth", tabWidth);
+// }
+// childrenRWLock.ExitReadLock ();
+ RegisterForLayouting (LayoutingType.ArrangeChildren);
}
}
- [XmlAttributeAttribute()][DefaultValue(0)]
+
public virtual int SelectedTab {
get { return selectedTab; }
set {
- if (value < 0)//prevent TemplatedGroup index binding set to -1
+ if (value == selectedTab)
return;
-
- if (selectedTab < Children.Count && SelectedTab >= 0)
+
+ if (selectedTab < Children.Count && selectedTab >= 0)
(Children [selectedTab] as TabItem).IsSelected = false;
selectedTab = value;
- if (selectedTab < Children.Count && SelectedTab >= 0)
+ if (selectedTab < Children.Count && selectedTab >= 0)
(Children [selectedTab] as TabItem).IsSelected = true;
NotifyValueChanged ("SelectedTab", selectedTab);
}
#endregion
- void Ti_TabTitle_LayoutChanged (object sender, LayoutingEventArgs e)
- {
- if (e.LayoutType == LayoutingType.Width)
- this.RegisterForLayouting (LayoutingType.ArrangeChildren);
- }
-
public override void AddChild (GraphicObject child)
{
TabItem ti = child as TabItem;
ti.MouseDown += Ti_MouseDown;
ti.TabTitle.LayoutChanged += Ti_TabTitle_LayoutChanged;
+ ti.tview = this;
base.AddChild (child);
SelectedTab = ti.ViewIndex = Children.Count - 1;
+ this.RegisterForLayouting (LayoutingType.ArrangeChildren);
}
-
- public override void DeleteChild (GraphicObject child)
+ public override void RemoveChild (GraphicObject child)
{
TabItem ti = child as TabItem;
if (ti == null)
ti.MouseDown -= Ti_MouseDown;
ti.TabTitle.LayoutChanged -= Ti_TabTitle_LayoutChanged;
+ ti.tview = null;
+
+ childrenRWLock.EnterReadLock ();
+
+ TabItem[] tabItms = Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray();
+ int selTabViewIdx = -1;
+
+ if (SelectedTab < tabItms.Length && SelectedTab >= 0)
+ selTabViewIdx = (Children [SelectedTab] as TabItem).ViewIndex;
- if (selectedTab > Children.Count - 2)
- SelectedTab--;
-
- base.DeleteChild (child);
+ for (int i = selTabViewIdx+1; i < tabItms.Length; i++)
+ tabItms [i].ViewIndex--;
+
+ if (selTabViewIdx > tabItms.Length - 2)
+ selTabViewIdx = tabItms.Length - 2;
+
+ if (selTabViewIdx < 0)
+ SelectedTab = -1;
+ else
+ SelectedTab = Children.IndexOf (tabItms [selTabViewIdx]);
+
+ childrenRWLock.ExitReadLock ();
+
+ base.RemoveChild (child);
}
public override bool ArrangeChildren { get { return true; } }
{
RegisteredLayoutings &= (~layoutType);
- if (layoutType == LayoutingType.ArrangeChildren) {
- int curOffset = Spacing;
+ if (layoutType == LayoutingType.ArrangeChildren && Children.Count > 0) {
+ Rectangle cb = ClientRectangle;
+
+ int tabSpace = tabWidth + leftSlope;
+ int computedSpacing = Math.Min(tabSpace, (cb.Width - rightSlope - leftSlope) / (Children.Count (c => c.Visible == true)));
+
TabItem[] tabItms = Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray();
+ int curOffset = leftSlope;
+
for (int i = 0; i < tabItms.Length; i++) {
if (!tabItms [i].Visible)
continue;
+// if (tabSizeHasChanged) {
+ tabItms [i].NotifyValueChanged ("TabHeight", tabHeight);
+ tabItms [i].NotifyValueChanged ("TabWidth", tabWidth);
+// tabSizeHasChanged = false;
+// }
if (!tabItms [i].HoldCursor)
tabItms [i].TabOffset = curOffset;
if (Orientation == Orientation.Horizontal) {
- if (tabItms [i].TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Width))
- return false;
- curOffset += tabItms [i].TabTitle.Slot.Width + Spacing;
- } else {
- if (tabItms [i].TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Height))
- return false;
- curOffset += tabItms [i].TabTitle.Slot.Height + Spacing;
- }
+ curOffset += computedSpacing;
+ } else
+ curOffset += computedSpacing;
}
//if no layouting remains in queue for item, registre for redraw
return base.UpdateLayout(layoutType);
}
+// public override void OnLayoutChanges (LayoutingType layoutType)
+// {
+// if (_orientation == Orientation.Horizontal) {
+// if (layoutType == LayoutingType.Width) {
+// computedSpacingOk = false;
+// RegisterForLayouting (LayoutingType.ArrangeChildren);
+// }
+// } else if (layoutType == LayoutingType.Height) {
+// computedSpacingOk = false;
+// RegisterForLayouting (LayoutingType.ArrangeChildren);
+// }
+//
+// base.OnLayoutChanges (layoutType);
+// }
+
protected override void onDraw (Context gr)
{
Rectangle rBack = new Rectangle (Slot.Size);
childrenRWLock.EnterReadLock ();
TabItem[] tabItms = Children.Cast<TabItem> ().OrderBy (t => t.ViewIndex).ToArray ();
- for (int i = 0; i < tabItms.Length; i++) {
- if (tabItms [i] == Children [SelectedTab])
- continue;
- tabItms [i].Paint (ref gr);
- }
+ int selTabViewIdx = -1;
if (SelectedTab < tabItms.Length && SelectedTab >= 0)
- Children [SelectedTab].Paint (ref gr);
+ selTabViewIdx = (Children [SelectedTab] as TabItem).ViewIndex;
childrenRWLock.ExitReadLock ();
+
+ int i = 0;
+ while (i < selTabViewIdx) {
+ tabItms [i].Paint (ref gr);
+ i++;
+ }
+ i = tabItms.Length - 1;
+ while (i > selTabViewIdx) {
+ tabItms [i].Paint (ref gr);
+ i--;
+ }
+
+ if (selTabViewIdx >= 0)
+ tabItms [selTabViewIdx].Paint (ref gr);
gr.Restore ();
}
- #region Mouse handling
- public override void checkHoverWidget (MouseMoveEventArgs e)
+ void Ti_TabTitle_LayoutChanged (object sender, LayoutingEventArgs e)
{
- if (IFace.HoverWidget != this) {
- IFace.HoverWidget = this;
- onMouseEnter (this, e);
- }
-
- if (SelectedTab > Children.Count - 1)
- return;
-
- if (((Children[SelectedTab] as TabItem).Content.Parent as GraphicObject).MouseIsIn(e.Position))
- {
- Children[SelectedTab].checkHoverWidget (e);
- return;
- }
- TabItem[] tabItms = Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray();
- for (int i = tabItms.Length - 1; i >= 0; i--) {
- if (tabItms [i].TabTitle.MouseIsIn(e.Position))
- {
- tabItms [i].checkHoverWidget (e);
- return;
- }
- }
+ if (e.LayoutType == LayoutingType.X)
+ RegisterForLayouting (LayoutingType.ArrangeChildren);
}
- #endregion
-
void Ti_MouseDown (object sender, MouseButtonEventArgs e)
{
SelectedTab = Children.IndexOf (sender as GraphicObject);