when losing focus, show hollow box

This commit is contained in:
Mitchell Hashimoto
2022-04-22 21:58:15 -07:00
parent 7169679654
commit bd7855da46
4 changed files with 89 additions and 3 deletions

View File

@ -7,12 +7,23 @@ flat in uint mode;
// background color. Otherwise, this is the foreground color.
flat in vec4 color;
// The position of the cells top-left corner.
flat in vec2 screen_cell_pos;
// Position the fragment coordinate to the upper left
layout(origin_upper_left) in vec4 gl_FragCoord;
// Font texture
uniform sampler2D text;
// Dimensions of the cell
uniform vec2 cell_size;
// See fragment shader
const uint MODE_BG = 1u;
const uint MODE_FG = 2u;
const uint MODE_CURSOR_RECT = 3u;
const uint MODE_CURSOR_RECT_HOLLOW = 4u;
void main() {
switch (mode) {
@ -24,5 +35,45 @@ void main() {
float a = texture(text, glyph_tex_coords).r;
gl_FragColor = vec4(color.rgb, color.a*a);
break;
case MODE_CURSOR_RECT:
gl_FragColor = color;
break;
case MODE_CURSOR_RECT_HOLLOW:
// Okay so yeah this is probably horrendously slow and a shader
// should never do this, but we only ever render a cursor for ONE
// rectangle so we take the slowdown for that one.
// Default to no color.
gl_FragColor = vec4(0., 0., 0, 0.0);
// We subtracted one from cell size because our coordinates start at 0.
// So a width of 50 means max pixel of 49.
vec2 cell_size_coords = cell_size - 1;
// Apply padding
vec2 padding = vec2(1.,1.);
cell_size_coords = cell_size_coords - (padding * 2);
vec2 screen_cell_pos_padded = screen_cell_pos + padding;
// Convert our frag coord to offset of this cell. We have to subtract
// 0.5 because the frag coord is in center pixels.
vec2 cell_frag_coord = gl_FragCoord.xy - screen_cell_pos_padded - 0.5;
// If the frag coords are in the bounds, then we color it.
const float eps = 0.1;
if (cell_frag_coord.x >= 0 && cell_frag_coord.y >= 0 &&
cell_frag_coord.x <= cell_size_coords.x &&
cell_frag_coord.y <= cell_size_coords.y) {
if (abs(cell_frag_coord.x) < eps ||
abs(cell_frag_coord.x - cell_size_coords.x) < eps ||
abs(cell_frag_coord.y) < eps ||
abs(cell_frag_coord.y - cell_size_coords.y) < eps) {
gl_FragColor = color;
}
}
break;
}
}

View File

@ -6,6 +6,8 @@
// NOTE: this must be kept in sync with the fragment shader
const uint MODE_BG = 1u;
const uint MODE_FG = 2u;
const uint MODE_CURSOR_RECT = 3u;
const uint MODE_CURSOR_RECT_HOLLOW = 4u;
// The grid coordinates (x, y) where x < columns and y < rows
layout (location = 0) in vec2 grid_coord;
@ -38,6 +40,10 @@ flat out vec4 color;
// The x/y coordinate for the glyph representing the font.
out vec2 glyph_tex_coords;
// The position of the cell top-left corner in screen cords. z and w
// are width and height.
flat out vec2 screen_cell_pos;
// Pass the mode forward to the fragment shader.
flat out uint mode;
@ -121,5 +127,24 @@ void main() {
// Set our foreground color output
color = fg_color_in / 255.;
break;
case MODE_CURSOR_RECT:
// Same as background since we're taking up the whole cell.
cell_pos = cell_pos + cell_size * position;
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
color = bg_color_in / 255.0;
break;
case MODE_CURSOR_RECT_HOLLOW:
// Top-left position of this cell is needed for the hollow rect.
screen_cell_pos = cell_pos;
// Same as background since we're taking up the whole cell.
cell_pos = cell_pos + cell_size * position;
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
color = bg_color_in / 255.0;
break;
}
}

View File

@ -37,6 +37,12 @@ font_atlas: FontAtlas,
/// Whether the cursor is visible or not. This is used to control cursor
/// blinking.
cursor_visible: bool,
cursor_style: CursorStyle,
const CursorStyle = enum(u8) {
box = 3,
box_hollow = 4,
};
/// The raw structure that maps directly to the buffer sent to the vertex shader.
const GPUCell = struct {
@ -211,6 +217,7 @@ pub fn init(alloc: Allocator) !Grid {
.texture = tex,
.font_atlas = font,
.cursor_visible = true,
.cursor_style = .box,
};
}
@ -295,7 +302,7 @@ pub fn updateCells(self: *Grid, term: Terminal) !void {
// Draw the cursor
if (self.cursor_visible) {
self.cells.appendAssumeCapacity(.{
.mode = 1,
.mode = @enumToInt(self.cursor_style),
.grid_col = @intCast(u16, term.cursor.x),
.grid_row = @intCast(u16, term.cursor.y),
.fg_r = 0,

View File

@ -221,10 +221,13 @@ fn keyCallback(
fn focusCallback(window: glfw.Window, focused: bool) void {
const win = window.getUserPointer(Window) orelse return;
if (focused) {
win.cursor_timer.start(cursorTimerCallback, 800, 800) catch unreachable;
win.wakeup = true;
} else {
win.cursor_timer.start(cursorTimerCallback, 0, 800) catch unreachable;
win.grid.cursor_style = .box;
win.grid.cursor_visible = false;
} else {
win.grid.cursor_visible = true;
win.grid.cursor_style = .box_hollow;
win.grid.updateCells(win.terminal) catch unreachable;
win.cursor_timer.stop() catch unreachable;
}