Advertisement
szymski

Untitled

Jun 17th, 2016
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.99 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Diagnostics;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10.  
  11. namespace CodeEditorComponent.Source
  12. {
  13. public partial class CodeEditorComponent : Panel
  14. {
  15. public Options Options { get; } = new Options();
  16.  
  17. public List<Line> Lines { get; } = new List<Line>();
  18. public int LineCount => Lines.Count;
  19. private Line CurrentLine => Lines[Caret.Y];
  20.  
  21. private Caret Caret { get; set; } = new Caret();
  22.  
  23. private float fontWidth, fontHeight;
  24. private int lineNumberBarWidth = 100;
  25.  
  26. private float TotalLineHeight => fontHeight + Options.LineHeightMargin;
  27.  
  28. VScrollBar vScrollBar = new VScrollBar();
  29. HScrollBar hScrollBar = new HScrollBar();
  30.  
  31. float scrollX = 0f, scrollY = 0f;
  32.  
  33. Label debugLabel = new Label();
  34.  
  35. public CodeEditorComponent()
  36. {
  37. InitializeComponent();
  38.  
  39. InitScrollBars();
  40. InitEvents();
  41. InitTest();
  42. }
  43.  
  44. #region Initialization
  45.  
  46. void InitEvents()
  47. {
  48. DoubleBuffered = true;
  49.  
  50. Options.OnFontChanged += OnFontChanged;
  51.  
  52. OnLineCountChanged += UpdateVScrollbar;
  53. OnLineModified += UpdateHScrollbar;
  54.  
  55. OnCodeSet += UpdateVScrollbar;
  56.  
  57. Timer timer = new Timer();
  58. timer.Interval = 10;
  59. timer.Enabled = true;
  60. timer.Tick += (sender, args) => Refresh();
  61. }
  62.  
  63. void InitScrollBars()
  64. {
  65. vScrollBar.Parent = this;
  66. vScrollBar.Dock = DockStyle.Right;
  67. vScrollBar.LargeChange = 1;
  68. vScrollBar.ValueChanged += (sender, args) => scrollY = vScrollBar.Value;
  69.  
  70. hScrollBar.Parent = this;
  71. hScrollBar.Dock = DockStyle.Bottom;
  72. }
  73.  
  74. void InitTest()
  75. {
  76. debugLabel.Parent = this;
  77. debugLabel.Dock = DockStyle.Bottom;
  78.  
  79. Options.Font = new Font("Consolas", 13, FontStyle.Regular);
  80. Code = @"import std.stdio;
  81. void main() {
  82. writeln(""Hello world!"");
  83. }
  84.  
  85. int soManyLinesOfCode() {
  86. int gay = 5;
  87. gay ^= 255;
  88. gay |= 5;
  89. return gay;
  90. }
  91.  
  92. int soManyLinesOfCode() {
  93. int gay = 5;
  94. gay ^= 255;
  95. gay |= 5;
  96. return gay;
  97. }
  98.  
  99. int soManyLinesOfCode() {
  100. int gay = 5;
  101. gay ^= 255;
  102. gay |= 5;
  103. return gay;
  104. }
  105.  
  106. int soManyLinesOfCode() {
  107. int gay = 5;
  108. gay ^= 255;
  109. gay |= 5;
  110. return gay;
  111. }
  112. ";
  113. }
  114.  
  115. #endregion
  116.  
  117. protected void OnFontChanged(Font font)
  118. {
  119. var size = CreateGraphics().MeasureString("0", font, 200, StringFormat.GenericTypographic);
  120.  
  121. fontWidth = size.Width;
  122. fontHeight = size.Height;
  123. }
  124.  
  125. protected override void OnSizeChanged(EventArgs e)
  126. {
  127. base.OnSizeChanged(e);
  128. Refresh();
  129. }
  130.  
  131. public override Cursor Cursor => Cursors.IBeam;
  132.  
  133. public string Code
  134. {
  135. get { return Lines.Select(l => l.Text).Aggregate((a, b) => $"{a}\r\n{b}"); }
  136. set
  137. {
  138. Lines.Clear();
  139.  
  140. foreach (string line in value.Replace("\r\n", "\n").Split('\n'))
  141. Lines.Add(new Line() { Text = line });
  142.  
  143. OnCodeSet?.Invoke();
  144.  
  145. Refresh();
  146. }
  147. }
  148.  
  149. #region Code Editing
  150.  
  151. void InsertTextAtCurrentPosition(string text)
  152. {
  153. InsertText(Caret.X, Caret.Y, text);
  154. }
  155.  
  156. void InsertText(int x, int y, string text)
  157. {
  158. CurrentLine.Text = CurrentLine.Text.Insert(Caret.X, text);
  159. MoveCaret(text.Length, 0);
  160. OnLineModified?.Invoke(y);
  161.  
  162. Refresh();
  163. }
  164.  
  165. void RemoveTextAtPreviousPosition()
  166. {
  167. if (Caret.Y == 0 && Caret.X == 0)
  168. return;
  169.  
  170. MoveCaret(-1, 0);
  171. RemoveText(Caret.X, Caret.Y, 1);
  172. }
  173.  
  174. void RemoveText(int x, int y, int length)
  175. {
  176. if (x >= CurrentLine.Length)
  177. {
  178. if (LineCount <= 1)
  179. return;
  180.  
  181. CurrentLine.Text += Lines[y + 1].Text;
  182. Lines.RemoveAt(y + 1);
  183.  
  184. OnLineCountChanged?.Invoke();
  185. }
  186. else
  187. {
  188. CurrentLine.Text = CurrentLine.Text.Remove(x, length <= CurrentLine.Length ? length : CurrentLine.Length);
  189. }
  190.  
  191. OnLineModified?.Invoke(y);
  192.  
  193. Refresh();
  194. }
  195.  
  196. void InsertLineAtCurrentPosition()
  197. {
  198. InsertLine(Caret.X, Caret.Y);
  199. }
  200.  
  201. void InsertLine(int x, int y)
  202. {
  203. Line newLine = new Line() { Text = CurrentLine.Text.Substring(x) };
  204. Lines.Insert(y + 1, newLine);
  205. if (CurrentLine.Length > x)
  206. CurrentLine.Text = CurrentLine.Text.Remove(x);
  207. MoveCaret(1, 0);
  208.  
  209. OnLineModified?.Invoke(y);
  210. OnLineModified?.Invoke(y + 1);
  211. OnLineCountChanged?.Invoke();
  212.  
  213. Refresh();
  214. }
  215.  
  216. void InsertTabAtCurrentPosition()
  217. {
  218. InsertTab(Caret.X, Caret.Y);
  219. }
  220.  
  221. void InsertTab(int x, int y)
  222. {
  223. InsertText(x, y, new string(' ', GetDistanceToNextIndent(x)));
  224. }
  225.  
  226. int GetDistanceToNextIndent(int x)
  227. {
  228. return x % Options.TabToSpaces != 0 ? 4 - (x % Options.TabToSpaces) : Options.TabToSpaces;
  229. }
  230.  
  231. #endregion
  232.  
  233. void UpdateVScrollbar()
  234. {
  235. vScrollBar.Maximum = LineCount - 1;
  236. }
  237.  
  238. void UpdateHScrollbar(int line)
  239. {
  240. // TODO: Horizontal scrollbar update
  241. }
  242. }
  243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement