This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124//! This is the render state that is given to a renderer.
const std = @import("std");const Allocator = std.mem.Allocator;const Inspector = @import("../inspector/main.zig").Inspector;const terminalpkg = @import("../terminal/main.zig");const inputpkg = @import("../input.zig");const renderer = @import("../renderer.zig");
/// The mutex that must be held while reading any of the data in the/// members of this state. Note that the state itself is NOT protected/// by the mutex and is NOT thread-safe, only the members values of the/// state (i.e. the terminal, devmode, etc. values).mutex: *std.Thread.Mutex,
/// The terminal data.terminal: *terminalpkg.Terminal,
/// The terminal inspector, if any. This will be null while the inspector/// is not active and will be set when it is active.inspector: ?*Inspector = null,
/// Dead key state. This will render the current dead key preedit text/// over the cursor. This currently only ever renders a single codepoint./// Preedit can in theory be multiple codepoints long but that is left as/// a future exercise.preedit: ?Preedit = null,
/// Mouse state. This only contains state relevant to what renderers/// need about the mouse.mouse: Mouse = .{},
pub const Mouse = struct { /// The point on the viewport where the mouse currently is. We use /// viewport points to avoid the complexity of mapping the mouse to /// the renderer state. point: ?terminalpkg.point.Coordinate = null,
/// The mods that are currently active for the last mouse event. /// This could really just be mods in general and we probably will /// move it out of mouse state at some point. mods: inputpkg.Mods = .{},};
/// The pre-edit state. See Surface.preeditCallback for more information.pub const Preedit = struct { /// The codepoints to render as preedit text. codepoints: []const Codepoint = &.{},
/// A single codepoint to render as preedit text. pub const Codepoint = struct { codepoint: u21, wide: bool = false, };
/// Deinit this preedit that was cre pub fn deinit(self: *const Preedit, alloc: Allocator) void { alloc.free(self.codepoints); }
/// Allocate a copy of this preedit in the given allocator.. pub fn clone(self: *const Preedit, alloc: Allocator) !Preedit { return .{ .codepoints = try alloc.dupe(Codepoint, self.codepoints), }; }
/// The width in cells of all codepoints in the preedit. pub fn width(self: *const Preedit) usize { var result: usize = 0; for (self.codepoints) |cp| { result += if (cp.wide) 2 else 1; }
return result; }
/// Range returns the start and end x position of the preedit text /// along with any codepoint offset necessary to fit the preedit /// into the available space. pub fn range( self: *const Preedit, start: terminalpkg.size.CellCountInt, max: terminalpkg.size.CellCountInt, ) struct { start: terminalpkg.size.CellCountInt, end: terminalpkg.size.CellCountInt, cp_offset: usize, } { // If our width is greater than the number of cells we have // then we need to adjust our codepoint start to a point where // our width would be less than the number of cells we have. const w, const cp_offset = width: { // max is inclusive, so we need to add 1 to it. const max_width = max - start + 1;
// Rebuild our width in reverse order. This is because we want // to offset by the end cells, not the start cells (if we have to). var w: terminalpkg.size.CellCountInt = 0; for (0..self.codepoints.len) |i| { const reverse_i = self.codepoints.len - i - 1; const cp = self.codepoints[reverse_i]; w += if (cp.wide) 2 else 1; if (w > max_width) { break :width .{ w, reverse_i }; } }
// Width fit in the max width so no offset necessary. break :width .{ w, 0 }; };
// If our preedit goes off the end of the screen, we adjust it so // that it shifts left. const end = start + w; const start_offset = if (end > max) end - max else 0; return .{ .start = start -| start_offset, .end = end -| start_offset, .cp_offset = cp_offset, }; }};