/// <summary> /// Creates empty text box. /// </summary> /// <param name="name">Name of the widget</param> /// <param name="pos">Position of the text box</param> /// <param name="length">Maximum width</param> /// <param name="text">Value of textbox (default: empty).</param> /// <param name="fc">Foreground color (default gray).</param> /// <param name="bc">Background color (default black).</param> public TextBox(string name, Position pos, int length, string text = "", ConsoleColor fc = ConsoleColor.Gray, ConsoleColor bc = ConsoleColor.Black) : base(name, pos, length, 1, fc, bc) { this.Text = text; this._isEdited = false; }
/// <summary> /// Initializes a new rectangle structure based on the /// positions of its upper left and lower right vertices. /// </summary> /// <param name="tl">Position of the top left vertex of the rectangle.</param> /// <param name="br">Position of the bottom right vertex of the rectangle.</param> public Rectangle(Position tl, Position br) { Left = tl.X; Top = tl.Y; Width = br.X - tl.X; Height = br.Y - tl.Y; }
/// <summary> /// Creates empty frame. /// </summary> /// <param name="name">Name of the widget.</param> /// <param name="pos">Position of the frame.</param> /// <param name="width">Size of the frame.</param> /// <param name="height">Size of the frame.</param> /// <param name="title">Frame title.</param> /// <param name="fc">Foreground color (default gray).</param> /// <param name="bc">Background color (default black).</param> public Frame(string name, Position pos, int width, int height, string title = "", ConsoleColor fc = ConsoleColor.Gray, ConsoleColor bc = ConsoleColor.Black) : base(name, pos, width, height, false, fc, bc) { Children = new Dictionary<string, Widget>(); Title = title; }
/// <summary> /// Creates progress bar. /// </summary> /// <param name="name">Name of the widget.</param> /// <param name="pos">Position of the progress bar.</param> /// <param name="width">Width of the progress bar</param> /// <param name="maxValue">Maximum value.</param> /// <param name="value">Current value (default: 0).</param> /// <param name="fc">Foreground color (default gray).</param> /// <param name="bc">Background color (default black).</param> public ProgressBar(string name, Position pos, int width, int maxValue, float value = 0.0f, ConsoleColor fc = ConsoleColor.Gray, ConsoleColor bc = ConsoleColor.Black) : base(name, pos, width, 1, false, fc, bc) { this.Value = value; this.MaxValue = maxValue; }
/// <summary> /// Creates an widget. /// </summary> /// <param name="name">Name of the widget.</param> /// <param name="pos">Position of the widget.</param> /// <param name="width">Size of the widget.</param> /// <param name="height">Size of the widget.</param> /// <param name="isSelectable">If true widget can be selected.</param> /// <param name="fc">Foreground color (default gray).</param> /// <param name="bc">Background color (default black).</param> public Widget(string name, Position pos, int width, int height, bool isSelectable, ConsoleColor fc = ConsoleColor.Gray, ConsoleColor bc = ConsoleColor.Black) { this.Name = name; this.rectangle = new Rectangle(pos, new Position(pos.X + width, pos.Y + height)); this.ForegroundColor = fc; this.BackgroundColor = bc; _isSelectable = isSelectable; }
public override void Draw() { ConsoleColor fc = ForegroundColor; ConsoleColor bc = BackgroundColor; // If widget is selected // swap colors if (IsSelectable && IsSelected && !_isEdited) { fc = BackgroundColor; bc = ForegroundColor; } ConsoleKeyInfo info; if (_isEdited && Interface.Input.TryReadKey(out info)) { // ASCII code of pressed key int asciiCode = (int)info.KeyChar; // If pressed key is enter - stop editing if (info.Key == ConsoleKey.Enter) { _isEdited = false; UIManager.IsInputBlocked = false; } // If pressed key is backspace - remove last char else if (info.Key == ConsoleKey.Backspace) { if (Text.Length > 0) Text = Text.Remove(Text.Length - 1); } // If pressed key is a printable char // add this char to text else if (asciiCode >= 32 && asciiCode <= 126) { Text += info.KeyChar.ToString(); } } UIManager.DrawString(Position, "[" + Text + "]", fc, bc); if (_isEdited) { var CursorPos = new Position(Position.X + Text.Length + 1, Position.Y); var cfc = fc; if (((long)Tools.CurTime()) % 2 == 0) cfc = bc; UIManager.DrawString(CursorPos, "_", cfc, bc); } }
/// <summary> /// Finds the smallest rectangle that encloses both this /// instance and another given rectangle. /// </summary> /// <param name="rect">Rectangle to find the union of.</param> /// <returns>A rectangle that encloses both this instance and /// the given rectangle.</returns> public Rectangle Union(Rectangle rect) { if (Area == 0) return rect; if (rect.Area == 0) return this; var tl = new Position( Math.Min(this.Left, rect.Left), Math.Min(this.Top, rect.Top)); var br = new Position( Math.Max(this.Right, rect.Right), Math.Max(this.Bottom, rect.Bottom)); return new Rectangle(tl, br); }
/// <summary> /// Finds the nearest position within the rectangle to /// the specified location. /// </summary> /// <param name="pos">Position to find the closest position to.</param> /// <returns>The closest position within the rectangle to the /// specified location.</returns> public Position NearestPosition(Position pos) { return new Position(pos.X.Clamp(Left, Right - 1), pos.Y.Clamp(Top, Bottom - 1)); }
/// <summary> /// Tests to see if the given position is within the bounds /// of this rectangle. /// </summary> /// <param name="pos">Position to perform an intersection /// test with.</param> /// <returns>True if the position is within the bounds of this /// rectangle, and false otherwise.</returns> public bool Intersects(Position pos) { return this.Left <= pos.X && this.Top <= pos.Y && this.Right > pos.X && this.Bottom > pos.Y; }
/// <summary> /// Finds the rectangle describing the intersection between /// this and another rectangle if one exists, and otherwise /// an empty rectangle. /// </summary> /// <param name="rect">Rectangle to find the intersection with.</param> /// <returns>The intersecting rectangle if one exists, and /// otherwise the zero rectangle.</returns> public Rectangle Intersection(Rectangle rect) { if (!Intersects(rect) && !IsAdjacent(rect)) return Rectangle.Zero; var tl = new Position( Math.Max(this.Left, rect.Left), Math.Max(this.Top, rect.Top)); var br = new Position( Math.Min(this.Right, rect.Right), Math.Min(this.Bottom, rect.Bottom)); return new Rectangle(tl, br); }
/// <summary> /// Gets a sequence of positions that trace a line from /// this position to the specified destination. /// </summary> /// <param name="dest">Destination to trace a line to.</param> /// <returns>A sequence of positions forming a line.</returns> /// <remarks> /// From http://bit.ly/QNHZ7i /// </remarks> public IEnumerable<Position> BresenhamLine(Position dest) { var a = this; var b = dest; int dx = Math.Abs(b.X - a.X); int dy = Math.Abs(b.Y - a.Y); int sx = a.X < b.X ? 1 : -1; int sy = a.Y < b.Y ? 1 : -1; int err = dx - dy; for (;;) { yield return a; if (a.X == b.X && a.Y == b.Y) yield break; int e2 = 2 * err; if (e2 > -dy) { err = err - dy; a.X += sx; } if (e2 < dx) { err = err + dx; a.Y += sy; } } }
/// <summary> /// Creates new label. /// </summary> /// <param name="name">Name of the widget.</param> /// <param name="pos">Position of the label.</param> /// <param name="text">Text of the label.</param> /// <param name="fc">Foreground color (default gray).</param> /// <param name="bc">Background color (default black).</param> public Label(string name, Position pos, string text, ConsoleColor fc = ConsoleColor.Gray, ConsoleColor bc = ConsoleColor.Black) : base(name, pos, text.Length, 1, false, fc, bc) { this.Text = text; }
/// <summary> /// A map of the 16 possible neighbouring tile solidity /// states to the characters that should be used when /// drawing walls. /// /// TODO: Move to a definition file, allowing for different /// types of walls? /// </summary> /// <summary> /// Renders the tiles deemed visible within the room corresponding /// to this visibility mask to the specified location on the screen. /// </summary> /// <param name="vis">Visibility mask to draw from.</param> /// <param name="rect">Clipping rectangle in level-space.</param> /// <param name="screenPos">Position on the screen that the top-left /// of the rectangle should be drawn to.</param> /// <param name="attribs">Attributes to be used when drawing tiles /// and entities.</param> public static void Draw(this RoomVisibility vis, Rectangle rect, Position screenPos, DrawAttributes attribs, ulong time) { var subRect = vis.Rect.Intersection(rect); var roomPos = vis.Rect.TopLeft; if (subRect.Width * subRect.Height <= 0) return; // Move the screen position and clipping rectangle to room-space. screenPos += roomPos - rect.TopLeft; rect = subRect - roomPos; foreach (var tile in vis.GetVisible(time)) { if (rect.Intersects(tile.Position)) { tile.Draw(screenPos + tile.Position, attribs, true); } } foreach (var tile in vis.GetRemembered(time)) { if (rect.Intersects(tile.Position)) { tile.Draw(screenPos + tile.Position, new DrawAttributes(0), false); } } }
/// <summary> /// Marks a specific tile within the room as being visible /// at the given time. /// </summary> /// <param name="pos">Position of the tile to mark as visible.</param> /// <param name="appearance">Appearance of the tile at the time /// of being seen.</param> /// <param name="time">Time at which the tile was seen.</param> public void Reveal(Position pos, TileAppearance appearance, ulong time) { _mask[pos.X, pos.Y] = Math.Max(_mask[pos.X, pos.Y], time); _tiles[pos.X, pos.Y] = appearance; LastVisibleTime = Math.Max(LastVisibleTime, time); }
/// <summary> /// Marks a specific tile within the room as being visible /// at the given time. /// </summary> /// <param name="pos">Position of the tile to mark as visible.</param> /// <param name="time">Time at which the tile was seen.</param> public void Reveal(Position pos, ulong time) { _mask[pos.X, pos.Y] = Math.Max(_mask[pos.X, pos.Y], time); LastVisibleTime = Math.Max(LastVisibleTime, time); }
/// <summary> /// Updates the visibility of each tile within the room from a specified /// origin of sight, with a given maximum view radius. /// </summary> /// <param name="origin">Position of the observer.</param> /// <param name="maxRadius">Maximum view radius.</param> /// <param name="time">Time at which visibility is being tested.</param> /// <returns>True if any tiles are currently visible, and false otherwise.</returns> public bool UpdateVisibility(Position origin, int maxRadius, ulong time) { if ((Room.Rect.NearestPosition(origin) - origin).LengthSquared > maxRadius * maxRadius) { return false; } foreach (var pos in Room.Rect.Positions) { if ((pos - origin).LengthSquared > maxRadius * maxRadius) continue; var rel = pos - Room.Rect.TopLeft; if (_mask[rel.X, rel.Y] >= time) continue; foreach (var mid in origin.BresenhamLine(pos)) { rel = mid - Room.Rect.TopLeft; if (Room.RelativeRect.Intersects(rel)) { Reveal(rel, time); } if (Room[rel].State != TileState.Floor) break; } } return LastVisibleTime >= time; }
/// <summary> /// Renders text /// </summary> /// <param name="pos">Position of first character.</param> /// <param name="text">Text to render.</param> /// <param name="fc">Foreground color (default gray).</param> /// <param name="bc">Background color (default black).</param> public static void DrawString(Position pos, string text, ConsoleColor fc = ConsoleColor.Gray, ConsoleColor bc = ConsoleColor.Black) { for (var x = 0; x < text.Length; x++) { Interface.Display.SetCell(pos.X + x, pos.Y, text[x], fc, bc); } }
/// <summary> /// Creates an widget that can be used. /// </summary> /// <param name="name">Name of the widget.</param> /// <param name="pos">Position of the widget.</param> /// <param name="width">Size of the widget.</param> /// <param name="height">Size of the widget.</param> /// <param name="fc">Foreground color (default gray).</param> /// <param name="bc">Background color (default black).</param> public UsableWidget(string name, Position pos, int width, int height, ConsoleColor fc = ConsoleColor.Gray, ConsoleColor bc = ConsoleColor.Black) : base(name, pos, width, height, true, fc, bc) { }
/// <summary> /// Renders an individual tile and any entities it contains to the /// specified location on the screen. /// </summary> /// <param name="tile">Tile to draw.</param> /// <param name="screenPos">Position on the screen to draw the tile.</param> /// <param name="attribs">Attributes to be used when drawing the tile and any entities.</param> /// <param name="visible">If true, the tile is currently within visible range.</param> public static void Draw(this TileAppearance tile, Position screenPos, DrawAttributes attribs, bool visible) { if (tile.EntityCount == 0) { Interface.Display.SetCell(screenPos, tile.Symbol, visible ? tile.ForeColor : ConsoleColor.DarkBlue, visible ? tile.BackColor : ConsoleColor.Black); } else { int index = (attribs.Flash / EntityFlashPeriod) % tile.EntityCount; var entity = tile[index]; var frame = entity[attribs.Flash % entity.FrameCount]; Interface.Display.SetCell(screenPos, frame.Symbol, visible ? frame.ForeColor : ConsoleColor.DarkBlue, visible ? frame.BackColor : ConsoleColor.Black); } }