Update to latest zwidget

This commit is contained in:
Magnus Norddahl 2025-07-28 20:50:51 +02:00
commit 56ddcb9a2e
6 changed files with 147 additions and 45 deletions

View file

@ -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<double>& 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<std::string> items;
std::vector<std::vector<std::string>> items;
std::vector<double> columnwidths;
int selectedItem = 0;
};

View file

@ -1,6 +1,5 @@
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <functional>

View file

@ -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<double>& widths)
{
items.push_back(text);
columnwidths = widths;
bool updated = false;
const size_t newWidth = columnwidths.size();
for (std::vector<std::string>& 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<std::string> 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<std::string>& 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++;

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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;