Đến nội dung

Giao diện native ​

Một cửa sổ có thể hiển thị frontend mà myzig tự vẽ thay vì một trang web. Bạn viết nó trong Zig chỉ với myzig.ui: không có HTML, không có JavaScript và không có bản dựng frontend, đồng thời cửa sổ không bắt đầu webview, vì vậy, nó mở ngay lập tức và sử dụng ít bộ nhớ. myzig vẽ nó trên GPU nếu có thể, với Metal trên macOS, Direct3D 11 trên Windows, OpenGL trên Linux và WebGL 2 trong trình duyệt và với bộ kết xuất CPU riêng (cùng pixel) ở mọi nơi khác; xem kết xuất.

Gallery đang chạy với giao diện sáng: nút bấm, công tắc, thanh trượt và ô nhập văn bản.

Gallery đang chạy với giao diện sáng: nút bấm, công tắc, thanh trượt và ô nhập văn bản.

Ảnh trong các hướng dẫn được render từ view Zig đang chạy bằng ui.Tester, ở tỉ lệ 2×. Phần lớn dùng lại ví dụ Gallery; ảnh bố cục, grid, hướng đọc và shader dùng các ví dụ nhỏ riêng. Xem cách tạo lại ảnh.

zig
const std = @import("std");
const myzig = @import("myzig");
const ui = myzig.ui;

/// The app's state.
const Counter = struct {
    n: i64 = 0,

    /// Builds the window's interface from the state, for every frame.
    fn view(s: *Counter, c: *ui.Context) void {
        ui.column(c, .{ .width = .fill, .height = .fill, .align_items = .center, .justify = .center, .gap = 12 });
        defer ui.end(c);
        ui.textf(c, .{ .size = 40, .weight = .bold }, "{d}", .{s.n});
        if (ui.button(c, "Increment", .{ .variant = .primary }).clicked) s.n += 1;
    }
};

pub fn main(init: std.process.Init) !void {
    const app = try myzig.App.create(init, .{ .name = "Counter" });
    defer app.destroy();
    var state: Counter = .{};
    _ = try app.newWindow(.{
        .title = "Counter",
        .width = 420,
        .height = 300,
        .content = .{ .view = .init(&state, Counter.view) },
    });
    try app.run();
}

View là hàm của state, được myzig chạy trên main thread khi có input, thay đổi kích thước hoặc một bước hoạt ảnh. Widget trả lời ngay trong lượt dựng view: ui.button cho biết có được nhấp hay không, ui.toggle đổi giá trị bool được truyền vào. Bạn cập nhật state và frame tiếp theo hiển thị nó. Nếu tương tác làm đổi state, myzig dựng lại frame trước khi vẽ để hình hiển thị theo kịp state.

Phần tử cần nhận scroll hoặc pinch trước lượt dựng kế tiếp có thể dùng callback handleInput.

Không có polling nào. Một khung được vẽ khi nhập, khi thay đổi kích thước, trong khi hoạt ảnh chạy hoặc khi ứng dụng yêu cầu (Window.redraw, c.frameIn); một cửa sổ nhàn rỗi không sử dụng CPU.

Khung hình giữ lại những gì bạn vượt qua ​

Một khung được xây dựng, sau đó bố trí, rồi vẽ: bố cục và vẽ chạy sau khi view đã quay trở lại. Văn bản được sao chép vào bộ nhớ của khung khi chúng được hiển thị (ui.text, ui.richText và các khoảng, nhãn, chú giải công cụ, trường của nó, những gì c.describe cho biết công nghệ hỗ trợ), do đó, một view có thể giải phóng hoặc thay đổi một chuỗi ngay sau khi hiển thị nó. Các slice và con trỏ khác mà widget lấy (byte của ảnh, tên biểu tượng, độ dốc, điểm của khung vẽ) được đọc ở vị trí của chúng cho đến khi khung được vẽ: truyền hằng số, bộ nhớ riêng của ứng dụng hoặc định dạng của khung (c.print("{d} left", .{n}) vào một arena được giải phóng khi khung tiếp theo bắt đầu, c.alloc() cung cấp arena đó cho bất kỳ thứ gì khác), không bao giờ là bộ đệm trên ngăn xếp của chức năng xem. Để giải phóng dữ liệu như vậy mà view hiển thị, hãy giải phóng dữ liệu đó sau khung (sự kiện tiếp theo hoặc khung sau) hoặc giữ bản sao cũ để cập nhật thêm một lần nữa.

Hai cách để viết hộp ​

Các hàm đơn giản có cấu trúc ui.Style, theo cách của CSS flexbox:

zig
ui.row(c, .{ .gap = 8, .padding = .all(12), .background = c.theme.surface, .radius = 8 });
defer ui.end(c);

ui.div tạo kiểu cho cùng một hộp bằng một chuỗi các phương thức nhỏ, như GPUI thực hiện:

zig
const card = ui.div(c).row().p(12).gap(8).bg(c.theme.surface).rounded(8).hover(c.theme.surface_hover);
defer card.end();
if (card.clicked()) s.open = !s.open;

Cả hai đều làm những chiếc hộp giống nhau; trộn chúng một cách tự do. Xem bố cục và kiểu dáng.

Chạy nó mà không có cửa sổ ​

Mọi view đều có thể được điều khiển trong kiểm thử với ui.Tester, xây dựng và vẽ khung ngoài màn hình, nhấp chuột, nhập và chụp ảnh màn hình, trên đồng hồ mà bạn tự nâng cao:

zig
var t: ui.Tester = undefined;
try t.init(std.testing.allocator, .init(&state, Counter.view), .{});
defer t.deinit();
try t.clickText("Increment");
try std.testing.expect(t.hasText("1"));

Xem thử nghiệm.

Các hướng dẫn viên ​

Nền tảng:

  • Lượt xem: chức năng xem, ui.View, ngữ cảnh, id và khóa, trạng thái thay đổi từ bên ngoài, khung theo yêu cầu.
  • Bố cục: hàng, cột, kích thước, tăng trưởng, căn chỉnh, đệm, cuộn, hộp tuyệt đối, cắt bớt.
  • Tạo kiểu: màu sắc, đường viền, bóng, chủ đề, sáng và tối, chủ đề được đặt tên, điểm nhấn, tùy chọn của màn hình, Oklch.
  • Văn bản: kiểu văn bản, ngắt dòng, khoảng phong phú, tiêu đề và nhãn, phông chữ, văn bản có thể chọn, thu phóng.

Widget:

  • Nút và những thứ nhỏ nhặt: nút, liên kết, huy hiệu, mũ phím, biểu tượng, hình ảnh, hình đại diện, nút lịch sử.
  • Lựa chọn: hộp kiểm, nhóm hộp kiểm, công tắc, nút radio, nhóm radio, điều khiển phân đoạn, xếp hạng.
  • Phạm vi: thanh trượt, thanh trượt phạm vi, bước, đầu vào số, mét, thanh tiến trình, vòng quay.
  • Nhập văn bản: trường văn bản, trường tìm kiếm, trường mã thông báo, hộp tổ hợp, tự động hoàn thành, phương thức nhập và thao tác văn bản.
  • Ngày và màu: lịch, đầu vào ngày và giờ, bộ chọn màu và giếng.
  • Biểu mẫu: trường được gắn nhãn, biểu mẫu, tập hợp trường, xác thực.
  • Lớp phủ: cửa sổ bật lên, chú giải công cụ, hộp thoại, hộp thoại cảnh báo, chúc mừng.
  • Menus: menu, menu ngữ cảnh, nút menu, lựa chọn.
  • Item: hàng nội dung có icon/avatar, mô tả và nút thao tác.
  • Input Group: ô nhập có icon, tiền tố/hậu tố và nút.
  • Pagination: phân trang với tổng đã biết hoặc chưa biết.
  • Empty, Skeleton và Alert: nội dung trống, đang tải và thông báo trong trang.
  • Command Palette: tìm và kích hoạt lệnh bằng bàn phím.
  • Sheet: panel modal ở các cạnh cửa sổ.
  • Nh?m n?t v? n?t b?t/t?t
  • Ch?n nhi?u m?c
  • Ch?n kho?ng ng?y
  • Gh?p b?ng d? li?u
  • V?ng th? file
  • Cấu trúc: tab, thành phần thu gọn, accordion, phần tách, thanh bên, thanh công cụ, đường dẫn.
  • Danh sách, cây và bảng: danh sách ảo, cây, đường viền, bảng, view lưới.
  • Bố cục lưới: lưới kiểu CSS gồm các rãnh và ô.
  • Điều hướng: bộ định tuyến, hành động và lối tắt, nhóm tiêu điểm.
  • Kéo và thả: kéo trong và ngoài cửa sổ.
  • Tiện ích tùy chỉnh: hộp, tương tác, giá trị hoạt ảnh, tay cầm: cách tạo ra các widget riêng của myzig.
  • Cuộn và thu phóng: handler scroll/pinch, định tuyến sự kiện và test headless.
  • Chỉ báo loading: plugin tùy chọn với 29 mẫu, đồng hồ độc lập và cấu hình riêng.

Vẽ và nội dung phong phú:

  • Chuyển động: giá trị hoạt ảnh, lò xo, khung hình chính, dòng thời gian, chuyển tiếp, ít chuyển động hơn.
  • Biến đổi và hiệu ứng: di chuyển, chia tỷ lệ và xoay hộp, chuyển màu, làm mờ, hiệu ứng phông nền.
  • Bản vẽ: khung vẽ đường dẫn, phần tô màu và nét vẽ, SVG.
  • Biểu đồ: đường, thanh, vùng, v.v, phát trực tuyến.
  • Markdown: Các tiện ích mở rộng của CommonMark và GitHub, được phát trực tuyến khi nó xuất hiện.
  • Vùng văn bản: văn bản nhiều dòng, sợi dây, tài liệu.
  • Trình chỉnh sửa mã và trình xem khác biệt: tô sáng cú pháp, máng xối, khác biệt.
  • Văn bản có định dạng: trình soạn thảo văn bản có định dạng và thanh công cụ của nó.
  • Shaders: các shader được viết một lần, được vẽ bởi mọi bộ kết xuất.
  • View web: các trang web trong hộp giao diện native, với giao diện native được vẽ phía trên chúng.

Chất lượng:

Giao diện native cũng chạy trong trình duyệt, được xây dựng cho wasm32-wasi; xem trình duyệt.

Phát hành theo giấy phép MIT.