parent
3e953981fe
commit
e1b1591167
10 changed files with 184 additions and 14 deletions
|
@ -81,6 +81,7 @@
|
|||
["ctrl+x ctrl+f", "open_file"],
|
||||
["ctrl+x b", "open_recent"],
|
||||
["alt+x", "open_command_palette"],
|
||||
["f", "change_fontface"],
|
||||
["ctrl+x ctrl+c", "quit"]
|
||||
]
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@
|
|||
["g", "open_gui_config"],
|
||||
["k", "open_keybind_config"],
|
||||
["t", "change_theme"],
|
||||
["f", "change_fontface"],
|
||||
["q", "quit"],
|
||||
["ctrl+\\", "add_split"],
|
||||
["ctrl+f ctrl+f ctrl+f ctrl+f ctrl+f", "home_sheeran"],
|
||||
|
|
|
@ -515,6 +515,7 @@
|
|||
["b", "open_keybind_config"],
|
||||
["j", "home_menu_down"],
|
||||
["k", "home_menu_up"],
|
||||
["f", "change_fontface"],
|
||||
["space", "home_menu_activate"]
|
||||
]
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
["b", "open_keybind_config"],
|
||||
["j", "home_menu_down"],
|
||||
["k", "home_menu_up"],
|
||||
["f", "change_fontface"],
|
||||
["<Space>", "home_menu_activate"]
|
||||
]
|
||||
}
|
||||
|
|
|
@ -396,6 +396,11 @@ pub fn reset_fontface(self: *Self) void {
|
|||
gui.reset_fontface(hwnd);
|
||||
}
|
||||
|
||||
pub fn get_fontfaces(self: *Self) void {
|
||||
const hwnd = self.hwnd orelse return;
|
||||
gui.get_fontfaces(hwnd);
|
||||
}
|
||||
|
||||
pub fn set_terminal_cursor_color(self: *Self, color: Color) void {
|
||||
_ = self;
|
||||
_ = color;
|
||||
|
|
|
@ -37,6 +37,7 @@ const menu_commands = if (build_options.gui) &[_][]const u8{
|
|||
"open_keybind_config",
|
||||
"toggle_input_mode",
|
||||
"change_theme",
|
||||
"change_fontface",
|
||||
"quit",
|
||||
} else &[_][]const u8{
|
||||
"open_help",
|
||||
|
@ -101,9 +102,13 @@ fn add_menu_command(self: *Self, comptime command_name: []const u8, menu: anytyp
|
|||
var buf: [64]u8 = undefined;
|
||||
var fis = std.io.fixedBufferStream(&buf);
|
||||
const writer = fis.writer();
|
||||
try writer.print("{s} ..", .{description});
|
||||
const leader = if (hint.len > 0) "." else " ";
|
||||
_ = try writer.write(description);
|
||||
_ = try writer.write(" ");
|
||||
_ = try writer.write(leader);
|
||||
_ = try writer.write(leader);
|
||||
for (0..(self.max_desc_len - label_len - 5)) |_|
|
||||
try writer.print(".", .{});
|
||||
_ = try writer.write(leader);
|
||||
try writer.print(" :{s}", .{hint});
|
||||
const label = fis.getWritten();
|
||||
try menu.add_item_with_handler(label, menu_action(command_name));
|
||||
|
|
78
src/tui/mode/overlay/fontface_palette.zig
Normal file
78
src/tui/mode/overlay/fontface_palette.zig
Normal file
|
@ -0,0 +1,78 @@
|
|||
const std = @import("std");
|
||||
const cbor = @import("cbor");
|
||||
const tp = @import("thespian");
|
||||
|
||||
const Widget = @import("../../Widget.zig");
|
||||
const tui = @import("../../tui.zig");
|
||||
|
||||
pub const Type = @import("palette.zig").Create(@This());
|
||||
|
||||
pub const label = "Select font face";
|
||||
pub const name = " font";
|
||||
pub const description = "font";
|
||||
|
||||
pub const Entry = struct {
|
||||
label: []const u8,
|
||||
};
|
||||
|
||||
pub const Match = struct {
|
||||
label: []const u8,
|
||||
score: i32,
|
||||
matches: []const usize,
|
||||
};
|
||||
|
||||
var previous_fontface: ?[]const u8 = null;
|
||||
|
||||
pub fn deinit(palette: *Type) void {
|
||||
if (previous_fontface) |fontface|
|
||||
palette.allocator.free(fontface);
|
||||
previous_fontface = null;
|
||||
for (palette.entries.items) |entry|
|
||||
palette.allocator.free(entry.label);
|
||||
}
|
||||
|
||||
pub fn load_entries(palette: *Type) !usize {
|
||||
var idx: usize = 0;
|
||||
previous_fontface = try palette.allocator.dupe(u8, tui.current().fontface);
|
||||
const fontfaces = tui.current().fontfaces orelse return 0;
|
||||
tui.current().fontfaces = null;
|
||||
for (fontfaces.items) |fontface| {
|
||||
idx += 1;
|
||||
(try palette.entries.addOne()).* = .{ .label = fontface };
|
||||
if (previous_fontface) |previous_fontface_| if (std.mem.eql(u8, fontface, previous_fontface_)) {
|
||||
palette.initial_selected = idx;
|
||||
};
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn add_menu_entry(palette: *Type, entry: *Entry, matches: ?[]const usize) !void {
|
||||
var value = std.ArrayList(u8).init(palette.allocator);
|
||||
defer value.deinit();
|
||||
const writer = value.writer();
|
||||
try cbor.writeValue(writer, entry.label);
|
||||
try cbor.writeValue(writer, matches orelse &[_]usize{});
|
||||
try palette.menu.add_item_with_handler(value.items, select);
|
||||
palette.items += 1;
|
||||
}
|
||||
|
||||
fn select(menu: **Type.MenuState, button: *Type.ButtonState) void {
|
||||
var label_: []const u8 = undefined;
|
||||
var iter = button.opts.label;
|
||||
if (!(cbor.matchString(&iter, &label_) catch false)) return;
|
||||
tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch |e| menu.*.opts.ctx.logger.err("fontface_palette", e);
|
||||
tp.self_pid().send(.{ "cmd", "set_fontface", .{label_} }) catch |e| menu.*.opts.ctx.logger.err("fontface_palette", e);
|
||||
}
|
||||
|
||||
pub fn updated(palette: *Type, button_: ?*Type.ButtonState) !void {
|
||||
const button = button_ orelse return cancel(palette);
|
||||
var label_: []const u8 = undefined;
|
||||
var iter = button.opts.label;
|
||||
if (!(cbor.matchString(&iter, &label_) catch false)) return;
|
||||
tp.self_pid().send(.{ "cmd", "set_fontface", .{label_} }) catch |e| palette.logger.err("fontface_palette upated", e);
|
||||
}
|
||||
|
||||
pub fn cancel(palette: *Type) !void {
|
||||
if (previous_fontface) |prev|
|
||||
tp.self_pid().send(.{ "cmd", "set_fontface", .{prev} }) catch |e| palette.logger.err("fontface_palette cancel", e);
|
||||
}
|
|
@ -76,7 +76,6 @@ pub fn Create(options: type) type {
|
|||
try self.start_query(0);
|
||||
try mv.floating_views.add(self.modal.widget());
|
||||
try mv.floating_views.add(self.menu.container_widget);
|
||||
if (self.initial_selected) |idx| self.select(idx);
|
||||
var mode = try keybind.mode("overlay/palette", allocator, .{
|
||||
.insert_command = "overlay_insert_bytes",
|
||||
});
|
||||
|
@ -154,7 +153,7 @@ pub fn Create(options: type) type {
|
|||
|
||||
fn on_resize_menu(self: *Self, _: *Menu.State(*Self), _: Widget.Box) void {
|
||||
self.do_resize();
|
||||
self.start_query(0) catch {};
|
||||
// self.start_query(0) catch {};
|
||||
}
|
||||
|
||||
fn do_resize(self: *Self) void {
|
||||
|
@ -231,13 +230,18 @@ pub fn Create(options: type) type {
|
|||
} else {
|
||||
_ = try self.query_entries(self.inputbox.text.items);
|
||||
}
|
||||
self.menu.select_down();
|
||||
var i = n;
|
||||
while (i > 0) : (i -= 1)
|
||||
if (self.initial_selected) |idx| {
|
||||
self.initial_selected = null;
|
||||
self.select(idx);
|
||||
} else {
|
||||
self.menu.select_down();
|
||||
self.do_resize();
|
||||
tui.current().refresh_hover();
|
||||
self.selection_updated();
|
||||
var i = n;
|
||||
while (i > 0) : (i -= 1)
|
||||
self.menu.select_down();
|
||||
self.do_resize();
|
||||
tui.current().refresh_hover();
|
||||
self.selection_updated();
|
||||
}
|
||||
}
|
||||
|
||||
fn query_entries(self: *Self, query: []const u8) error{OutOfMemory}!usize {
|
||||
|
|
|
@ -54,6 +54,8 @@ render_pending: bool = false,
|
|||
keepalive_timer: ?tp.Cancellable = null,
|
||||
mouse_idle_timer: ?tp.Cancellable = null,
|
||||
default_cursor: keybind.CursorShape = .default,
|
||||
fontface: []const u8 = "",
|
||||
fontfaces: ?std.ArrayList([]const u8) = null,
|
||||
|
||||
const keepalive = std.time.us_per_day * 365; // one year
|
||||
const idle_frames = 0;
|
||||
|
@ -381,6 +383,27 @@ fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void {
|
|||
return;
|
||||
}
|
||||
|
||||
if (try m.match(.{ "fontface", "done" })) {
|
||||
return self.enter_overlay_mode(@import("mode/overlay/fontface_palette.zig").Type);
|
||||
}
|
||||
|
||||
var fontface: []const u8 = undefined;
|
||||
if (try m.match(.{ "fontface", "current", tp.extract(&fontface) })) {
|
||||
if (self.fontface.len > 0) self.allocator.free(self.fontface);
|
||||
self.fontface = "";
|
||||
self.fontface = try self.allocator.dupe(u8, fontface);
|
||||
return;
|
||||
}
|
||||
|
||||
if (try m.match(.{ "fontface", tp.extract(&fontface) })) {
|
||||
var fontfaces = if (self.fontfaces) |*p| p else blk: {
|
||||
self.fontfaces = std.ArrayList([]const u8).init(self.allocator);
|
||||
break :blk &self.fontfaces.?;
|
||||
};
|
||||
try fontfaces.append(try self.allocator.dupe(u8, fontface));
|
||||
return;
|
||||
}
|
||||
|
||||
return tp.unexpected(m);
|
||||
}
|
||||
|
||||
|
@ -798,6 +821,12 @@ const cmds = struct {
|
|||
}
|
||||
pub const change_file_type_meta = .{ .description = "Change file type" };
|
||||
|
||||
pub fn change_fontface(self: *Self, _: Ctx) Result {
|
||||
if (build_options.gui)
|
||||
self.rdr.get_fontfaces();
|
||||
}
|
||||
pub const change_fontface_meta = .{ .description = "Select font face" };
|
||||
|
||||
pub fn exit_overlay_mode(self: *Self, _: Ctx) Result {
|
||||
self.rdr.cursor_disable();
|
||||
if (self.input_mode_outer == null) return;
|
||||
|
|
|
@ -31,7 +31,8 @@ const WM_APP_SET_FONTSIZE = win32.WM_APP + 4;
|
|||
const WM_APP_SET_FONTFACE = win32.WM_APP + 5;
|
||||
const WM_APP_RESET_FONTSIZE = win32.WM_APP + 6;
|
||||
const WM_APP_RESET_FONTFACE = win32.WM_APP + 7;
|
||||
const WM_APP_UPDATE_SCREEN = win32.WM_APP + 8;
|
||||
const WM_APP_GET_FONTFACES = win32.WM_APP + 8;
|
||||
const WM_APP_UPDATE_SCREEN = win32.WM_APP + 9;
|
||||
|
||||
const WM_APP_EXIT_RESULT = 0x45feaa11;
|
||||
const WM_APP_SET_BACKGROUND_RESULT = 0x369a26cd;
|
||||
|
@ -40,6 +41,7 @@ const WM_APP_SET_FONTSIZE_RESULT = 0x72fa44bc;
|
|||
const WM_APP_SET_FONTFACE_RESULT = 0x1a49ffa8;
|
||||
const WM_APP_RESET_FONTSIZE_RESULT = 0x082c4c0c;
|
||||
const WM_APP_RESET_FONTFACE_RESULT = 0x0101f996;
|
||||
const WM_APP_GET_FONTFACES_RESULT = 0x07e228f5;
|
||||
const WM_APP_UPDATE_SCREEN_RESULT = 0x3add213b;
|
||||
|
||||
pub const DropWriter = struct {
|
||||
|
@ -128,7 +130,7 @@ fn getIcons(dpi: XY(u32)) Icons {
|
|||
return .{ .small = @ptrCast(small), .large = @ptrCast(large) };
|
||||
}
|
||||
|
||||
fn getConfig() *const gui_config {
|
||||
fn getConfig() *gui_config {
|
||||
if (global.conf == null) {
|
||||
global.conf, _ = root.read_config(gui_config, global.arena);
|
||||
root.write_config(global.conf.?, global.arena) catch
|
||||
|
@ -171,6 +173,15 @@ fn getFontFace() *const FontFace {
|
|||
return &(global.fontface.?);
|
||||
}
|
||||
|
||||
fn setFontFace(fontface: *const FontFace) void {
|
||||
global.fontface = fontface.*;
|
||||
const conf = getConfig();
|
||||
var buf: [FontFace.max * 2]u8 = undefined;
|
||||
conf.fontface = buf[0 .. std.unicode.utf16LeToUtf8(&buf, fontface.slice()) catch return];
|
||||
root.write_config(conf.*, global.arena) catch
|
||||
std.log.err("failed to write gui config file", .{});
|
||||
}
|
||||
|
||||
fn getFontSize() f32 {
|
||||
if (global.fontsize == null) {
|
||||
global.fontsize = @floatFromInt(getConfig().fontsize);
|
||||
|
@ -492,6 +503,15 @@ pub fn reset_fontface(hwnd: win32.HWND) void {
|
|||
));
|
||||
}
|
||||
|
||||
pub fn get_fontfaces(hwnd: win32.HWND) void {
|
||||
std.debug.assert(WM_APP_GET_FONTFACES_RESULT == win32.SendMessageW(
|
||||
hwnd,
|
||||
WM_APP_GET_FONTFACES,
|
||||
0,
|
||||
0,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn updateScreen(hwnd: win32.HWND, screen: *const vaxis.Screen) void {
|
||||
std.debug.assert(WM_APP_UPDATE_SCREEN_RESULT == win32.SendMessageW(
|
||||
hwnd,
|
||||
|
@ -543,6 +563,27 @@ fn updateWindowSize(
|
|||
setWindowPosRect(hwnd, new_rect);
|
||||
}
|
||||
|
||||
fn getFontFaces(state: *State) void {
|
||||
const fonts = render.Fonts.init();
|
||||
defer fonts.deinit();
|
||||
var buf: [FontFace.max * 2]u8 = undefined;
|
||||
|
||||
if (global.fontface) |fontface|
|
||||
state.pid.send(.{
|
||||
"fontface",
|
||||
"current",
|
||||
buf[0 .. std.unicode.utf16LeToUtf8(&buf, fontface.slice()) catch 0],
|
||||
}) catch {};
|
||||
|
||||
for (0..fonts.count()) |font_index|
|
||||
state.pid.send(.{
|
||||
"fontface",
|
||||
buf[0 .. std.unicode.utf16LeToUtf8(&buf, fonts.getName(font_index).slice()) catch 0],
|
||||
}) catch {};
|
||||
|
||||
state.pid.send(.{ "fontface", "done" }) catch {};
|
||||
}
|
||||
|
||||
const CellPos = struct {
|
||||
cell: XY(i32),
|
||||
offset: XY(i32),
|
||||
|
@ -1138,8 +1179,7 @@ fn WndProc(
|
|||
},
|
||||
WM_APP_SET_FONTFACE => {
|
||||
const state = stateFromHwnd(hwnd);
|
||||
const fontface: *FontFace = @ptrFromInt(wparam);
|
||||
global.fontface = fontface.*;
|
||||
setFontFace(@ptrFromInt(wparam));
|
||||
updateWindowSize(hwnd, win32.WMSZ_BOTTOMRIGHT, &state.bounds);
|
||||
win32.invalidateHwnd(hwnd);
|
||||
return WM_APP_SET_FONTFACE_RESULT;
|
||||
|
@ -1151,6 +1191,11 @@ fn WndProc(
|
|||
win32.invalidateHwnd(hwnd);
|
||||
return WM_APP_SET_FONTFACE_RESULT;
|
||||
},
|
||||
WM_APP_GET_FONTFACES => {
|
||||
const state = stateFromHwnd(hwnd);
|
||||
getFontFaces(state);
|
||||
return WM_APP_GET_FONTFACES_RESULT;
|
||||
},
|
||||
WM_APP_UPDATE_SCREEN => {
|
||||
const screen: *const vaxis.Screen = @ptrFromInt(wparam);
|
||||
_ = global.screen_arena.reset(.retain_capacity);
|
||||
|
|
Loading…
Add table
Reference in a new issue