]> O.S.I.I.S - jp/crow.git/commitdiff
tabview debug and improvments
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 15 Dec 2020 22:28:36 +0000 (23:28 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 15 Dec 2020 22:28:36 +0000 (23:28 +0100)
Crow/Crow.csproj
Crow/src/ISelectable.cs [new file with mode: 0644]
Crow/src/Widgets/TabItem.cs
Crow/src/Widgets/TabView.cs
Crow/src/Widgets/TemplatedGroup.cs

index faede56da87f85f03c5f1ed73459452ff372a486..8d7886b676b0b78d23946bc58366b25eb4193e78 100644 (file)
@@ -49,7 +49,7 @@
        </ItemGroup>
 
        <ItemGroup>
-               <Content Include="$(SolutionDir)Images\crow.png" Pack="true" PackagePath="" />
+               <Content Include="..\Images\crow.png" Pack="true" PackagePath="" />
                <Compile Include="src\**\*.cs" Exclude="src\Mono.Cairo\NativeMethods-internal.cs" />
                <EmbeddedResource Include="Templates\*.*">
                        <LogicalName>Crow.%(Filename).template</LogicalName>
diff --git a/Crow/src/ISelectable.cs b/Crow/src/ISelectable.cs
new file mode 100644 (file)
index 0000000..23fdcfd
--- /dev/null
@@ -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;
+               }
+
+       }
+}
index 109b1e533cf028e8542c75dc56fe01b7c2f0c0ba..61a34c2e0c52f39bf0937c97d2323a950af170b5 100644 (file)
@@ -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);
index 9a88d72f0e07a36a6e844271d134de9123f302c1..103c8ac9ab12c5b6b619e302e8422df3c564db8c 100644 (file)
@@ -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 (ref gr);
+                               tabItms[i].Paint (ref gr);
                                i++;
                        }
                        i = tabItms.Length - 1;
                        while (i > selTabViewIdx) {
-                               tabItms [i].Paint (ref gr);
+                               tabItms[i].Paint (ref gr);
                                i--;
                        }
 
-                       if (selTabViewIdx >= 0)
-                               tabItms [selTabViewIdx].Paint (ref gr);
+                       if (selTabViewIdx >= 0 && selTabViewIdx < tabItms.Length)
+                               tabItms[selTabViewIdx].Paint (ref 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;
        }
 }
 
index f4e63f4379187ede19007438d1bbf601ae1fc02d..95ed4dc81214da3a343d7b14f421db99e13d9f8f 100644 (file)
@@ -501,7 +501,12 @@ namespace Crow {
                        }
                }
                internal virtual void itemClick(object sender, MouseButtonEventArgs e){
+                       /*if (selectedItemContainer == sender)
+                               return;*/
                        //SelectedIndex = (int)((IList)data)?.IndexOf((sender as Widget).DataSource);
+                       ISelectable si = SelectedItem as ISelectable;
+                       if (si != null)
+                               si.IsSelected = false;
                        if (selectedItemContainer is ListItem li)
                                li.IsSelected = false;
                        selectedItemContainer = sender as Widget;
@@ -510,6 +515,9 @@ namespace Crow {
                        if (selectedItemContainer == null)
                                return;
                        SelectedItem = selectedItemContainer.DataSource;
+                       si = SelectedItem as ISelectable;
+                       if (si != null)
+                               si.IsSelected = true;
                        //SelectedIndex = items.Children.IndexOf(sender as Widget);
                }
 
@@ -524,6 +532,7 @@ namespace Crow {
                {
                        if (disposing)
                                cancelLoadingThread ();
+                       Data = null;
                        base.Dispose (disposing);
                }
 
@@ -546,5 +555,6 @@ namespace Crow {
                        if (data is IObservableList)
                                (data as IObservableList).RaiseEdit ();
                }
+               
        }
 }