Compare commits
9 Commits
2e2c140d5b
...
7145b66e0e
| Author | SHA1 | Date | |
|---|---|---|---|
| 7145b66e0e | |||
|
|
d6c8a062cd | ||
|
|
045624beac | ||
|
|
b0259c5788 | ||
|
|
0a47ea1e43 | ||
|
|
cc10d806fe | ||
|
|
e3a4506194 | ||
|
|
3348b2e91c | ||
|
|
9ca360c6b3 |
@@ -8,8 +8,8 @@ pub fn build(b: *std.Build) void {
|
|||||||
|
|
||||||
const exe = b.addExecutable(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = "Zivro",
|
.name = "Zivro",
|
||||||
.use_llvm = true,
|
// .use_llvm = true,
|
||||||
.use_lld = true,
|
// .use_lld = true,
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
|
|||||||
@@ -33,8 +33,8 @@
|
|||||||
// internet connectivity.
|
// internet connectivity.
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.dvui = .{
|
.dvui = .{
|
||||||
.url = "https://github.com/david-vanderson/dvui/archive/main.tar.gz",
|
.url = "git+https://github.com/david-vanderson/dvui#edb2d5a4cd2981fca74ee5f096277b91333c1316",
|
||||||
.hash = "dvui-0.4.0-dev-AQFJmev72QC6e0ojhnW8a_wRhZDgzWWLgeyoNuIPZc2m",
|
.hash = "dvui-0.4.0-dev-AQFJmeGB3QAwun9qF76CDE5IopA4nUVRgD-IwwTsOo4H",
|
||||||
},
|
},
|
||||||
|
|
||||||
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
|
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
|
||||||
|
|||||||
0
review.txt
Normal file
0
review.txt
Normal file
@@ -16,15 +16,10 @@ pub const OpenDocument = struct {
|
|||||||
selected_object_id: ?u64 = null,
|
selected_object_id: ?u64 = null,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, self: *OpenDocument) void {
|
pub fn init(allocator: std.mem.Allocator, self: *OpenDocument) void {
|
||||||
const default_size = basic_models.Size_f{ .w = 800, .h = 600 };
|
initWithDocument(allocator, self, .init(.{
|
||||||
self.document = Document.init(default_size);
|
.w = 800,
|
||||||
self.cpu_render = CpuRenderEngine.init(allocator, .Squares);
|
.h = 600,
|
||||||
self.canvas = Canvas.init(
|
}));
|
||||||
allocator,
|
|
||||||
&self.document,
|
|
||||||
(&self.cpu_render).renderEngine(),
|
|
||||||
);
|
|
||||||
self.selected_object_id = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initWithDocument(allocator: std.mem.Allocator, self: *OpenDocument, doc: Document) void {
|
pub fn initWithDocument(allocator: std.mem.Allocator, self: *OpenDocument, doc: Document) void {
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ const WindowContext = @import("WindowContext.zig");
|
|||||||
const ui = @import("ui/frame.zig");
|
const ui = @import("ui/frame.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
// std.heap.GeneralPurposeAllocator was renamed to DebugAllocator recently.
|
||||||
|
var gpa: std.heap.DebugAllocator(.{}) = .init;
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
var backend = try SDLBackend.initWindow(.{
|
var backend = try SDLBackend.initWindow(.{
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ shape: ShapeKind,
|
|||||||
properties: std.ArrayList(Property),
|
properties: std.ArrayList(Property),
|
||||||
children: std.ArrayList(Object),
|
children: std.ArrayList(Object),
|
||||||
|
|
||||||
pub fn getProperty(self: Object, tag: std.meta.Tag(PropertyData)) ?*const PropertyData {
|
pub fn getProperty(self: Object, comptime tag: std.meta.Tag(PropertyData)) ?@FieldType(PropertyData, @tagName(tag)) {
|
||||||
for (self.properties.items) |*prop| {
|
for (self.properties.items) |*prop| {
|
||||||
if (std.meta.activeTag(prop.data) == tag) return &prop.data;
|
if (std.meta.activeTag(prop.data) == tag) return @field(prop.data, @tagName(tag));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ pub const Property = struct {
|
|||||||
.points => |slice| .{
|
.points => |slice| .{
|
||||||
.data = .{
|
.data = .{
|
||||||
.points = blk: {
|
.points = blk: {
|
||||||
const copy = try allocator.alloc(Point2_f, slice.len);
|
const copy = try allocator.dupe(Point2_f, slice);
|
||||||
@memcpy(copy, slice);
|
|
||||||
break :blk copy;
|
break :blk copy;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ fn appendShapeProperties(allocator: std.mem.Allocator, obj: *Object, props: []co
|
|||||||
for (props) |prop| {
|
for (props) |prop| {
|
||||||
if (prop.data == .points) {
|
if (prop.data == .points) {
|
||||||
const pts = prop.data.points;
|
const pts = prop.data.points;
|
||||||
const copy = try allocator.alloc(Point2_f, pts.len);
|
const copy = try allocator.dupe(Point2_f, pts);
|
||||||
@memcpy(copy, pts);
|
|
||||||
try obj.properties.append(allocator, .{ .data = .{ .points = copy } });
|
try obj.properties.append(allocator, .{ .data = .{ .points = copy } });
|
||||||
} else {
|
} else {
|
||||||
try obj.properties.append(allocator, prop);
|
try obj.properties.append(allocator, prop);
|
||||||
@@ -33,7 +32,7 @@ pub fn createObject(allocator: std.mem.Allocator, shape_kind: Object.ShapeKind)
|
|||||||
.ellipse => try appendShapeProperties(allocator, &obj, &ellipse.default_shape_properties),
|
.ellipse => try appendShapeProperties(allocator, &obj, &ellipse.default_shape_properties),
|
||||||
.broken => {
|
.broken => {
|
||||||
try appendShapeProperties(allocator, &obj, &broken.default_shape_properties);
|
try appendShapeProperties(allocator, &obj, &broken.default_shape_properties);
|
||||||
try obj.setProperty(allocator, .{ .data = .{ .fill_rgba = obj.getProperty(.stroke_rgba).?.stroke_rgba } });
|
try obj.setProperty(allocator, .{ .data = .{ .fill_rgba = obj.getProperty(.stroke_rgba).? } });
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ fn randomizeObjectProperties(allocator: std.mem.Allocator, doc_size: *const Size
|
|||||||
x += randFloat(rng, -40, 80);
|
x += randFloat(rng, -40, 80);
|
||||||
y += randFloat(rng, -30, 60);
|
y += randFloat(rng, -30, 60);
|
||||||
}
|
}
|
||||||
const slice = try allocator.alloc(Point2_f, list.items.len);
|
const slice = try allocator.dupe(Point2_f, list.items);
|
||||||
@memcpy(slice, list.items);
|
errdefer allocator.free(slice);
|
||||||
try obj.setProperty(allocator, .{ .data = .{ .points = slice } });
|
try obj.setProperty(allocator, .{ .data = .{ .points = slice } });
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -100,6 +100,7 @@ pub fn addRandomShapes(doc: *Document, allocator: std.mem.Allocator, rng: std.Ra
|
|||||||
for (0..n_root) |_| {
|
for (0..n_root) |_| {
|
||||||
if (total_count >= max_total) break;
|
if (total_count >= max_total) break;
|
||||||
var obj = try shape.createObject(allocator, randomShapeKind(rng));
|
var obj = try shape.createObject(allocator, randomShapeKind(rng));
|
||||||
|
defer obj.deinit(allocator);
|
||||||
try randomizeObjectProperties(allocator, &doc.size, &obj, rng);
|
try randomizeObjectProperties(allocator, &doc.size, &obj, rng);
|
||||||
try doc.addObject(allocator, obj);
|
try doc.addObject(allocator, obj);
|
||||||
total_count += 1;
|
total_count += 1;
|
||||||
@@ -117,6 +118,7 @@ pub fn addRandomShapes(doc: *Document, allocator: std.mem.Allocator, rng: std.Ra
|
|||||||
for (0..n_children) |_| {
|
for (0..n_children) |_| {
|
||||||
if (total_count >= max_total) break;
|
if (total_count >= max_total) break;
|
||||||
var child = try shape.createObject(allocator, randomShapeKind(rng));
|
var child = try shape.createObject(allocator, randomShapeKind(rng));
|
||||||
|
defer child.deinit(allocator);
|
||||||
try randomizeObjectProperties(allocator, &doc.size, &child, rng);
|
try randomizeObjectProperties(allocator, &doc.size, &child, rng);
|
||||||
try obj.addChild(allocator, child, &doc.next_object_id);
|
try obj.addChild(allocator, child, &doc.next_object_id);
|
||||||
total_count += 1;
|
total_count += 1;
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ fn renderGradient(self: CpuRenderEngine, pixels: []Color.PMA, width: u32, height
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderSquares(self: CpuRenderEngine, pixels: []Color.PMA, canvas_size: Size_i, visible_rect: Rect_i) void {
|
fn renderSquares(pixels: []Color.PMA, canvas_size: Size_i, visible_rect: Rect_i) void {
|
||||||
_ = self;
|
|
||||||
|
|
||||||
const colors = [_]Color.PMA{
|
const colors = [_]Color.PMA{
|
||||||
.{ .r = 255, .g = 0, .b = 0, .a = 255 },
|
.{ .r = 255, .g = 0, .b = 0, .a = 255 },
|
||||||
.{ .r = 255, .g = 165, .b = 0, .a = 255 },
|
.{ .r = 255, .g = 165, .b = 0, .a = 255 },
|
||||||
@@ -169,10 +167,10 @@ pub fn example(self: CpuRenderEngine, canvas_size: Size_i, visible_rect: Rect_i)
|
|||||||
|
|
||||||
switch (self.type) {
|
switch (self.type) {
|
||||||
.Gradient => self.renderGradient(pixels, width, height, full_w, full_h, visible_rect),
|
.Gradient => self.renderGradient(pixels, width, height, full_w, full_h, visible_rect),
|
||||||
.Squares => self.renderSquares(pixels, canvas_size, visible_rect),
|
.Squares => renderSquares(pixels, canvas_size, visible_rect),
|
||||||
}
|
}
|
||||||
|
|
||||||
return try dvui.textureCreate(pixels, width, height, .nearest);
|
return try dvui.textureCreate(pixels, width, height, .nearest, .rgba_8_8_8_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn renderEngine(self: *CpuRenderEngine) RenderEngine {
|
pub fn renderEngine(self: *CpuRenderEngine) RenderEngine {
|
||||||
@@ -191,7 +189,7 @@ pub fn renderDocument(self: *CpuRenderEngine, document: *const Document, canvas_
|
|||||||
try cpu_draw.drawDocument(pixels, width, height, visible_rect, document, canvas_size, self._allocator);
|
try cpu_draw.drawDocument(pixels, width, height, visible_rect, document, canvas_size, self._allocator);
|
||||||
self._renderStats.render_time_ns = t.read();
|
self._renderStats.render_time_ns = t.read();
|
||||||
|
|
||||||
return try dvui.textureCreate(pixels, width, height, .nearest);
|
return try dvui.textureCreate(pixels, width, height, .nearest, .rgba_8_8_8_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getStats(self: CpuRenderEngine) RenderStats {
|
pub fn getStats(self: CpuRenderEngine) RenderStats {
|
||||||
|
|||||||
@@ -16,14 +16,13 @@ pub fn draw(
|
|||||||
obj: *const Object,
|
obj: *const Object,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
) !void {
|
) !void {
|
||||||
const p_prop = obj.getProperty(.points) orelse return;
|
const pts = obj.getProperty(.points) orelse return;
|
||||||
const pts = p_prop.points;
|
|
||||||
if (pts.len < 2) return;
|
if (pts.len < 2) return;
|
||||||
const stroke = if (obj.getProperty(.stroke_rgba)) |s| pipeline.rgbaToPma(s.stroke_rgba) else default_stroke;
|
const stroke = if (obj.getProperty(.stroke_rgba)) |stroke_rgba| pipeline.rgbaToPma(stroke_rgba) else default_stroke;
|
||||||
const thickness = if (obj.getProperty(.thickness)) |t| t.thickness else default_thickness;
|
const thickness = obj.getProperty(.thickness) orelse default_thickness;
|
||||||
const closed = if (obj.getProperty(.closed)) |c| c.closed else false;
|
const closed = obj.getProperty(.closed) orelse false;
|
||||||
const filled = if (obj.getProperty(.filled)) |f| f.filled else true;
|
const filled = obj.getProperty(.filled) orelse true;
|
||||||
const fill_color = if (obj.getProperty(.fill_rgba)) |f| pipeline.rgbaToPma(f.fill_rgba) else default_fill;
|
const fill_color = if (obj.getProperty(.fill_rgba)) |fill_rgba| pipeline.rgbaToPma(fill_rgba) else default_fill;
|
||||||
|
|
||||||
const buffer = try allocator.alloc(Color.PMA, ctx.buf_width * ctx.buf_height);
|
const buffer = try allocator.alloc(Color.PMA, ctx.buf_width * ctx.buf_height);
|
||||||
@memset(buffer, .{ .r = 0, .g = 0, .b = 0, .a = 0 });
|
@memset(buffer, .{ .r = 0, .g = 0, .b = 0, .a = 0 });
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const DrawContext = pipeline.DrawContext;
|
|||||||
const Transform = pipeline.Transform;
|
const Transform = pipeline.Transform;
|
||||||
|
|
||||||
fn isVisible(obj: *const Object) bool {
|
fn isVisible(obj: *const Object) bool {
|
||||||
return if (obj.getProperty(.visible)) |p| p.visible else true;
|
return obj.getProperty(.visible) orelse true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drawObject(
|
fn drawObject(
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ const default_thickness: f32 = 2.0;
|
|||||||
/// arc_percent: 100 — полный эллипс, иначе одна дуга; обход в коде от (0,ry) по квадрантам (визуально может казаться от низа против часовой из‑за экранной Y).
|
/// arc_percent: 100 — полный эллипс, иначе одна дуга; обход в коде от (0,ry) по квадрантам (визуально может казаться от низа против часовой из‑за экранной Y).
|
||||||
/// Отрисовка в отдельный буфер и один composite, чтобы при alpha<255 пиксели не накладывались несколько раз.
|
/// Отрисовка в отдельный буфер и один composite, чтобы при alpha<255 пиксели не накладывались несколько раз.
|
||||||
pub fn draw(ctx: *DrawContext, obj: *const Object, allocator: std.mem.Allocator) !void {
|
pub fn draw(ctx: *DrawContext, obj: *const Object, allocator: std.mem.Allocator) !void {
|
||||||
const r_prop = obj.getProperty(.radii) orelse return;
|
const radii = obj.getProperty(.radii) orelse return;
|
||||||
const rx = r_prop.radii.x;
|
const rx = radii.x;
|
||||||
const ry = r_prop.radii.y;
|
const ry = radii.y;
|
||||||
if (rx <= 0 or ry <= 0) return;
|
if (rx <= 0 or ry <= 0) return;
|
||||||
|
|
||||||
const stroke = if (obj.getProperty(.stroke_rgba)) |s| pipeline.rgbaToPma(s.stroke_rgba) else default_stroke;
|
const stroke = if (obj.getProperty(.stroke_rgba)) |stroke_rgba| pipeline.rgbaToPma(stroke_rgba) else default_stroke;
|
||||||
const thickness = if (obj.getProperty(.thickness)) |t| t.thickness else default_thickness;
|
const thickness = if (obj.getProperty(.thickness)) |thickness| thickness else default_thickness;
|
||||||
const arc_percent = std_math.clamp(if (obj.getProperty(.arc_percent)) |p| p.arc_percent else 100.0, 0.0, 100.0);
|
const arc_percent = std_math.clamp(if (obj.getProperty(.arc_percent)) |arc_percent| arc_percent else 100.0, 0.0, 100.0);
|
||||||
const closed = if (obj.getProperty(.closed)) |c| c.closed else true;
|
const closed = obj.getProperty(.closed) orelse true;
|
||||||
const filled = if (obj.getProperty(.filled)) |f| f.filled else false;
|
const filled = obj.getProperty(.filled) orelse false;
|
||||||
const fill_color = if (obj.getProperty(.fill_rgba)) |f| pipeline.rgbaToPma(f.fill_rgba) else default_fill;
|
const fill_color = if (obj.getProperty(.fill_rgba)) |fill_rgba| pipeline.rgbaToPma(fill_rgba) else default_fill;
|
||||||
const do_fill = filled and (closed or arc_percent >= 100.0);
|
const do_fill = filled and (closed or arc_percent >= 100.0);
|
||||||
|
|
||||||
const t = &ctx.transform;
|
const t = &ctx.transform;
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ const default_thickness: f32 = 2.0;
|
|||||||
|
|
||||||
/// Линия от (0,0) до end_point.
|
/// Линия от (0,0) до end_point.
|
||||||
pub fn draw(ctx: *DrawContext, obj: *const Object) void {
|
pub fn draw(ctx: *DrawContext, obj: *const Object) void {
|
||||||
const ep_prop = obj.getProperty(.end_point) orelse return;
|
const end_point = obj.getProperty(.end_point) orelse return;
|
||||||
const end_x = ep_prop.end_point.x;
|
const end_x = end_point.x;
|
||||||
const end_y = ep_prop.end_point.y;
|
const end_y = end_point.y;
|
||||||
const stroke = if (obj.getProperty(.stroke_rgba)) |s| pipeline.rgbaToPma(s.stroke_rgba) else default_stroke;
|
const stroke = if (obj.getProperty(.stroke_rgba)) |stroke_rgba| pipeline.rgbaToPma(stroke_rgba) else default_stroke;
|
||||||
const thickness = if (obj.getProperty(.thickness)) |t| t.thickness else default_thickness;
|
const thickness = obj.getProperty(.thickness) orelse default_thickness;
|
||||||
drawLine(ctx, 0, 0, end_x, end_y, stroke, thickness, false);
|
drawLine(ctx, 0, 0, end_x, end_y, stroke, thickness, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ pub const Transform = struct {
|
|||||||
opacity: f32 = 1.0,
|
opacity: f32 = 1.0,
|
||||||
|
|
||||||
pub fn init(obj: *const Document.Object) Transform {
|
pub fn init(obj: *const Document.Object) Transform {
|
||||||
const pos = if (obj.getProperty(.position)) |p| p.position else Point2_f{ .x = 0, .y = 0 };
|
const pos = obj.getProperty(.position) orelse Point2_f{ .x = 0, .y = 0 };
|
||||||
const angle = if (obj.getProperty(.angle)) |p| p.angle else 0;
|
const angle = obj.getProperty(.angle) orelse 0;
|
||||||
const scale = if (obj.getProperty(.scale)) |p| p.scale else Scale2_f{ .scale_x = 1, .scale_y = 1 };
|
const scale = obj.getProperty(.scale) orelse Scale2_f{ .scale_x = 1, .scale_y = 1 };
|
||||||
const opacity = if (obj.getProperty(.opacity)) |p| p.opacity else 1.0;
|
const opacity = obj.getProperty(.opacity) orelse 1.0;
|
||||||
return .{
|
return .{
|
||||||
.position = pos,
|
.position = pos,
|
||||||
.angle = angle,
|
.angle = angle,
|
||||||
@@ -273,7 +273,7 @@ const FillCanvas = struct {
|
|||||||
}.lessThan);
|
}.lessThan);
|
||||||
|
|
||||||
// Семена: по строкам находим сегменты (пары x), пересекаем с окном буфера, берём середину сегмента.
|
// Семена: по строкам находим сегменты (пары x), пересекаем с окном буфера, берём середину сегмента.
|
||||||
var seeds = findFillSeeds(self, keys_buf.items, buf_w_i, buf_h_i, allocator) catch return;
|
var seeds = findFillSeeds(keys_buf.items, buf_w_i, buf_h_i, allocator) catch return;
|
||||||
defer seeds.deinit(allocator);
|
defer seeds.deinit(allocator);
|
||||||
|
|
||||||
var stack = std.ArrayList(Point2_i).empty;
|
var stack = std.ArrayList(Point2_i).empty;
|
||||||
@@ -304,13 +304,11 @@ const FillCanvas = struct {
|
|||||||
|
|
||||||
/// По строкам: рёбра (подряд идущие x) → сегменты между ними. Семена — середины чётных сегментов (при чётном числе границ).
|
/// По строкам: рёбра (подряд идущие x) → сегменты между ними. Семена — середины чётных сегментов (при чётном числе границ).
|
||||||
fn findFillSeeds(
|
fn findFillSeeds(
|
||||||
self: *const FillCanvas,
|
|
||||||
keys: []const Point2_i,
|
keys: []const Point2_i,
|
||||||
buf_w_i: i32,
|
buf_w_i: i32,
|
||||||
buf_h_i: i32,
|
buf_h_i: i32,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
) !std.ArrayList(Point2_i) {
|
) !std.ArrayList(Point2_i) {
|
||||||
_ = self;
|
|
||||||
var list = std.ArrayList(Point2_i).empty;
|
var list = std.ArrayList(Point2_i).empty;
|
||||||
errdefer list.deinit(allocator);
|
errdefer list.deinit(allocator);
|
||||||
var segments = std.ArrayList(struct { left: i32, right: i32 }).empty;
|
var segments = std.ArrayList(struct { left: i32, right: i32 }).empty;
|
||||||
|
|||||||
@@ -17,14 +17,15 @@ pub fn canvasView(canvas: *Canvas, selected_object_id: ?u64, content_rect_scale:
|
|||||||
var overlay = dvui.overlay(@src(), .{ .expand = .both });
|
var overlay = dvui.overlay(@src(), .{ .expand = .both });
|
||||||
{
|
{
|
||||||
const overlay_parent = dvui.parentGet();
|
const overlay_parent = dvui.parentGet();
|
||||||
var scroll = dvui.scrollArea(
|
const init_options: dvui.ScrollAreaWidget.InitOpts = .{
|
||||||
@src(),
|
|
||||||
.{
|
|
||||||
.scroll_info = &canvas.scroll,
|
.scroll_info = &canvas.scroll,
|
||||||
.vertical_bar = .auto,
|
.vertical_bar = .auto,
|
||||||
.horizontal_bar = .auto,
|
.horizontal_bar = .auto,
|
||||||
.process_events_after = false,
|
.process_events_after = false,
|
||||||
},
|
};
|
||||||
|
var scroll = dvui.scrollArea(
|
||||||
|
@src(),
|
||||||
|
init_options,
|
||||||
.{
|
.{
|
||||||
.expand = .both,
|
.expand = .both,
|
||||||
.background = false,
|
.background = false,
|
||||||
@@ -100,7 +101,7 @@ pub fn canvasView(canvas: *Canvas, selected_object_id: ?u64, content_rect_scale:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scroll.init_opts.process_events_after) {
|
if (!init_options.process_events_after) {
|
||||||
if (scroll.scroll) |*sc| {
|
if (scroll.scroll) |*sc| {
|
||||||
dvui.clipSet(sc.prevClip);
|
dvui.clipSet(sc.prevClip);
|
||||||
sc.processEventsAfter();
|
sc.processEventsAfter();
|
||||||
@@ -675,8 +676,7 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
const slice = canvas.allocator.alloc(Point2_f, list.items.len) catch return;
|
const slice = canvas.allocator.dupe(Point2_f, list.items) catch return;
|
||||||
@memcpy(slice, list.items);
|
|
||||||
obj.setProperty(canvas.allocator, .{ .data = .{ .points = slice } }) catch {
|
obj.setProperty(canvas.allocator, .{ .data = .{ .points = slice } }) catch {
|
||||||
canvas.allocator.free(slice);
|
canvas.allocator.free(slice);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -222,11 +222,13 @@ pub fn leftPanel(ctx: *WindowContext) void {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
{
|
{
|
||||||
dvui.label(@src(), "Objects", .{}, .{ .font = .{
|
dvui.label(@src(), "Objects", .{}, .{
|
||||||
.id = dvui.themeGet().font_heading.id,
|
.font = .{
|
||||||
.line_height_factor = dvui.themeGet().font_heading.line_height_factor,
|
.line_height_factor = dvui.themeGet().font_heading.line_height_factor,
|
||||||
.size = dvui.themeGet().font_heading.size + 8,
|
.size = dvui.themeGet().font_heading.size + 8,
|
||||||
}, .gravity_x = 0.5 });
|
},
|
||||||
|
.gravity_x = 0.5,
|
||||||
|
});
|
||||||
var scroll = dvui.scrollArea(
|
var scroll = dvui.scrollArea(
|
||||||
@src(),
|
@src(),
|
||||||
.{ .vertical = .auto, .horizontal = .auto },
|
.{ .vertical = .auto, .horizontal = .auto },
|
||||||
|
|||||||
Reference in New Issue
Block a user