aboutsummaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2021-02-02 20:48:59 +0100
committerj-p <jp_bruyere@hotmail.com>2021-02-06 20:28:02 +0100
commit0c3faab041a4af8607d7ba0bd7e08b38c36a8945 (patch)
treeb381edf0fb66fd62a45838dd26c96d58beccda79
parente732b84972c7fc5dd224fc9920abdd111377d3f4 (diff)
TabView activate new tab or not
-rw-r--r--Crow/Crow.csproj2
-rw-r--r--Crow/src/ISelectable.cs20
-rw-r--r--Crow/src/Widgets/TabItem.cs12
-rw-r--r--Crow/src/Widgets/TabView.cs196
-rw-r--r--Crow/src/styling/StyleReader.cs2
5 files changed, 143 insertions, 89 deletions
diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj
index fc39aa69..840469c8 100644
--- a/Crow/Crow.csproj
+++ b/Crow/Crow.csproj
@@ -23,7 +23,7 @@
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn>
- <DefineConstants>_DESIGN_MODE;_MEASURE_TIME</DefineConstants>
+ <DefineConstants>DESIGN_MODE;_MEASURE_TIME</DefineConstants>
<EnableDefaultItems>false</EnableDefaultItems>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<!--<AllowUnsafeBlocks>true</AllowUnsafeBlocks>-->
diff --git a/Crow/src/ISelectable.cs b/Crow/src/ISelectable.cs
new file mode 100644
index 00000000..23fdcfd6
--- /dev/null
+++ b/Crow/src/ISelectable.cs
@@ -0,0 +1,20 @@
+// Copyright (c) 2020-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+
+using System;
+
+namespace Crow
+{
+ public interface ISelectable
+ {
+ event EventHandler Selected;
+ event EventHandler Unselected;
+
+ bool IsSelected {
+ get;
+ set;
+ }
+
+ }
+}
diff --git a/Crow/src/Widgets/TabItem.cs b/Crow/src/Widgets/TabItem.cs
index 109b1e53..61a34c2e 100644
--- a/Crow/src/Widgets/TabItem.cs
+++ b/Crow/src/Widgets/TabItem.cs
@@ -83,6 +83,7 @@ namespace Crow
public Measure TabHeight {
get { return tview == null ? Measure.Fit : tview.TabHeight; }
}
+ public bool IsActiveTab => tview?.ActiveTab == this;
public Measure TabWidth {
get { return tview == null ? Measure.Fit : tview.TabWidth; }
}
@@ -93,10 +94,15 @@ namespace Crow
if (isSelected == value)
return;
- if (tview != null)
- tview.SelectedTab = tview.Children.IndexOf(this);
+ //Console.WriteLine ($"TabItem({this.dataSource}).IsSelected: {isSelected} -> {value}");
+ /*if (tview != null)
+ tview.SelectedTab = tview.Children.IndexOf(this);*/
isSelected = value;
+
+ if (IsSelected)
+ tview.ActiveTab = this;
+
NotifyValueChangedAuto (isSelected);
RegisterForRedraw ();
}
@@ -158,7 +164,7 @@ namespace Crow
gr.StrokePreserve ();
gr.ClipPreserve ();
- if (tv.isSelectedTab (this))
+ if (IsActiveTab)
SelectedBackground.SetAsSource (IFace, gr, ClientRectangle);
else
Background.SetAsSource (IFace, gr, ClientRectangle);
diff --git a/Crow/src/Widgets/TabView.cs b/Crow/src/Widgets/TabView.cs
index b7c963d1..93c77364 100644
--- a/Crow/src/Widgets/TabView.cs
+++ b/Crow/src/Widgets/TabView.cs
@@ -12,7 +12,7 @@ namespace Crow
public class TabView : Group
{
#region CTOR
- public TabView() {}
+ public TabView () { }
public TabView (Interface iface, string style = null) : base (iface, style) { }
#endregion
@@ -22,13 +22,13 @@ namespace Crow
int rightSlope;
Measure tabHeight, tabWidth;
Orientation _orientation;
- int selectedTab = -1;
+ TabItem activeTab;
+ bool activateNewTab;
#endregion
#region public properties
- [DefaultValue(Orientation.Horizontal)]
- public virtual Orientation Orientation
- {
+ [DefaultValue (Orientation.Horizontal)]
+ public virtual Orientation Orientation {
get { return _orientation; }
set {
if (_orientation == value)
@@ -38,13 +38,12 @@ 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
- {
+ [DefaultValue (16)]
+ public int LeftSlope {
get { return leftSlope; }
set {
if (leftSlope == value)
@@ -56,9 +55,8 @@ namespace Crow
}
}
//bool tabSizeHasChanged = false;
- [DefaultValue(16)]
- public int RightSlope
- {
+ [DefaultValue (16)]
+ public int RightSlope {
get { return rightSlope; }
set {
if (rightSlope == value)
@@ -69,7 +67,7 @@ namespace Crow
//RegisterForLayouting (LayoutingType.ArrangeChildren);
}
}
- [DefaultValue("18")]
+ [DefaultValue ("18")]
public Measure TabHeight {
get { return tabHeight; }
set {
@@ -77,15 +75,15 @@ namespace Crow
return;
tabHeight = value;
NotifyValueChangedAuto (tabHeight);
-// childrenRWLock.EnterReadLock ();
-// foreach (GraphicObject ti in Children) {
-// ti.NotifyValueChanged ("TabHeight", tabHeight);
-// }
-// childrenRWLock.ExitReadLock ();
+ // childrenRWLock.EnterReadLock ();
+ // foreach (GraphicObject ti in Children) {
+ // ti.NotifyValueChanged ("TabHeight", tabHeight);
+ // }
+ // childrenRWLock.ExitReadLock ();
RegisterForLayouting (LayoutingType.ArrangeChildren);
}
}
- [DefaultValue("120")]
+ [DefaultValue ("120")]
public Measure TabWidth {
get { return adjustedTab > 0 ? (Measure)adjustedTab : tabWidth; }
set {
@@ -93,38 +91,59 @@ namespace Crow
return;
tabWidth = value;
NotifyValueChangedAuto (TabWidth);
-//
-// childrenRWLock.EnterReadLock ();
-// foreach (GraphicObject ti in Children) {
-// ti.NotifyValueChanged ("TabWidth", tabWidth);
-// }
-// childrenRWLock.ExitReadLock ();
+ //
+ // childrenRWLock.EnterReadLock ();
+ // foreach (GraphicObject ti in Children) {
+ // ti.NotifyValueChanged ("TabWidth", tabWidth);
+ // }
+ // childrenRWLock.ExitReadLock ();
RegisterForLayouting (LayoutingType.ArrangeChildren);
}
}
-
- public virtual int SelectedTab {
- get { return selectedTab; }
+ /// <summary>
+ /// If true new tabs will be set as the active tab of this tabview.
+ /// </summary>
+ [DefaultValue (true)]
+ public bool ActivateNewTab {
+ get => activateNewTab;
set {
- if (value == selectedTab)
+ if (activateNewTab == value)
+ return;
+ activateNewTab = value;
+ NotifyValueChangedAuto (activateNewTab);
+ }
+ }
+ public virtual TabItem ActiveTab {
+ get => activeTab;
+ set {
+ if (activeTab == value)
return;
- if (selectedTab < Children.Count && selectedTab >= 0)
- (Children [selectedTab] as TabItem).IsSelected = false;
+ Console.WriteLine ($"TabView.ActiveTab: {activeTab?.DataSource} -> {value?.DataSource}");
+ bool selState = true;
- selectedTab = value;
+ if (value != null) {
+ if (activeTab != null) {
+ selState = activeTab.IsSelected;
+ activeTab.IsSelected = false;
+ ActiveTab.NotifyValueChanged ("IsActiveTab", false);
+ }
+ activeTab = value;
+ ActiveTab.IsSelected = selState;
+ ActiveTab.NotifyValueChanged ("IsActiveTab", true);
+ } else
+ activeTab = value;
- if (selectedTab < Children.Count && selectedTab >= 0)
- (Children [selectedTab] as TabItem).IsSelected = true;
+ /*if (activeTab != null)
+ value.IsSelected = true;*/
- NotifyValueChangedAuto (selectedTab);
+ NotifyValueChangedAuto (activeTab);
RegisterForRedraw ();
}
}
#endregion
- public override void AddChild (Widget child)
- {
+ public override void AddChild (Widget child) {
TabItem ti = child as TabItem;
if (ti == null)
throw new Exception ("TabView control accept only TabItem as child.");
@@ -135,11 +154,14 @@ namespace Crow
base.AddChild (child);
- SelectedTab = ti.ViewIndex = Children.Count - 1;
+ ti.ViewIndex = Children.Count - 1;
+
+ if (ActivateNewTab || ti.ViewIndex == 0)
+ ti.IsSelected = true;
+
this.RegisterForLayouting (LayoutingType.ArrangeChildren);
}
- public override void RemoveChild (Widget child)
- {
+ public override void RemoveChild (Widget child) {
TabItem ti = child as TabItem;
if (ti == null)
throw new Exception ("TabView control accept only TabItem as child.");
@@ -150,8 +172,20 @@ namespace Crow
childrenRWLock.EnterReadLock ();
- TabItem[] tabItms = Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray();
- int selTabViewIdx = -1;
+ TabItem[] tabItms = Children.Cast<TabItem> ().OrderBy (t => t.ViewIndex).ToArray ();
+ if (ActiveTab == ti) {
+ if (tabItms.Length > 1) {
+ if (ti.ViewIndex == tabItms.Length - 1)
+ ActiveTab = tabItms[ti.ViewIndex - 1];
+ else
+ ActiveTab = tabItms[ti.ViewIndex + 1];
+ } else
+ ActiveTab = null;
+ }
+ for (int i = ti.viewIndex + 1; i < tabItms.Length; i++)
+ tabItms[i].ViewIndex--;
+
+ /*int selTabViewIdx = -1;
if (SelectedTab < tabItms.Length && SelectedTab >= 0)
selTabViewIdx = (Children [SelectedTab] as TabItem).ViewIndex;
@@ -165,7 +199,7 @@ namespace Crow
if (selTabViewIdx < 0)
SelectedTab = -1;
else
- SelectedTab = Children.IndexOf (tabItms [selTabViewIdx]);
+ SelectedTab = Children.IndexOf (tabItms [selTabViewIdx]);*/
childrenRWLock.ExitReadLock ();
@@ -173,8 +207,7 @@ namespace Crow
}
public override bool ArrangeChildren { get { return true; } }
- public override bool UpdateLayout (LayoutingType layoutType)
- {
+ public override bool UpdateLayout (LayoutingType layoutType) {
RegisteredLayoutings &= (~layoutType);
if (layoutType == LayoutingType.ArrangeChildren && Children.Count > 0) {
@@ -184,7 +217,7 @@ namespace Crow
int tc = Children.Count (c => c.Visible == true);
if (tc > 0)
- tabSpace = Math.Min(tabSpace, (cb.Width-rightSlope) / tc);
+ tabSpace = Math.Min (tabSpace, (cb.Width - rightSlope) / tc);
if (tabSpace < tabWidth + leftSlope)
adjustedTab = tabSpace - leftSlope;
@@ -193,24 +226,24 @@ namespace Crow
//System.Diagnostics.Debug.WriteLine ("tabspace: {0} tw:{1}", tabSpace, tabWidth);
- childrenRWLock.EnterReadLock();
- TabItem[] tabItms = Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray();
- childrenRWLock.ExitReadLock();
+ childrenRWLock.EnterReadLock ();
+ TabItem[] tabItms = Children.Cast<TabItem> ().OrderBy (t => t.ViewIndex).ToArray ();
+ childrenRWLock.ExitReadLock ();
int curOffset = leftSlope;
for (int i = 0; i < tabItms.Length; i++) {
- if (!tabItms [i].Visible)
+ if (!tabItms[i].Visible)
continue;
- tabItms [i].NotifyValueChanged ("TabHeight", tabHeight);
- tabItms [i].NotifyValueChanged ("TabWidth", TabWidth);
- if (!tabItms [i].IsDragged) {
- tabItms [i].TabOffset = curOffset;
+ tabItms[i].NotifyValueChanged ("TabHeight", tabHeight);
+ tabItms[i].NotifyValueChanged ("TabWidth", TabWidth);
+ if (!tabItms[i].IsDragged) {
+ tabItms[i].TabOffset = curOffset;
//System.Diagnostics.Debug.WriteLine ("offset: {0}=>{1}", tabItms [i].Name, tabItms [i].TabOffset);
}
if (Orientation == Orientation.Horizontal) {
curOffset += tabSpace;
} else
- curOffset += tabSpace;
+ curOffset += tabSpace;
}
//if no layouting remains in queue for item, registre for redraw
@@ -220,25 +253,27 @@ namespace Crow
return true;
}
- return base.UpdateLayout(layoutType);
+ return base.UpdateLayout (layoutType);
}
- public override void OnLayoutChanges (LayoutingType layoutType)
- {
+ public override void OnLayoutChanges (LayoutingType layoutType) {
if (_orientation == Orientation.Horizontal) {
if (layoutType == LayoutingType.Width)
- RegisterForLayouting (LayoutingType.ArrangeChildren);
+ RegisterForLayouting (LayoutingType.ArrangeChildren);
} else if (layoutType == LayoutingType.Height)
- RegisterForLayouting (LayoutingType.ArrangeChildren);
-
+ RegisterForLayouting (LayoutingType.ArrangeChildren);
+
base.OnLayoutChanges (layoutType);
}
- protected override void onDraw (Context gr)
- {
+ internal TabItem[] VisibleTabsByViewIdx =>
+ Children.Where (tt => tt.Visible).Cast<TabItem> ().
+ OrderBy (t => t.ViewIndex).ToArray ();
+
+ protected override void onDraw (Context gr) {
Rectangle rBack = new Rectangle (Slot.Size);
Background.SetAsSource (IFace, gr, rBack);
- CairoHelpers.CairoRectangle(gr,rBack, CornerRadius);
+ CairoHelpers.CairoRectangle (gr, rBack, CornerRadius);
gr.Fill ();
gr.Save ();
@@ -251,34 +286,31 @@ namespace Crow
childrenRWLock.EnterReadLock ();
- TabItem[] tabItms = Children.Where(tt=>tt.Visible).Cast<TabItem> ().
- OrderBy (t => t.ViewIndex).ToArray ();
+ TabItem[] tabItms = VisibleTabsByViewIdx;
- int selTabViewIdx = -1;
- if (SelectedTab < tabItms.Length && SelectedTab >= 0)
- selTabViewIdx = (Children [SelectedTab] as TabItem).ViewIndex;
+ TabItem sti = ActiveTab;
+ int selTabViewIdx = sti == null ? tabItms.Length - 1 : sti.ViewIndex;
int i = 0;
while (i < selTabViewIdx) {
- tabItms [i].Paint (gr);
+ tabItms[i].Paint (gr);
i++;
}
i = tabItms.Length - 1;
while (i > selTabViewIdx) {
- tabItms [i].Paint (gr);
+ tabItms[i].Paint (gr);
i--;
}
- if (selTabViewIdx >= 0)
- tabItms [selTabViewIdx].Paint (gr);
+ if (selTabViewIdx >= 0 && selTabViewIdx < tabItms.Length)
+ tabItms[selTabViewIdx].Paint (gr);
childrenRWLock.ExitReadLock ();
gr.Restore ();
}
- protected override void onDragEnter (object sender, DragDropEventArgs e)
- {
+ protected override void onDragEnter (object sender, DragDropEventArgs e) {
base.onDragEnter (sender, e);
TabItem ti = e.DragSource as TabItem;
@@ -299,17 +331,13 @@ namespace Crow
}
- void Ti_TabTitle_LayoutChanged (object sender, LayoutingEventArgs e)
- {
- if (e.LayoutType == LayoutingType.X)
- RegisterForLayouting (LayoutingType.ArrangeChildren);
+ void Ti_TabTitle_LayoutChanged (object sender, LayoutingEventArgs e) {
+ if (e.LayoutType == LayoutingType.X)
+ RegisterForLayouting (LayoutingType.ArrangeChildren);
}
- void Ti_MouseDown (object sender, MouseButtonEventArgs e)
- {
- SelectedTab = Children.IndexOf (sender as Widget);
+ void Ti_MouseDown (object sender, MouseButtonEventArgs e) {
+ ActiveTab = sender as TabItem;
}
- internal bool isSelectedTab (TabItem ti) =>
- Children.IndexOf (ti) == selectedTab;
}
}
diff --git a/Crow/src/styling/StyleReader.cs b/Crow/src/styling/StyleReader.cs
index 21cddace..f4898b14 100644
--- a/Crow/src/styling/StyleReader.cs
+++ b/Crow/src/styling/StyleReader.cs
@@ -95,7 +95,7 @@ namespace Crow
break;
case ',':
ReadChar ();
- if (!(curState == States.classNames) || token.Length == 0)
+ if (curState != States.classNames || token.Length == 0)
throw new ParserException (line, column, "Unexpected char ','", resId);
targetsClasses.Add (token.ToString());
token.Clear();