Пример #1
0
        internal void Launch()
        {
            Console.WriteLine("Text Area...");

            using var windowServer = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 8 } };
            using var window = windowServer.CreateWindow(renderingContext);

            window.Title = "Text Area";
            window.BorderStyle = WindowBorderStyle.Sizable;
            window.Size = (900, 900);
            renderingContext.CurrentWindow = window;

            var viewportSize = window.ViewportSize;
            var windowSize = window.Size;
            var backend = new DrawingBackend(new EntryPointLoader(renderingContext))
            {
                PixelScaling = viewportSize.height / windowSize.height
            };

            var openTypeCollection = new OpenTypeCollection();
            var nameId = typeof(VectorGraphicsLauncher).Namespace + ".Resources.Hack-Regular.ttf";
            openTypeCollection.AddFontResource(nameId, () => Assembly.GetExecutingAssembly().GetManifestResourceStream(nameId)!);

            using var sharedContext = new SharedDrawingContext(backend, openTypeCollection);
            using var drawingContext = new DrawingContext(sharedContext)
            {
                ClearColor = new RgbaColor(35, 35, 35, 255)
            };

            var styles = new MonospaceTextStyles(256);
            var fontSubfamily = openTypeCollection.LookupFontSubfamily("Hack", FontSubfamily.Normal);
            styles.GetStyle(fontSubfamily, new RgbaColor(255, 255, 255, 255), new RgbaColor(0, 0, 0, 0));
            var textArea = new TextArea(styles, "Hack", fontSubfamily, 9);
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)!, "..", "..", "..", "TextAreaLauncher.cs");
            textArea.Load(path);
            const int textLeft = 20;
            const int textTop = 30;

            window.Scroll += (sender, e) =>
            {
                textArea.ScrollVertically(e.DeltaY * 30);
            };

            var hideCaret = true;

            window.KeyDown += (sender, e) =>
            {
                switch (e.Keycode)
                {
                    case Keycode.Up:
                        textArea.MoveUp();
                        hideCaret = false;
                        break;
                    case Keycode.Down:
                        textArea.MoveDown();
                        hideCaret = false;
                        break;
                    case Keycode.Left:
                        textArea.MoveLeft();
                        hideCaret = false;
                        break;
                    case Keycode.Right:
                        textArea.MoveRight();
                        hideCaret = false;
                        break;
                    case Keycode.F11:
                        textArea.FontPoints--;
                        break;
                    case Keycode.F12:
                        textArea.FontPoints++;
                        break;
                    case Keycode.Backspace:
                        textArea.Backspace();
                        hideCaret = false;
                        break;
                    case Keycode.Tab:
                        textArea.Tab();
                        hideCaret = false;
                        break;
                    case Keycode.Enter:
                        textArea.Enter();
                        hideCaret = false;
                        break;
                }
            };

            window.TextInput += (sender, e) =>
            {
                textArea.Insert(e.CodePoint);
                hideCaret = false;
            };

            window.MouseDown += (sender, e) =>
            {
                if (e.ChangedButton == MouseButton.Left)
                {
                    var (x, y) = window.CursorPosition;
                    textArea.LeftMouseDown(x, y);
                    hideCaret = false;
                }
            };

            var interruptThread = false;

            void draw()
            {
                renderingContext.CurrentWindow = window;
                drawingContext.SharedContext.PixelScaling = viewportSize.height / windowSize.height;

                drawingContext.StartDrawing();

                textArea.Render(drawingContext);

                drawingContext.FinishDrawing();

                renderingContext.SwapBuffers(window);
            }

            void resize()
            {
                viewportSize = window.ViewportSize;
                windowSize = window.Size;
                renderingContext.CurrentWindow = window;
                backend.WindowSize = windowSize;
                textArea.SetViewRectangle(textLeft, textTop, (windowSize.width - textLeft - 30), (windowSize.height - textTop - 50));
            }

            window.Resize += (sender, e) =>
            {
                resize();
                draw();
            };

            var runLoop = MainRunLoop.Create(windowServer);
            var text = default(DecoratedText<byte>);
            var version = 0;
            var th = new Thread(() =>
            {
                var regexList = new List<Regex>();
                var styleList = new List<MonospaceTextStyle>();

                regexList.Add(new Regex("\\b(break|case|class|const|else|false|float|for|foreach|" +
                    "if|int|internal|public|namespace|new|unsafe|using|string|switch|true|var|void)\\b"));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(81, 153, 213, 255), new RgbaColor(0, 0, 0, 0)));

                regexList.Add(new Regex(@"\b-?\d+(,\d+)*(\.\d+((e|E)\d+)?)?\b"));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(0, 0, 0, 255), new RgbaColor(230, 180, 50, 255)));

                regexList.Add(new Regex(@"""(\\.|[^""\\])*"""));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(250, 180, 230, 255), new RgbaColor(0, 0, 0, 0)));

                while (!interruptThread)
                {
                    var t = text;
                    text = null;
                    var v = version;
                    if (t != null)
                    {
                        var txt = new StyledMonospaceText(t, styles);
                        var builder = new StringBuilder();
                        for (int i = 0; i < txt.LineCount; i++)
                        {
                            builder.Clear();
                            txt.CopyLineTo(i, builder);
                            var str = builder.ToString();
                            for (int j = 0; j < regexList.Count; j++)
                            {
                                var m = regexList[j].Match(str);
                                var s = styleList[j];
                                while (m.Success)
                                {
                                    txt.StyleRange(s, (i, m.Index), (i, m.Index + m.Length));
                                    m = m.NextMatch();
                                }
                            }
                        }
                        void f(int currentVersion, StyledMonospaceText newText)
                        {
                            runLoop.InvokeLater(0, (lag) =>
                            {
                                if (textArea.Version == currentVersion)
                                {
                                    textArea.SetText(newText);
                                }
                            });
                        }
                        f(v, txt);
                    }
                    Thread.Sleep(500);
                }
            });

            void blink(long lag)
            {
                textArea.HideCaret = hideCaret;
                hideCaret = !hideCaret;
                if (textArea.RequireRestyle)
                {
                    text = textArea.GetText();
                    version = textArea.Version;
                }
                runLoop.InvokeLater(500, blink);
            }

            runLoop.InvokeLater(500, blink);

            window.Closed += (sender, e) =>
            {
                backend.Dispose();
                runLoop.Interrupt();
                interruptThread = true;
            };

            resize();
            runLoop.RecurringActions.Add((time) =>
            {
                if (textArea.RequireRender)
                {
                    draw();
                }
            });
            th.Start();
            window.Visible = true;
            runLoop.Run();

            Console.WriteLine("Text Area done.");
        }