diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-03-06 10:39:36 +0100 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-03-06 10:39:36 +0100 |
| commit | 975df273eafe358482d892c108fbba1fdc5cac1f (patch) | |
| tree | c55b31151da9f92b52fd52885d52a4f8442ef3be /src/GraphicObjects | |
| parent | 3726ed97fabc1d4614ef2adc5592d21ef1147e9f (diff) | |
tab improvments
Diffstat (limited to 'src/GraphicObjects')
| -rw-r--r-- | src/GraphicObjects/GenericStack.cs | 10 | ||||
| -rw-r--r-- | src/GraphicObjects/TabItem.cs | 73 | ||||
| -rw-r--r-- | src/GraphicObjects/TabView.cs | 213 |
3 files changed, 183 insertions, 113 deletions
diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs index 19c70076..f23b0bba 100644 --- a/src/GraphicObjects/GenericStack.cs +++ b/src/GraphicObjects/GenericStack.cs @@ -28,6 +28,7 @@ using System.ComponentModel; using System.Diagnostics; using System.Xml.Serialization; using System; +using System.Linq; namespace Crow { @@ -79,13 +80,8 @@ 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; diff --git a/src/GraphicObjects/TabItem.cs b/src/GraphicObjects/TabItem.cs index 676904b5..92cb20d8 100644 --- a/src/GraphicObjects/TabItem.cs +++ b/src/GraphicObjects/TabItem.cs @@ -42,6 +42,8 @@ namespace Crow public event EventHandler QueryClose; + internal TabView tview = null; + #region Private fields GraphicObject titleWidget; int tabOffset; @@ -87,20 +89,9 @@ namespace Crow 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) @@ -112,7 +103,12 @@ namespace Crow 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; } @@ -127,20 +123,23 @@ namespace Crow { 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); @@ -149,7 +148,6 @@ namespace Crow gr.LineWidth = 1; Foreground.SetAsSource (gr); gr.StrokePreserve (); - gr.Clip (); base.onDraw (gr); gr.Restore (); @@ -162,7 +160,7 @@ namespace Crow 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; @@ -176,7 +174,7 @@ namespace Crow { base.onMouseUp (sender, e); HoldCursor = false; - (Parent as TabView).UpdateLayout (LayoutingType.ArrangeChildren); + tview.UpdateLayout (LayoutingType.ArrangeChildren); } public override void onMouseMove (object sender, MouseMoveEventArgs e) { @@ -185,25 +183,26 @@ namespace Crow 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); diff --git a/src/GraphicObjects/TabView.cs b/src/GraphicObjects/TabView.cs index 3b250c0e..9d2f1145 100644 --- a/src/GraphicObjects/TabView.cs +++ b/src/GraphicObjects/TabView.cs @@ -41,14 +41,16 @@ namespace Crow #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; } @@ -60,33 +62,83 @@ namespace Crow 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); @@ -95,12 +147,6 @@ namespace Crow } #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; @@ -109,13 +155,14 @@ namespace Crow 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) @@ -123,11 +170,30 @@ namespace Crow 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; } } @@ -135,23 +201,29 @@ namespace Crow { 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 @@ -163,6 +235,21 @@ namespace Crow 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); @@ -182,47 +269,35 @@ namespace Crow 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); |