From e953f3a0c727e8026a3898a3241c2806576b2a93 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 3 Jan 2024 03:10:26 +0100 Subject: [PATCH] Add scrollbar to the log --- src/common/widgets/errorwindow.cpp | 79 +++++++++++++++++++++++++++++- src/common/widgets/errorwindow.h | 10 ++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/common/widgets/errorwindow.cpp b/src/common/widgets/errorwindow.cpp index e8b28b9dee..11057a1f61 100644 --- a/src/common/widgets/errorwindow.cpp +++ b/src/common/widgets/errorwindow.cpp @@ -5,6 +5,7 @@ #include "printf.h" #include #include +#include bool ErrorWindow::ExecModal(const std::string& text, const std::string& log) { @@ -105,7 +106,10 @@ void ErrorWindow::OnGeometryChanged() LogViewer::LogViewer(Widget* parent) : Widget(parent) { - SetNoncontentSizes(8.0, 8.0, 8.0, 8.0); + SetNoncontentSizes(8.0, 8.0, 3.0, 8.0); + + scrollbar = new Scrollbar(this); + scrollbar->FuncScroll = [=]() { OnScrollbarScroll(); }; } void LogViewer::SetText(const std::string& text, const std::string& log) @@ -135,6 +139,9 @@ void LogViewer::SetText(const std::string& text, const std::string& log) layout.AddText(text, largefont, Colorf::fromRgba8(255, 255, 170)); lines.push_back(layout); + scrollbar->SetRanges(0.0, (double)lines.size(), 1.0, 100.0); + scrollbar->SetPosition((double)lines.size() - 1.0); + Update(); } @@ -194,7 +201,8 @@ void LogViewer::OnPaint(Canvas* canvas) { double width = GetWidth(); double y = GetHeight(); - for (size_t i = lines.size(); i > 0 && y > 0.0; i--) + size_t start = std::min((size_t)std::round(scrollbar->GetPosition() + 1.0), lines.size()); + for (size_t i = start; i > 0 && y > 0.0; i--) { SpanLayout& layout = lines[i - 1]; layout.Layout(canvas, width); @@ -203,3 +211,70 @@ void LogViewer::OnPaint(Canvas* canvas) y -= layout.GetSize().height; } } + +void LogViewer::OnMouseWheel(const Point& pos, EInputKey key) +{ + if (key == IK_MouseWheelUp) + { + ScrollUp(4); + } + else if (key == IK_MouseWheelDown) + { + ScrollDown(4); + } +} + +void LogViewer::OnKeyDown(EInputKey key) +{ + if (key == IK_Home) + { + scrollbar->SetPosition(0.0f); + Update(); + } + if (key == IK_End) + { + scrollbar->SetPosition(scrollbar->GetMax()); + Update(); + } + else if (key == IK_PageUp) + { + ScrollUp(20); + } + else if (key == IK_PageDown) + { + ScrollDown(20); + } + else if (key == IK_Up) + { + ScrollUp(4); + } + else if (key == IK_Down) + { + ScrollDown(4); + } +} + +void LogViewer::OnScrollbarScroll() +{ + Update(); +} + +void LogViewer::OnGeometryChanged() +{ + double w = GetWidth(); + double h = GetHeight(); + double sw = scrollbar->GetPreferredWidth(); + scrollbar->SetFrameGeometry(Rect::xywh(w - sw, 0.0, sw, h)); +} + +void LogViewer::ScrollUp(int lines) +{ + scrollbar->SetPosition(std::max(scrollbar->GetPosition() - (double)lines, 0.0)); + Update(); +} + +void LogViewer::ScrollDown(int lines) +{ + scrollbar->SetPosition(std::min(scrollbar->GetPosition() + (double)lines, scrollbar->GetMax())); + Update(); +} diff --git a/src/common/widgets/errorwindow.h b/src/common/widgets/errorwindow.h index 5f2ecf069f..63304b33f1 100644 --- a/src/common/widgets/errorwindow.h +++ b/src/common/widgets/errorwindow.h @@ -5,6 +5,7 @@ class LogViewer; class PushButton; +class Scrollbar; class ErrorWindow : public Widget { @@ -42,10 +43,19 @@ public: protected: void OnPaintFrame(Canvas* canvas) override; void OnPaint(Canvas* canvas) override; + void OnMouseWheel(const Point& pos, EInputKey key) override; + void OnKeyDown(EInputKey key) override; + void OnGeometryChanged() override; private: + void OnScrollbarScroll(); + void ScrollUp(int lines); + void ScrollDown(int lines); + SpanLayout CreateLineLayout(const std::string& text); + Scrollbar* scrollbar = nullptr; + std::shared_ptr largefont = Font::Create("Poppins", 16.0); std::shared_ptr font = Font::Create("Poppins", 12.0); std::vector lines;