From 56ddcb9a2ecfc6d50587f4c6934e9a6051285b47 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 28 Jul 2025 20:50:51 +0200 Subject: [PATCH] Update to latest zwidget --- .../zwidget/widgets/listview/listview.h | 11 ++- .../ZWidget/include/zwidget/window/window.h | 1 - .../ZWidget/src/widgets/listview/listview.cpp | 95 ++++++++++++++++--- .../src/window/win32/win32_display_window.cpp | 3 +- .../src/window/x11/x11_display_window.cpp | 79 +++++++++------ .../src/window/x11/x11_display_window.h | 5 + 6 files changed, 148 insertions(+), 46 deletions(-) diff --git a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h index fc6a82391..433119759 100644 --- a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h +++ b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h @@ -12,8 +12,12 @@ class ListView : public Widget public: ListView(Widget* parent = nullptr); - void AddItem(const std::string& text); - void RemoveItem(int index); + void SetColumnWidths(const std::vector& widths); + void AddItem(const std::string& text, int index = -1, int column = 0); + void UpdateItem(const std::string& text, int index, int column = 0); + void RemoveItem(int index = -1); + size_t GetItemAmount() const { return items.size(); } + size_t GetColumnAmount() const { return columnwidths.size(); } int GetSelectedItem() const { return selectedItem; } void SetSelectedItem(int index); void ScrollToItem(int index); @@ -34,6 +38,7 @@ protected: Scrollbar* scrollbar = nullptr; - std::vector items; + std::vector> items; + std::vector columnwidths; int selectedItem = 0; }; diff --git a/libraries/ZWidget/include/zwidget/window/window.h b/libraries/ZWidget/include/zwidget/window/window.h index f5a8da734..ad59f1f02 100644 --- a/libraries/ZWidget/include/zwidget/window/window.h +++ b/libraries/ZWidget/include/zwidget/window/window.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/libraries/ZWidget/src/widgets/listview/listview.cpp b/libraries/ZWidget/src/widgets/listview/listview.cpp index 54f48552d..146d9bc23 100644 --- a/libraries/ZWidget/src/widgets/listview/listview.cpp +++ b/libraries/ZWidget/src/widgets/listview/listview.cpp @@ -8,25 +8,91 @@ ListView::ListView(Widget* parent) : Widget(parent) scrollbar = new Scrollbar(this); scrollbar->FuncScroll = [=]() { OnScrollbarScroll(); }; + + SetColumnWidths({ 0.0 }); } -void ListView::AddItem(const std::string& text) +void ListView::SetColumnWidths(const std::vector& widths) { - items.push_back(text); + columnwidths = widths; + + bool updated = false; + const size_t newWidth = columnwidths.size(); + for (std::vector& column : items) + { + while (column.size() < newWidth) + { + updated = true; + column.push_back(""); + } + while (column.size() > newWidth) + { + updated = true; + column.pop_back(); + } + } + + if (updated) + Update(); +} + +void ListView::AddItem(const std::string& text, int index, int column) +{ + if (column < 0 || column >= columnwidths.size()) + return; + + std::vector newEntry; + for (size_t i = 0u; i < columnwidths.size(); ++i) + newEntry.push_back(""); + + newEntry[column] = text; + if (index >= 0) + { + if (index >= items.size()) + { + newEntry[column] = ""; + while (items.size() < index) + items.push_back(newEntry); + + newEntry[column] = text; + items.push_back(newEntry); + } + else + { + items.insert(items.begin() + index, newEntry); + } + } + else + { + items.push_back(newEntry); + } + scrollbar->SetRanges(GetHeight(), items.size() * 20.0); + Update(); +} + +void ListView::UpdateItem(const std::string& text, int index, int column) +{ + if (index < 0 || index >= items.size() || column < 0 || column >= columnwidths.size()) + return; + + items[index][column] = text; Update(); } void ListView::RemoveItem(int index) { - if (index >= 0 && index < items.size()) - { - items.erase(items.begin() + index); - } + if (!items.size() || index >= items.size()) + return; - if (selectedItem == items.size()) - { - selectedItem = !items.empty() ? (int)items.size() - 1 : 0; - } + if (index < 0) + index = items.size() - 1; + + if (selectedItem == index) + SetSelectedItem(0); + + items.erase(items.begin() + index); + scrollbar->SetRanges(GetHeight(), items.size() * 20.0); + Update(); } void ListView::Activate() @@ -84,7 +150,7 @@ void ListView::OnPaint(Canvas* canvas) Colorf selectionColor = GetStyleColor("selection-color"); int index = 0; - for (const std::string& item : items) + for (const std::vector& item : items) { double itemY = y; if (itemY + h >= 0.0 && itemY < GetHeight()) @@ -93,7 +159,12 @@ void ListView::OnPaint(Canvas* canvas) { canvas->fillRect(Rect::xywh(x - 2.0, itemY, w, h), selectionColor); } - canvas->drawText(Point(x, y + 15.0), textColor, item); + double cx = x; + for (size_t entry = 0u; entry < item.size(); ++entry) + { + canvas->drawText(Point(cx, y + 15.0), textColor, item[entry]); + cx += columnwidths[entry]; + } } y += h; index++; diff --git a/libraries/ZWidget/src/window/win32/win32_display_window.cpp b/libraries/ZWidget/src/window/win32/win32_display_window.cpp index 9a5043a9a..f45da1a14 100644 --- a/libraries/ZWidget/src/window/win32/win32_display_window.cpp +++ b/libraries/ZWidget/src/window/win32/win32_display_window.cpp @@ -384,8 +384,7 @@ void Win32DisplayWindow::PresentBitmap(int width, int height, const uint32_t* pi HDC dc = PaintDC; if (dc != 0) { - int result = SetDIBitsToDevice(dc, 0, 0, width, height, 0, 0, 0, height, pixels, (const BITMAPINFO*)&header, BI_RGB); - ReleaseDC(WindowHandle.hwnd, dc); + SetDIBitsToDevice(dc, 0, 0, width, height, 0, 0, 0, height, pixels, (const BITMAPINFO*)&header, BI_RGB); } } diff --git a/libraries/ZWidget/src/window/x11/x11_display_window.cpp b/libraries/ZWidget/src/window/x11/x11_display_window.cpp index cd3fe2734..5797b0b4f 100644 --- a/libraries/ZWidget/src/window/x11/x11_display_window.cpp +++ b/libraries/ZWidget/src/window/x11/x11_display_window.cpp @@ -285,18 +285,22 @@ void X11DisplayWindow::ShowCursor(bool enable) void X11DisplayWindow::LockCursor() { + ShowCursor(false); } void X11DisplayWindow::UnlockCursor() { + ShowCursor(true); } void X11DisplayWindow::CaptureMouse() { + ShowCursor(false); } void X11DisplayWindow::ReleaseMouseCapture() { + ShowCursor(true); } void X11DisplayWindow::Update() @@ -692,6 +696,8 @@ void X11DisplayWindow::OnEvent(XEvent* event) void X11DisplayWindow::OnConfigureNotify(XEvent* event) { + ClientSizeX = event->xconfigure.width; + ClientSizeY = event->xconfigure.height; windowHost->OnWindowGeometryChanged(); } @@ -766,7 +772,7 @@ InputKey X11DisplayWindow::GetInputKey(XEvent* event) case XK_Left: return InputKey::Left; case XK_Up: return InputKey::Up; case XK_Right: return InputKey::Right; - case XK_Down: return InputKey::Select; + case XK_Down: return InputKey::Down; case XK_Print: return InputKey::Print; case XK_Execute: return InputKey::Execute; // case XK_Print_Screen: return InputKey::PrintScrn; @@ -783,32 +789,32 @@ InputKey X11DisplayWindow::GetInputKey(XEvent* event) case XK_7: return InputKey::_7; case XK_8: return InputKey::_8; case XK_9: return InputKey::_9; - case XK_A: return InputKey::A; - case XK_B: return InputKey::B; - case XK_C: return InputKey::C; - case XK_D: return InputKey::D; - case XK_E: return InputKey::E; - case XK_F: return InputKey::F; - case XK_G: return InputKey::G; - case XK_H: return InputKey::H; - case XK_I: return InputKey::I; - case XK_J: return InputKey::J; - case XK_K: return InputKey::K; - case XK_L: return InputKey::L; - case XK_M: return InputKey::M; - case XK_N: return InputKey::N; - case XK_O: return InputKey::O; - case XK_P: return InputKey::P; - case XK_Q: return InputKey::Q; - case XK_R: return InputKey::R; - case XK_S: return InputKey::S; - case XK_T: return InputKey::T; - case XK_U: return InputKey::U; - case XK_V: return InputKey::V; - case XK_W: return InputKey::W; - case XK_X: return InputKey::X; - case XK_Y: return InputKey::Y; - case XK_Z: return InputKey::Z; + case XK_A: case XK_a: return InputKey::A; + case XK_B: case XK_b: return InputKey::B; + case XK_C: case XK_c: return InputKey::C; + case XK_D: case XK_d: return InputKey::D; + case XK_E: case XK_e: return InputKey::E; + case XK_F: case XK_f: return InputKey::F; + case XK_G: case XK_g: return InputKey::G; + case XK_H: case XK_h: return InputKey::H; + case XK_I: case XK_i: return InputKey::I; + case XK_J: case XK_j: return InputKey::J; + case XK_K: case XK_k: return InputKey::K; + case XK_L: case XK_l: return InputKey::L; + case XK_M: case XK_m: return InputKey::M; + case XK_N: case XK_n: return InputKey::N; + case XK_O: case XK_o: return InputKey::O; + case XK_P: case XK_p: return InputKey::P; + case XK_Q: case XK_q: return InputKey::Q; + case XK_R: case XK_r: return InputKey::R; + case XK_S: case XK_s: return InputKey::S; + case XK_T: case XK_t: return InputKey::T; + case XK_U: case XK_u: return InputKey::U; + case XK_V: case XK_v: return InputKey::V; + case XK_W: case XK_w: return InputKey::W; + case XK_X: case XK_x: return InputKey::X; + case XK_Y: case XK_y: return InputKey::Y; + case XK_Z: case XK_z: return InputKey::Z; case XK_KP_0: return InputKey::NumPad0; case XK_KP_1: return InputKey::NumPad1; case XK_KP_2: return InputKey::NumPad2; @@ -962,7 +968,24 @@ void X11DisplayWindow::OnMotionNotify(XEvent* event) double dpiScale = GetDpiScale(); int x = event->xmotion.x; int y = event->xmotion.y; - windowHost->OnWindowMouseMove(Point(x / dpiScale, y / dpiScale)); + if (isCursorEnabled) + { + windowHost->OnWindowMouseMove(Point(x / dpiScale, y / dpiScale)); + } + else + { + MouseX = ClientSizeX / 2; + MouseY = ClientSizeY / 2; + + if (MouseX != -1 && MouseY != -1) + { + windowHost->OnWindowRawMouseMove(x - MouseX, y - MouseY); + } + + // Warp pointer to the center of the window + XWarpPointer(display, window, window, 0, 0, ClientSizeX, ClientSizeY, ClientSizeX / 2, ClientSizeY / 2); + } + } void X11DisplayWindow::OnLeaveNotify(XEvent* event) diff --git a/libraries/ZWidget/src/window/x11/x11_display_window.h b/libraries/ZWidget/src/window/x11/x11_display_window.h index bd65d8d1c..62a63f151 100644 --- a/libraries/ZWidget/src/window/x11/x11_display_window.h +++ b/libraries/ZWidget/src/window/x11/x11_display_window.h @@ -115,6 +115,11 @@ private: bool isFullscreen = false; double dpiScale = 1.0; + int ClientSizeX = 0; + int ClientSizeY = 0; + int MouseX = -1; + int MouseY = -1; + Pixmap cursor_bitmap = None; Cursor hidden_cursor = None;