1 // =================================
  2 // Copyright (c) 2025 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 using System.Windows.API;
  9 
 10 namespace System.Windows
 11 {
 12     public ControlCreateParams& LogViewControlCreateParams(ControlCreateParams& controlCreateParams)
 13     {
 14         return controlCreateParams.SetWindowClassName("System.Windows.LogView").SetWindowClassStyle(DoubleClickWindowClassStyle()).
 15             SetWindowStyle(cast<WindowStyle>(DefaultChildWindowStyle() | WindowStyle.WS_TABSTOP)).
 16             SetWindowClassBackgroundColor(SystemColor.COLOR_WINDOW).SetBackgroundColor(Color.White());
 17     }
 18 
 19     public TextViewCreateParams& LogViewTextViewCreateParams(TextViewCreateParams& textViewCreateParams)
 20     {
 21         return textViewCreateParams.SetFontSize(9.000000f);
 22     }
 23 
 24     public class LogViewCreateParams
 25     {
 26         public LogViewCreateParams(TextViewCreateParams& textViewCreateParams_) : textViewCreateParams(textViewCreateParams_)
 27         {
 28         }
 29         public LogViewCreateParams& Defaults()
 30         {
 31             return *this;
 32         }
 33         public TextViewCreateParams& textViewCreateParams;
 34     }
 35 
 36     public class LogView : TextView
 37     {
 38         public LogView(const FontFamily& fontFamily, float fontSize, const Color& backgroundColor, const Color& textColor, const Point& location, 
 39             const Size& size, Dock dock, Anchors anchors) : 
 40             base(fontFamily, fontSize, backgroundColor, textColor, location, size, dock, anchors)
 41         {
 42             SetReadOnly();
 43         }
 44         public LogView(const Point& location, const Size& size, Dock dock, Anchors anchors) : 
 45             this(FontFamily("Consolas"), 9.000000f, Color.White(), Color.Black(), location, size, dock, anchors)
 46         {
 47         }
 48         public LogView() : this(Point(0, 0), Size(0, 0), Dock.bottom, Anchors.none)
 49         {
 50         }
 51         public LogView(LogViewCreateParams& createParams) : base(createParams.textViewCreateParams)
 52         {
 53             SetReadOnly();
 54         }
 55         [nodiscard]
 56         public virtual Result<bool> WriteLine(const string& text)
 57         {
 58             int startLineNumber = cast<int>(Lines().Count() - 1);
 59             auto utf32Result = ToUtf32(text);
 60             if (utf32Result.Error())
 61             {
 62                 return Result<bool>(ErrorId(utf32Result.GetErrorId()));
 63             }
 64             List<ustring> lines = SplitTextIntoLines(utf32Result.Value());
 65             for (const ustring& line : lines)
 66             {
 67                 AddLine(line);
 68             }
 69             auto result = SetCaretLineCol(cast<int>(Lines().Count()), 1);
 70             if (result.Error()) return result;
 71             result = SetTextExtent();
 72             if (result.Error()) return result;
 73             result = ScrollToCaret();
 74             if (result.Error()) return result;
 75             SetChanged();
 76             result = InvalidateLines(startLineNumber, cast<int>(startLineNumber + lines.Count()));
 77             if (result.Error()) return result;
 78             return Result<bool>(true);
 79         }
 80         [nodiscard]
 81         protected override Result<bool> OnPaint(PaintEventArgs& args)
 82         {
 83             return base->OnPaint(args);
 84         }
 85         [nodiscard]
 86         protected override Result<bool> OnMouseDown(MouseEventArgs& args)
 87         {
 88             return base->OnMouseDown(args);
 89         }
 90         [nodiscard]
 91         protected override Result<bool> OnKeyDown(KeyEventArgs& args)
 92         {
 93             auto result = base->OnKeyDown(args);
 94             if (result.Error()) return result;
 95             if (CaretLine() == Lines().Count())
 96             {
 97                 result = Invalidate();
 98                 if (result.Error()) return result;
 99             }
100             return Result<bool>(true);
101         }
102     }