Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace CodeEditorComponent.Source
- {
- public partial class CodeEditorComponent : Panel
- {
- public Options Options { get; } = new Options();
- public List<Line> Lines { get; } = new List<Line>();
- public int LineCount => Lines.Count;
- private Line CurrentLine => Lines[Caret.Y];
- private Caret Caret { get; set; } = new Caret();
- private float fontWidth, fontHeight;
- private int lineNumberBarWidth = 100;
- private float TotalLineHeight => fontHeight + Options.LineHeightMargin;
- VScrollBar vScrollBar = new VScrollBar();
- HScrollBar hScrollBar = new HScrollBar();
- float scrollX = 0f, scrollY = 0f;
- Label debugLabel = new Label();
- public CodeEditorComponent()
- {
- InitializeComponent();
- InitScrollBars();
- InitEvents();
- InitTest();
- }
- #region Initialization
- void InitEvents()
- {
- DoubleBuffered = true;
- Options.OnFontChanged += OnFontChanged;
- OnLineCountChanged += UpdateVScrollbar;
- OnLineModified += UpdateHScrollbar;
- OnCodeSet += UpdateVScrollbar;
- Timer timer = new Timer();
- timer.Interval = 10;
- timer.Enabled = true;
- timer.Tick += (sender, args) => Refresh();
- }
- void InitScrollBars()
- {
- vScrollBar.Parent = this;
- vScrollBar.Dock = DockStyle.Right;
- vScrollBar.LargeChange = 1;
- vScrollBar.ValueChanged += (sender, args) => scrollY = vScrollBar.Value;
- hScrollBar.Parent = this;
- hScrollBar.Dock = DockStyle.Bottom;
- }
- void InitTest()
- {
- debugLabel.Parent = this;
- debugLabel.Dock = DockStyle.Bottom;
- Options.Font = new Font("Consolas", 13, FontStyle.Regular);
- Code = @"import std.stdio;
- void main() {
- writeln(""Hello world!"");
- }
- int soManyLinesOfCode() {
- int gay = 5;
- gay ^= 255;
- gay |= 5;
- return gay;
- }
- int soManyLinesOfCode() {
- int gay = 5;
- gay ^= 255;
- gay |= 5;
- return gay;
- }
- int soManyLinesOfCode() {
- int gay = 5;
- gay ^= 255;
- gay |= 5;
- return gay;
- }
- int soManyLinesOfCode() {
- int gay = 5;
- gay ^= 255;
- gay |= 5;
- return gay;
- }
- ";
- }
- #endregion
- protected void OnFontChanged(Font font)
- {
- var size = CreateGraphics().MeasureString("0", font, 200, StringFormat.GenericTypographic);
- fontWidth = size.Width;
- fontHeight = size.Height;
- }
- protected override void OnSizeChanged(EventArgs e)
- {
- base.OnSizeChanged(e);
- Refresh();
- }
- public override Cursor Cursor => Cursors.IBeam;
- public string Code
- {
- get { return Lines.Select(l => l.Text).Aggregate((a, b) => $"{a}\r\n{b}"); }
- set
- {
- Lines.Clear();
- foreach (string line in value.Replace("\r\n", "\n").Split('\n'))
- Lines.Add(new Line() { Text = line });
- OnCodeSet?.Invoke();
- Refresh();
- }
- }
- #region Code Editing
- void InsertTextAtCurrentPosition(string text)
- {
- InsertText(Caret.X, Caret.Y, text);
- }
- void InsertText(int x, int y, string text)
- {
- CurrentLine.Text = CurrentLine.Text.Insert(Caret.X, text);
- MoveCaret(text.Length, 0);
- OnLineModified?.Invoke(y);
- Refresh();
- }
- void RemoveTextAtPreviousPosition()
- {
- if (Caret.Y == 0 && Caret.X == 0)
- return;
- MoveCaret(-1, 0);
- RemoveText(Caret.X, Caret.Y, 1);
- }
- void RemoveText(int x, int y, int length)
- {
- if (x >= CurrentLine.Length)
- {
- if (LineCount <= 1)
- return;
- CurrentLine.Text += Lines[y + 1].Text;
- Lines.RemoveAt(y + 1);
- OnLineCountChanged?.Invoke();
- }
- else
- {
- CurrentLine.Text = CurrentLine.Text.Remove(x, length <= CurrentLine.Length ? length : CurrentLine.Length);
- }
- OnLineModified?.Invoke(y);
- Refresh();
- }
- void InsertLineAtCurrentPosition()
- {
- InsertLine(Caret.X, Caret.Y);
- }
- void InsertLine(int x, int y)
- {
- Line newLine = new Line() { Text = CurrentLine.Text.Substring(x) };
- Lines.Insert(y + 1, newLine);
- if (CurrentLine.Length > x)
- CurrentLine.Text = CurrentLine.Text.Remove(x);
- MoveCaret(1, 0);
- OnLineModified?.Invoke(y);
- OnLineModified?.Invoke(y + 1);
- OnLineCountChanged?.Invoke();
- Refresh();
- }
- void InsertTabAtCurrentPosition()
- {
- InsertTab(Caret.X, Caret.Y);
- }
- void InsertTab(int x, int y)
- {
- InsertText(x, y, new string(' ', GetDistanceToNextIndent(x)));
- }
- int GetDistanceToNextIndent(int x)
- {
- return x % Options.TabToSpaces != 0 ? 4 - (x % Options.TabToSpaces) : Options.TabToSpaces;
- }
- #endregion
- void UpdateVScrollbar()
- {
- vScrollBar.Maximum = LineCount - 1;
- }
- void UpdateHScrollbar(int line)
- {
- // TODO: Horizontal scrollbar update
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement