tangled
alpha
login
or
join now
rockorager.dev
/
comlink
2
fork
atom
an experimental irc client
2
fork
atom
overview
issues
pulls
pipelines
ui: crude message drawing
rockorager.dev
1 year ago
c3bfb030
35324457
+74
1 changed file
expand all
collapse all
unified
split
src
irc.zig
+74
src/irc.zig
···
409
409
try children.append(topic_border);
410
410
}
411
411
412
412
+
const msg_view_ctx = ctx.withConstraints(.{ .height = 0, .width = 0 }, .{
413
413
+
.height = max.height - 4,
414
414
+
.width = max.width,
415
415
+
});
416
416
+
const message_view = try self.drawMessageView(msg_view_ctx);
417
417
+
try children.append(.{
418
418
+
.origin = .{ .row = 2, .col = 0 },
419
419
+
.surface = message_view,
420
420
+
});
421
421
+
412
422
// Draw the text field
413
423
try children.append(.{
414
424
.origin = .{ .col = 0, .row = max.height - 1 },
415
425
.surface = try self.text_field.draw(ctx),
416
426
});
427
427
+
428
428
+
return .{
429
429
+
.size = max,
430
430
+
.widget = self.contentWidget(),
431
431
+
.buffer = &.{},
432
432
+
.children = children.items,
433
433
+
};
434
434
+
}
435
435
+
436
436
+
fn drawMessageView(self: *Channel, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
437
437
+
const max = ctx.max.size();
438
438
+
if (max.width == 0 or max.height == 0) {
439
439
+
return .{
440
440
+
.size = max,
441
441
+
.widget = self.contentWidget(),
442
442
+
.buffer = &.{},
443
443
+
.children = &.{},
444
444
+
};
445
445
+
}
446
446
+
447
447
+
var children = std.ArrayList(vxfw.SubSurface).init(ctx.arena);
448
448
+
449
449
+
// Row is the row we are printing on.
450
450
+
var row: i17 = max.height;
451
451
+
var iter = std.mem.reverseIterator(self.messages.items);
452
452
+
const gutter_width = 6;
453
453
+
while (iter.next()) |msg| {
454
454
+
// Break if we have gone past the top of the screen
455
455
+
if (row < 0) break;
456
456
+
457
457
+
// Draw the message so we have it's wrapped height
458
458
+
const text: vxfw.Text = .{ .text = msg.bytes };
459
459
+
const child_ctx = ctx.withConstraints(
460
460
+
.{ .height = 0, .width = 0 },
461
461
+
.{ .width = max.width - gutter_width, .height = null },
462
462
+
);
463
463
+
const surface = try text.draw(child_ctx);
464
464
+
465
465
+
// Adjust the row we print on for the wrapped height of this message
466
466
+
row -= surface.size.height;
467
467
+
try children.append(.{
468
468
+
.origin = .{ .row = row, .col = gutter_width },
469
469
+
.surface = surface,
470
470
+
});
471
471
+
472
472
+
// If we have a time, print it in the gutter
473
473
+
if (msg.localTime(&self.client.app.tz)) |instant| {
474
474
+
const time = instant.time();
475
475
+
const buf = try std.fmt.allocPrint(
476
476
+
ctx.arena,
477
477
+
"{d:0>2}:{d:0>2}",
478
478
+
.{ time.hour, time.minute },
479
479
+
);
480
480
+
const time_text: vxfw.Text = .{
481
481
+
.text = buf,
482
482
+
.style = .{ .dim = true },
483
483
+
.softwrap = false,
484
484
+
};
485
485
+
try children.append(.{
486
486
+
.origin = .{ .row = row, .col = 0 },
487
487
+
.surface = try time_text.draw(child_ctx),
488
488
+
});
489
489
+
}
490
490
+
}
417
491
418
492
return .{
419
493
.size = max,