Skip to content

Commit 1bb37ee

Browse files
committed
TabControl refactoring
1 parent f993c04 commit 1bb37ee

File tree

3 files changed

+103
-122
lines changed

3 files changed

+103
-122
lines changed

src/Myra/Graphics2D/UI/Selectors/TabControl.cs

+83-103
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System.ComponentModel;
22
using Myra.Graphics2D.UI.Styles;
33
using System;
4-
using System.Collections.ObjectModel;
54
using System.Xml.Serialization;
5+
using Microsoft.Xna.Framework;
66

77
namespace Myra.Graphics2D.UI
88
{
@@ -19,13 +19,15 @@ public class TabControl : Selector<Grid, TabItem>
1919
private Grid _gridButtons;
2020
private Panel _panelContent;
2121
private TabSelectorPosition _selectorPosition;
22-
private ObservableCollection<Proportion> _buttonProportions;
23-
private ObservableCollection<Proportion> _contentProportions;
2422

2523
[Browsable(false)]
2624
[XmlIgnore]
2725
public TabControlStyle TabControlStyle { get; set; }
2826

27+
[Browsable(false)]
28+
[XmlIgnore]
29+
public override SelectionMode SelectionMode { get => base.SelectionMode; set => base.SelectionMode = value; }
30+
2931
[DefaultValue(HorizontalAlignment.Left)]
3032
public override HorizontalAlignment HorizontalAlignment
3133
{
@@ -62,94 +64,13 @@ public TabSelectorPosition TabSelectorPosition
6264
}
6365
set
6466
{
65-
if (_selectorPosition != value)
67+
if (value == _selectorPosition)
6668
{
67-
// Content proportions and widgets need to be reversed if switching between
68-
// right/bottom and top/left
69-
bool newValueIsTopOrLeft = value == TabSelectorPosition.Top ||
70-
value == TabSelectorPosition.Left;
71-
bool oldValueWasBottomOrRight = _selectorPosition == TabSelectorPosition.Bottom ||
72-
_selectorPosition == TabSelectorPosition.Right;
73-
74-
bool newValueIsTopOrBottom = value == TabSelectorPosition.Top ||
75-
value == TabSelectorPosition.Bottom;
76-
bool oldValueWasTopOrBottom = _selectorPosition == TabSelectorPosition.Top ||
77-
_selectorPosition == TabSelectorPosition.Bottom;
78-
79-
bool transposeContent = newValueIsTopOrLeft == oldValueWasBottomOrRight;
80-
ObservableCollection<Proportion> newButtonProportions;
81-
ObservableCollection<Proportion> newContentProportions;
82-
83-
if (newValueIsTopOrBottom)
84-
{
85-
newButtonProportions = _gridButtons.ColumnsProportions;
86-
newContentProportions = InternalChild.RowsProportions;
87-
}
88-
else
89-
{
90-
newButtonProportions = _gridButtons.RowsProportions;
91-
newContentProportions = InternalChild.ColumnsProportions;
92-
}
93-
94-
Grid.SetColumn(_panelContent, value == TabSelectorPosition.Left ? 1 : 0);
95-
Grid.SetRow(_panelContent, value == TabSelectorPosition.Top ? 1 : 0);
96-
97-
Grid.SetColumn(_gridButtons, value == TabSelectorPosition.Right ? 1 : 0);
98-
Grid.SetRow(_gridButtons, value == TabSelectorPosition.Bottom ? 1 : 0);
99-
100-
if (newButtonProportions != _buttonProportions)
101-
{
102-
for (int i = 0; i < _buttonProportions.Count; i++)
103-
{
104-
newButtonProportions.Add(_buttonProportions[i]);
105-
}
106-
107-
_buttonProportions.Clear();
108-
_buttonProportions = newButtonProportions;
109-
}
110-
111-
if (newContentProportions != _contentProportions)
112-
{
113-
for (int i = 0; i < _contentProportions.Count; i++)
114-
{
115-
newContentProportions.Add(_contentProportions[i]);
116-
}
117-
118-
_contentProportions.Clear();
119-
_contentProportions = newContentProportions;
120-
}
121-
122-
if (transposeContent)
123-
{
124-
for (int i = 0; i < InternalChild.Widgets.Count; i++)
125-
{
126-
_contentProportions.Move(_contentProportions.Count - 1, i);
127-
InternalChild.Widgets.Move(InternalChild.Widgets.Count - 1, i);
128-
}
129-
}
130-
131-
for (int i = 0; i < InternalChild.Widgets.Count; i++)
132-
{
133-
Widget w = InternalChild.Widgets[i];
134-
if (newValueIsTopOrBottom)
135-
{
136-
Grid.SetColumn(w, 0);
137-
Grid.SetRow(w, i);
138-
}
139-
else
140-
{
141-
Grid.SetColumn(w, i);
142-
Grid.SetRow(w, 0);
143-
}
144-
}
145-
146-
_selectorPosition = value;
147-
148-
if (newValueIsTopOrBottom != oldValueWasTopOrBottom)
149-
{
150-
UpdateGridPositions();
151-
}
69+
return;
15270
}
71+
72+
_selectorPosition = value;
73+
UpdateSelectorPosition();
15374
}
15475
}
15576

@@ -160,19 +81,19 @@ public TabControl(string styleName = Stylesheet.DefaultStyleName) : base(new Gri
16081

16182
_gridButtons = new Grid();
16283
_panelContent = new Panel();
163-
Grid.SetRow(_panelContent, 1);
16484

165-
// Default to Top selector position:
16685
_selectorPosition = TabSelectorPosition.Top;
167-
_buttonProportions = _gridButtons.ColumnsProportions;
168-
_contentProportions = InternalChild.RowsProportions;
86+
_gridButtons.DefaultColumnProportion = Proportion.Auto;
87+
_gridButtons.DefaultRowProportion = Proportion.Auto;
88+
89+
InternalChild.DefaultColumnProportion = Proportion.Fill;
90+
InternalChild.DefaultRowProportion = Proportion.Fill;
16991

170-
// button, then content
171-
_contentProportions.Add(new Proportion());
172-
_contentProportions.Add(new Proportion(ProportionType.Fill));
17392
InternalChild.Widgets.Add(_gridButtons);
17493
InternalChild.Widgets.Add(_panelContent);
17594

95+
UpdateSelectorPosition();
96+
17697
ClipToBounds = true;
17798

17899
SetStyle(styleName);
@@ -194,11 +115,72 @@ private void ItemOnChanged(object sender, EventArgs eventArgs)
194115
InvalidateMeasure();
195116
}
196117

197-
private void UpdateGridPositions()
118+
private void UpdateSelectorPosition()
119+
{
120+
switch (_selectorPosition)
121+
{
122+
case TabSelectorPosition.Top:
123+
Grid.SetColumn(_gridButtons, 0);
124+
Grid.SetRow(_gridButtons, 0);
125+
126+
Grid.SetColumn(_panelContent, 0);
127+
Grid.SetRow(_panelContent, 1);
128+
129+
InternalChild.ColumnsProportions.Clear();
130+
InternalChild.RowsProportions.Clear();
131+
InternalChild.RowsProportions.Add(Proportion.Auto);
132+
InternalChild.RowsProportions.Add(Proportion.Fill);
133+
break;
134+
135+
case TabSelectorPosition.Right:
136+
Grid.SetColumn(_gridButtons, 1);
137+
Grid.SetRow(_gridButtons, 0);
138+
139+
Grid.SetColumn(_panelContent, 0);
140+
Grid.SetRow(_panelContent, 0);
141+
142+
InternalChild.ColumnsProportions.Clear();
143+
InternalChild.ColumnsProportions.Add(Proportion.Fill);
144+
InternalChild.ColumnsProportions.Add(Proportion.Auto);
145+
InternalChild.RowsProportions.Clear();
146+
break;
147+
148+
case TabSelectorPosition.Bottom:
149+
Grid.SetColumn(_gridButtons, 0);
150+
Grid.SetRow(_gridButtons, 1);
151+
152+
Grid.SetColumn(_panelContent, 0);
153+
Grid.SetRow(_panelContent, 0);
154+
155+
156+
InternalChild.ColumnsProportions.Clear();
157+
InternalChild.RowsProportions.Clear();
158+
InternalChild.RowsProportions.Add(Proportion.Fill);
159+
InternalChild.RowsProportions.Add(Proportion.Auto);
160+
break;
161+
162+
case TabSelectorPosition.Left:
163+
Grid.SetColumn(_gridButtons, 0);
164+
Grid.SetRow(_gridButtons, 0);
165+
166+
Grid.SetColumn(_panelContent, 1);
167+
Grid.SetRow(_panelContent, 0);
168+
169+
InternalChild.ColumnsProportions.Clear();
170+
InternalChild.ColumnsProportions.Add(Proportion.Auto);
171+
InternalChild.ColumnsProportions.Add(Proportion.Fill);
172+
InternalChild.RowsProportions.Clear();
173+
break;
174+
}
175+
176+
UpdateButtonsGrid();
177+
}
178+
179+
private void UpdateButtonsGrid()
198180
{
199181
bool tabSelectorIsLeftOrRight = TabSelectorPosition == TabSelectorPosition.Left ||
200182
TabSelectorPosition == TabSelectorPosition.Right;
201-
for (var i = 0; i < Items.Count; ++i)
183+
for (var i = 0; i < _gridButtons.Widgets.Count; ++i)
202184
{
203185
var widget = _gridButtons.Widgets[i];
204186
if (tabSelectorIsLeftOrRight)
@@ -234,7 +216,7 @@ protected override void InsertItem(TabItem item, int index)
234216
var panel = new HorizontalStackPanel
235217
{
236218
Spacing = item.ImageTextSpacing,
237-
VerticalAlignment = item.ContentVerticalAlignment
219+
VerticalAlignment = VerticalAlignment.Stretch
238220
};
239221

240222
panel.Widgets.Add(image);
@@ -253,12 +235,11 @@ protected override void InsertItem(TabItem item, int index)
253235

254236
button.Click += ButtonOnClick;
255237

256-
_buttonProportions.Insert(index, new Proportion(ProportionType.Auto));
257238
_gridButtons.Widgets.Insert(index, button);
258239

259240
item.Button = button;
260241

261-
UpdateGridPositions();
242+
UpdateButtonsGrid();
262243

263244
if (Items.Count == 1)
264245
{
@@ -272,15 +253,14 @@ protected override void RemoveItem(TabItem item)
272253
item.Changed -= ItemOnChanged;
273254

274255
var index = _gridButtons.Widgets.IndexOf(item.Button);
275-
_buttonProportions.RemoveAt(index);
276256
_gridButtons.Widgets.RemoveAt(index);
277257

278258
if (SelectedItem == item)
279259
{
280260
SelectedItem = null;
281261
}
282262

283-
UpdateGridPositions();
263+
UpdateButtonsGrid();
284264
}
285265

286266
private void UpdateContent()

src/Myra/Graphics2D/UI/Selectors/TabItem.cs

-7
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,6 @@ public Widget Content
9191
[XmlIgnore]
9292
public int ImageTextSpacing { get; set; }
9393

94-
[DefaultValue(VerticalAlignment.Stretch)]
95-
96-
public VerticalAlignment ContentVerticalAlignment
97-
{
98-
get; set;
99-
} = VerticalAlignment.Stretch;
100-
10194
[DefaultValue(null)]
10295
public int? Height { get; set; }
10396

src/MyraPad/AsyncTasksQueue.cs

+20-12
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
using Myra.Graphics2D.UI;
22
using System;
3+
using System.Collections.Concurrent;
34
using System.Threading;
45

56
namespace MyraPad
67
{
78
internal class AsyncTasksQueue
89
{
910
private bool _running = true;
10-
private string _projectXml;
11-
private string _objectXml;
11+
private readonly ConcurrentQueue<string> _projectXmls = new ConcurrentQueue<string>();
12+
private readonly ConcurrentQueue<string> _objectXmls = new ConcurrentQueue<string>();
1213

1314
private readonly AutoResetEvent _refreshProjectEvent = new AutoResetEvent(false);
1415
private readonly AutoResetEvent _waitForQuitEvent = new AutoResetEvent(false);
@@ -20,13 +21,13 @@ public AsyncTasksQueue()
2021

2122
public void QueueLoadProject(string xml)
2223
{
23-
_projectXml = xml;
24+
_projectXmls.Enqueue(xml);
2425
_refreshProjectEvent.Set();
2526
}
2627

2728
public void QueueLoadObject(string xml)
2829
{
29-
_objectXml = xml;
30+
_objectXmls.Enqueue(xml);
3031
_refreshProjectEvent.Set();
3132
}
3233

@@ -43,31 +44,40 @@ private void RefreshProc(object state)
4344
{
4445
_refreshProjectEvent.WaitOne();
4546

46-
if (!string.IsNullOrEmpty(_projectXml))
47+
// Get last project xml
48+
var projectXml = string.Empty;
49+
while (_projectXmls.Count > 0)
50+
{
51+
_projectXmls.TryDequeue(out projectXml);
52+
}
53+
if (!string.IsNullOrEmpty(projectXml))
4754
{
4855
try
4956
{
5057
Studio.MainForm.QueueSetStatusText("Reloading Project...");
51-
Studio.MainForm.NewProject = Project.LoadFromXml(_projectXml, Studio.MainForm.AssetManager);
58+
Studio.MainForm.NewProject = Project.LoadFromXml(projectXml, Studio.MainForm.AssetManager);
5259
Studio.MainForm.QueueSetStatusText(string.Empty);
5360
}
5461
catch (Exception ex)
5562
{
5663
Studio.MainForm.QueueClearExplorer();
5764
Studio.MainForm.QueueSetStatusText(ex.Message);
5865
}
59-
60-
_projectXml = null;
6166
}
6267

63-
if (!string.IsNullOrEmpty(_objectXml))
68+
var objectXml = string.Empty;
69+
while (_objectXmls.Count > 0)
70+
{
71+
_objectXmls.TryDequeue(out objectXml);
72+
}
73+
if (!string.IsNullOrEmpty(objectXml))
6474
{
6575
if (Studio.MainForm.Project != null)
6676
{
6777
try
6878
{
6979
Studio.MainForm.QueueSetStatusText("Reloading Object...");
70-
Studio.MainForm.NewObject = Studio.MainForm.Project.LoadObjectFromXml(_objectXml, Studio.MainForm.AssetManager);
80+
Studio.MainForm.NewObject = Studio.MainForm.Project.LoadObjectFromXml(objectXml, Studio.MainForm.AssetManager);
7181
Studio.MainForm.QueueSetStatusText(string.Empty);
7282
}
7383
catch (Exception ex)
@@ -76,8 +86,6 @@ private void RefreshProc(object state)
7686
Studio.MainForm.QueueSetStatusText(ex.Message);
7787
}
7888
}
79-
80-
_objectXml = null;
8189
}
8290
}
8391

0 commit comments

Comments
 (0)