diff --git a/UICatalog/Scenarios/Images.cs b/UICatalog/Scenarios/Images.cs
index 16c350c24..fc690c3c8 100644
--- a/UICatalog/Scenarios/Images.cs
+++ b/UICatalog/Scenarios/Images.cs
@@ -23,13 +23,39 @@ public class Images : Scenario
private Point _screenLocationForSixel;
private string _encodedSixelData;
private Window _win;
+
+ ///
+ /// Number of sixel pixels per row of characters in the console.
+ ///
private NumericUpDown _pxY;
+
+ ///
+ /// Number of sixel pixels per column of characters in the console
+ ///
private NumericUpDown _pxX;
+ ///
+ /// View shown in sixel tab if sixel is supported
+ ///
+ private View _sixelSupported;
+
+ ///
+ /// View shown in sixel tab if sixel is not supported
+ ///
+ private View _sixelNotSupported;
+
+ private Tab _tabSixel;
+ private TabView _tabView;
+
+ ///
+ /// The view into which the currently opened sixel image is bounded
+ ///
+ private View _sixelView;
+
public override void Main ()
{
Application.Init ();
- _win = new Window { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}" };
+ _win = new() { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}" };
bool canTrueColor = Application.Driver?.SupportsTrueColor ?? false;
@@ -38,7 +64,7 @@ public class Images : Scenario
DisplayText = "Basic"
};
- var tabSixel = new Tab
+ _tabSixel = new()
{
DisplayText = "Sixel"
};
@@ -61,14 +87,17 @@ public class Images : Scenario
X = Pos.Right (lblDriverName) + 2,
Y = 1,
CheckedState = ConsoleDriver.SupportsSixel
- ? CheckState.Checked : CheckState.UnChecked,
+ ? CheckState.Checked
+ : CheckState.UnChecked,
Text = "Supports Sixel"
};
cbSupportsSixel.CheckedStateChanging += (s, e) =>
{
ConsoleDriver.SupportsSixel = e.NewValue == CheckState.Checked;
+ SetupSixelSupported (e.NewValue == CheckState.Checked);
};
+
_win.Add (cbSupportsSixel);
var cbUseTrueColor = new CheckBox
@@ -85,38 +114,41 @@ public class Images : Scenario
var btnOpenImage = new Button { X = Pos.Right (cbUseTrueColor) + 2, Y = 0, Text = "Open Image" };
_win.Add (btnOpenImage);
- var btnStartFire = new Button { X = Pos.Right (cbUseTrueColor) + 2, Y = 1, Text = "Start Fire" };
- _win.Add (btnStartFire);
-
- btnStartFire.Accept += BtnStartFireOnAccept;
-
- var tv = new TabView
+ _tabView = new()
{
- Y = Pos.Bottom (cbSupportsSixel), Width = Dim.Fill (), Height = Dim.Fill ()
+ Y = Pos.Bottom (btnOpenImage), Width = Dim.Fill (), Height = Dim.Fill ()
};
- tv.AddTab (tabBasic, true);
- tv.AddTab (tabSixel, false);
+ _tabView.AddTab (tabBasic, true);
+ _tabView.AddTab (_tabSixel, false);
BuildBasicTab (tabBasic);
- BuildSixelTab (tabSixel);
+ BuildSixelTab ();
+
+ SetupSixelSupported (cbSupportsSixel.CheckedState == CheckState.Checked);
btnOpenImage.Accept += OpenImage;
- _win.Add (tv);
+ _win.Add (_tabView);
Application.Run (_win);
_win.Dispose ();
Application.Shutdown ();
}
+ private void SetupSixelSupported (bool isSupported)
+ {
+ _tabSixel.View = isSupported ? _sixelSupported : _sixelNotSupported;
+ _tabView.SetNeedsDisplay ();
+ }
+
private void BtnStartFireOnAccept (object sender, HandledEventArgs e)
{
-
var fire = new DoomFire (_win.Frame.Width * _pxX.Value, _win.Frame.Height * _pxY.Value);
var encoder = new SixelEncoder ();
encoder.Quantizer.PaletteBuildingAlgorithm = new ConstPalette (fire.Palette);
- int counter = 0;
+ var counter = 0;
+
Application.AddTimeout (
TimeSpan.FromMilliseconds (30),
() =>
@@ -131,27 +163,31 @@ public class Images : Scenario
return true;
}
- var bmp = fire.GetFirePixels ();
+ Color [,] bmp = fire.GetFirePixels ();
// TODO: Static way of doing this, suboptimal
Application.Sixel.Clear ();
- Application.Sixel.Add (new SixelToRender
- {
- SixelData = encoder.EncodeSixel (bmp),
- ScreenPosition = new Point (0,0)
- });
- _win.SetNeedsDisplay();
+ Application.Sixel.Add (
+ new()
+ {
+ SixelData = encoder.EncodeSixel (bmp),
+ ScreenPosition = new (0, 0)
+ });
+
+ _win.SetNeedsDisplay ();
return true;
});
}
- ///
+ ///
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
_imageView.Dispose ();
+ _sixelNotSupported.Dispose ();
+ _sixelSupported.Dispose ();
}
private void OpenImage (object sender, HandledEventArgs e)
@@ -198,103 +234,138 @@ public class Images : Scenario
return;
}
-
_imageView.SetImage (img);
Application.Refresh ();
}
private void BuildBasicTab (Tab tabBasic)
{
- _imageView = new()
+ _imageView = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
CanFocus = true
-
};
tabBasic.View = _imageView;
}
- private void BuildSixelTab (Tab tabSixel)
+ private void BuildSixelTab ()
{
- tabSixel.View = new()
+ _sixelSupported = new()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
CanFocus = true
};
- var btnSixel = new Button { X = 0, Y = 0, Text = "Output Sixel", Width = Dim.Auto () };
- tabSixel.View.Add (btnSixel);
-
- var sixelView = new View
+ _sixelNotSupported = new()
+ {
+ Width = Dim.Fill (),
+ Height = Dim.Fill (),
+ CanFocus = true
+ };
+
+ _sixelNotSupported.Add (
+ new Label
+ {
+ Width = Dim.Fill (),
+ Height = Dim.Fill (),
+ TextAlignment = Alignment.Center,
+ Text = "Your driver does not support Sixel image format",
+ VerticalTextAlignment = Alignment.Center
+ });
+
+ _sixelView = new()
{
- Y = Pos.Bottom (btnSixel),
Width = Dim.Percent (50),
Height = Dim.Fill (),
BorderStyle = LineStyle.Dotted
};
- tabSixel.View.Add (sixelView);
+ _sixelSupported.Add (_sixelView);
+
+ var btnSixel = new Button
+ {
+ X = Pos.Right (_sixelView),
+ Y = 0,
+ Text = "Output Sixel", Width = Dim.Auto ()
+ };
+ btnSixel.Accept += OutputSixelButtonClick;
+ _sixelSupported.Add (btnSixel);
+
+ var btnStartFire = new Button
+ {
+ X = Pos.Right (_sixelView),
+ Y = Pos.Bottom (btnSixel),
+ Text = "Start Fire"
+ };
+ btnStartFire.Accept += BtnStartFireOnAccept;
+ _sixelSupported.Add (btnStartFire);
+
var lblPxX = new Label
{
- X = Pos.Right (sixelView),
+ X = Pos.Right (_sixelView),
+ Y = Pos.Bottom (btnStartFire) + 1,
Text = "Pixels per Col:"
};
- _pxX = new NumericUpDown
+
+ _pxX = new()
{
X = Pos.Right (lblPxX),
+ Y = Pos.Bottom (btnStartFire) + 1,
Value = 10
};
var lblPxY = new Label
{
X = lblPxX.X,
- Y = 1,
+ Y = Pos.Bottom (_pxX),
Text = "Pixels per Row:"
};
- _pxY = new NumericUpDown
+
+ _pxY = new()
{
X = Pos.Right (lblPxY),
- Y = 1,
+ Y = Pos.Bottom (_pxX),
Value = 20
};
- tabSixel.View.Add (lblPxX);
- tabSixel.View.Add (_pxX);
- tabSixel.View.Add (lblPxY);
- tabSixel.View.Add (_pxY);
+ _sixelSupported.Add (lblPxX);
+ _sixelSupported.Add (_pxX);
+ _sixelSupported.Add (lblPxY);
+ _sixelSupported.Add (_pxY);
- sixelView.DrawContent += SixelViewOnDrawContent;
+ _sixelView.DrawContent += SixelViewOnDrawContent;
+ }
+ private void OutputSixelButtonClick (object sender, HandledEventArgs e)
+ {
+ if (_imageView.FullResImage == null)
+ {
+ MessageBox.Query ("No Image Loaded", "You must first open an image. Use the 'Open Image' button above.", "Ok");
+ return;
+ }
- btnSixel.Accept += (s, e) =>
- {
+ _screenLocationForSixel = _sixelView.FrameToScreen ().Location;
- if (_imageView.FullResImage == null)
- {
- return;
- }
+ _encodedSixelData = GenerateSixelData (
+ _imageView.FullResImage,
+ _sixelView.Frame.Size,
+ _pxX.Value,
+ _pxY.Value);
-
- _screenLocationForSixel = sixelView.FrameToScreen ().Location;
- _encodedSixelData = GenerateSixelData(
- _imageView.FullResImage,
- sixelView.Frame.Size,
- _pxX.Value,
- _pxY.Value);
-
- // TODO: Static way of doing this, suboptimal
- Application.Sixel.Add (new SixelToRender
+ // TODO: Static way of doing this, suboptimal
+ Application.Sixel.Add (
+ new()
{
SixelData = _encodedSixelData,
ScreenPosition = _screenLocationForSixel
});
- };
}
- void SixelViewOnDrawContent (object sender, DrawEventArgs e)
+
+ private void SixelViewOnDrawContent (object sender, DrawEventArgs e)
{
if (!string.IsNullOrWhiteSpace (_encodedSixelData))
{
@@ -308,12 +379,12 @@ public class Images : Scenario
}
}
- public string GenerateSixelData(
- Image fullResImage,
- Size maxSize,
- int pixelsPerCellX,
- int pixelsPerCellY
- )
+ public string GenerateSixelData (
+ Image fullResImage,
+ Size maxSize,
+ int pixelsPerCellX,
+ int pixelsPerCellY
+ )
{
var encoder = new SixelEncoder ();
@@ -439,8 +510,6 @@ public class Images : Scenario
FullResImage = image;
SetNeedsDisplay ();
}
-
-
}
public class PaletteView : View
@@ -514,15 +583,12 @@ public class Images : Scenario
internal class ConstPalette : IPaletteBuilder
{
- private readonly List _palette;
+ private readonly List _palette;
public ConstPalette (Color [] palette) { _palette = palette.ToList (); }
- ///
- public List BuildPalette (List colors, int maxColors)
- {
- return _palette;
- }
+ ///
+ public List BuildPalette (List colors, int maxColors) { return _palette; }
}
public abstract class LabColorDistance : IColorDistance
@@ -738,15 +804,14 @@ public class MedianCutPaletteBuilder : IPaletteBuilder
}
}
-
public class DoomFire
{
- private int _width;
- private int _height;
- private Color [,] _firePixels;
+ private readonly int _width;
+ private readonly int _height;
+ private readonly Color [,] _firePixels;
private static Color [] _palette;
public Color [] Palette => _palette;
- private Random _random = new Random ();
+ private readonly Random _random = new ();
public DoomFire (int width, int height)
{
@@ -763,30 +828,30 @@ public class DoomFire
_palette = new Color [37]; // Using 37 colors as per the original Doom fire palette scale.
// First color is transparent black
- _palette [0] = new Color (0, 0, 0, 0); // Transparent black (ARGB)
+ _palette [0] = new (0, 0, 0, 0); // Transparent black (ARGB)
// The rest of the palette is fire colors
- for (int i = 1; i < 37; i++)
+ for (var i = 1; i < 37; i++)
{
- byte r = (byte)Math.Min (255, i * 7);
- byte g = (byte)Math.Min (255, i * 5);
- byte b = (byte)Math.Min (255, i * 2);
- _palette [i] = new Color (r, g, b); // Full opacity
+ var r = (byte)Math.Min (255, i * 7);
+ var g = (byte)Math.Min (255, i * 5);
+ var b = (byte)Math.Min (255, i * 2);
+ _palette [i] = new (r, g, b); // Full opacity
}
}
public void InitializeFire ()
{
// Set the bottom row to full intensity (simulate the base of the fire).
- for (int x = 0; x < _width; x++)
+ for (var x = 0; x < _width; x++)
{
_firePixels [x, _height - 1] = _palette [36]; // Max intensity fire.
}
// Set the rest of the pixels to black (transparent).
- for (int y = 0; y < _height - 1; y++)
+ for (var y = 0; y < _height - 1; y++)
{
- for (int x = 0; x < _width; x++)
+ for (var x = 0; x < _width; x++)
{
_firePixels [x, y] = _palette [0]; // Transparent black
}
@@ -796,9 +861,9 @@ public class DoomFire
public void AdvanceFrame ()
{
// Process every pixel except the bottom row
- for (int x = 0; x < _width; x++)
+ for (var x = 0; x < _width; x++)
{
- for (int y = 1; y < _height; y++) // Skip the last row (which is always max intensity)
+ for (var y = 1; y < _height; y++) // Skip the last row (which is always max intensity)
{
int srcX = x;
int srcY = y;
@@ -827,9 +892,5 @@ public class DoomFire
}
}
- public Color [,] GetFirePixels ()
- {
- return _firePixels;
- }
+ public Color [,] GetFirePixels () { return _firePixels; }
}
-