mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
264 lines
7.9 KiB
C#
264 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Terminal.Gui;
|
|
using Terminal.Gui.TextEffects;
|
|
using static UICatalog.Scenario;
|
|
|
|
using Color = Terminal.Gui.TextEffects.Color;
|
|
using Animation = Terminal.Gui.TextEffects.Animation;
|
|
|
|
namespace UICatalog.Scenarios;
|
|
|
|
[ScenarioMetadata ("Text Effects", "Text Effects.")]
|
|
[ScenarioCategory ("Colors")]
|
|
public class TextEffectsScenario : Scenario
|
|
{
|
|
public override void Main ()
|
|
{
|
|
Application.Init ();
|
|
var top = Application.Top;
|
|
|
|
// Creates a window that occupies the entire terminal with a title.
|
|
var window = new Window ()
|
|
{
|
|
X = 0,
|
|
Y = 1, // Leaves one row for the toplevel menu
|
|
|
|
// By using Dim.Fill(), it will automatically resize without manual intervention
|
|
Width = Dim.Fill (),
|
|
Height = Dim.Fill (),
|
|
Title = "Text Effects Scenario"
|
|
};
|
|
|
|
// Create a large empty view.
|
|
var emptyView = new TextEffectsExampleView ()
|
|
{
|
|
X = 0,
|
|
Y = 0,
|
|
Width = Dim.Fill (),
|
|
Height = Dim.Fill (),
|
|
};
|
|
|
|
window.Add (emptyView);
|
|
|
|
// Create a label in the center of the window.
|
|
var label = new Label ()
|
|
{
|
|
X = Pos.Center (),
|
|
Y = Pos.Center (),
|
|
Width = 10,
|
|
Height = 1,
|
|
Text = "Hello"
|
|
};
|
|
window.Add (label);
|
|
|
|
Application.Run (window);
|
|
Application.Shutdown ();
|
|
}
|
|
}
|
|
|
|
internal class TextEffectsExampleView : View
|
|
{
|
|
Ball? _ball;
|
|
private bool resized;
|
|
|
|
protected override void OnViewportChanged (DrawEventArgs e)
|
|
{
|
|
base.OnViewportChanged (e);
|
|
resized = true;
|
|
}
|
|
|
|
public override void OnDrawContent (Rectangle viewport)
|
|
{
|
|
base.OnDrawContent (viewport);
|
|
|
|
if (
|
|
// First time
|
|
(_ball == null && viewport.Width > 0 && viewport.Height > 0)
|
|
|| resized)
|
|
{
|
|
_ball = new Ball (this);
|
|
_ball.Start ();
|
|
resized = false;
|
|
}
|
|
|
|
DrawTopLineGradient (viewport);
|
|
DrawRadialGradient (viewport);
|
|
|
|
_ball?.Draw ();
|
|
}
|
|
|
|
private void DrawRadialGradient (Rectangle viewport)
|
|
{
|
|
// Define the colors of the gradient stops
|
|
var stops = new List<Color>
|
|
{
|
|
Color.FromRgb(255, 0, 0), // Red
|
|
Color.FromRgb(0, 255, 0), // Green
|
|
Color.FromRgb(238, 130, 238) // Violet
|
|
};
|
|
|
|
// Define the number of steps between each color
|
|
var steps = new List<int> { 10, 10 }; // 10 steps between Red -> Green, and Green -> Blue
|
|
|
|
// Create the gradient
|
|
var radialGradient = new Gradient (stops, steps, loop: false);
|
|
|
|
// Define the size of the rectangle
|
|
int maxRow = 20;
|
|
int maxColumn = 40;
|
|
|
|
// Build the coordinate-color mapping for a radial gradient
|
|
var gradientMapping = radialGradient.BuildCoordinateColorMapping (maxRow, maxColumn, Gradient.Direction.Radial);
|
|
|
|
// Print the gradient
|
|
for (int row = 0; row <= maxRow; row++)
|
|
{
|
|
for (int col = 0; col <= maxColumn; col++)
|
|
{
|
|
var coord = new Coord (col, row);
|
|
var color = gradientMapping [coord];
|
|
|
|
SetColor (color);
|
|
|
|
AddRune (col+2, row+3, new Rune ('█'));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawTopLineGradient (Rectangle viewport)
|
|
{
|
|
|
|
// Define the colors of the rainbow
|
|
var stops = new List<Color>
|
|
{
|
|
Color.FromRgb(255, 0, 0), // Red
|
|
Color.FromRgb(255, 165, 0), // Orange
|
|
Color.FromRgb(255, 255, 0), // Yellow
|
|
Color.FromRgb(0, 128, 0), // Green
|
|
Color.FromRgb(0, 0, 255), // Blue
|
|
Color.FromRgb(75, 0, 130), // Indigo
|
|
Color.FromRgb(238, 130, 238) // Violet
|
|
};
|
|
|
|
// Define the number of steps between each color
|
|
var steps = new List<int>
|
|
{
|
|
20, // between Red and Orange
|
|
20, // between Orange and Yellow
|
|
20, // between Yellow and Green
|
|
20, // between Green and Blue
|
|
20, // between Blue and Indigo
|
|
20 // between Indigo and Violet
|
|
};
|
|
|
|
// Create the gradient
|
|
var rainbowGradient = new Gradient (stops, steps, loop: true);
|
|
|
|
for (int x = 0; x < viewport.Width; x++)
|
|
{
|
|
double fraction = (double)x / (viewport.Width - 1);
|
|
Color color = rainbowGradient.GetColorAtFraction (fraction);
|
|
|
|
SetColor (color);
|
|
|
|
AddRune (x, 0, new Rune ('█'));
|
|
}
|
|
}
|
|
|
|
private void SetColor (Color color)
|
|
{
|
|
// Assuming AddRune is a method you have for drawing at specific positions
|
|
Application.Driver.SetAttribute (
|
|
new Attribute (
|
|
new Terminal.Gui.Color (color.R, color.G, color.B),
|
|
new Terminal.Gui.Color (color.R, color.G, color.B)
|
|
)); // Setting color based on RGB
|
|
|
|
}
|
|
|
|
public class Ball
|
|
{
|
|
public Animation Animation { get; private set; }
|
|
public Scene BouncingScene { get; private set; }
|
|
public View Viewport { get; private set; }
|
|
public EffectCharacter Character { get; private set; }
|
|
|
|
public Ball (View viewport)
|
|
{
|
|
Viewport = viewport;
|
|
Character = new EffectCharacter (1, "O", 0, 0);
|
|
Animation = Character.Animation;
|
|
CreateBouncingScene ();
|
|
CreateMotionPath ();
|
|
}
|
|
|
|
private void CreateBouncingScene ()
|
|
{
|
|
BouncingScene = Animation.NewScene (isLooping: true);
|
|
int width = Viewport.Frame.Width;
|
|
int height = Viewport.Frame.Height;
|
|
double frequency = 4 * Math.PI / width; // Double the frequency
|
|
|
|
for (int x = 0; x < width; x++)
|
|
{
|
|
int y = (int)((height) / 2 * (1 + Math.Sin (frequency * x))); // Decrease amplitude
|
|
BouncingScene.AddFrame ("O", 1);
|
|
}
|
|
|
|
for (int x = width - 1; x >= 0; x--)
|
|
{
|
|
int y = (int)((height) / 2 * (1 + Math.Sin (frequency * x))); // Decrease amplitude
|
|
BouncingScene.AddFrame ("O", 1);
|
|
}
|
|
}
|
|
|
|
private void CreateMotionPath ()
|
|
{
|
|
int width = Viewport.Frame.Width;
|
|
int height = Viewport.Frame.Height;
|
|
double frequency = 4 * Math.PI / width; // Double the frequency
|
|
|
|
var path = Character.Motion.CreatePath ("sineWavePath", speed: 1, loop: true);
|
|
|
|
for (int x = 0; x < width; x++)
|
|
{
|
|
int y = (int)((height) / 2 * (1 + Math.Sin (frequency * x))); // Decrease amplitude
|
|
path.AddWaypoint (new Waypoint ($"waypoint_{x}", new Coord (x, y)));
|
|
}
|
|
|
|
for (int x = width - 1; x >= 0; x--)
|
|
{
|
|
int y = (int)((height) / 2 * (1 + Math.Sin (frequency * x))); // Decrease amplitude
|
|
path.AddWaypoint (new Waypoint ($"waypoint_{x}", new Coord (x, y)));
|
|
}
|
|
|
|
Character.Motion.ActivatePath (path);
|
|
}
|
|
|
|
public void Start ()
|
|
{
|
|
Animation.ActivateScene (BouncingScene);
|
|
new Thread (() =>
|
|
{
|
|
while (true)
|
|
{
|
|
Thread.Sleep (10); // Adjust the speed of animation
|
|
Character.Tick ();
|
|
|
|
Application.Invoke (() => Viewport.SetNeedsDisplay ());
|
|
}
|
|
})
|
|
{ IsBackground = true }.Start ();
|
|
}
|
|
|
|
public void Draw ()
|
|
{
|
|
Driver.SetAttribute (Viewport.ColorScheme.Normal);
|
|
Viewport.AddRune (Character.Motion.CurrentCoord.Column, Character.Motion.CurrentCoord.Row, new Rune ('O'));
|
|
}
|
|
}
|
|
}
|