added a window api of sorts, got started on grep style tool
parent
ff020fd059
commit
a7fa2f6b1d
|
@ -8,6 +8,36 @@ Mode :: enum {
|
||||||
Insert,
|
Insert,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowDrawProc :: proc(win: ^Window, state: ^State);
|
||||||
|
WindowFreeProc :: proc(win: ^Window, state: ^State);
|
||||||
|
WindowGetBufferProc :: proc(win: ^Window) -> ^FileBuffer;
|
||||||
|
Window :: struct {
|
||||||
|
input_map: InputMap,
|
||||||
|
draw: WindowDrawProc,
|
||||||
|
free: WindowFreeProc,
|
||||||
|
|
||||||
|
get_buffer: WindowGetBufferProc,
|
||||||
|
|
||||||
|
// TODO: create hook for when mode changes happen
|
||||||
|
}
|
||||||
|
request_window_close :: proc(state: ^State) {
|
||||||
|
state.should_close_window = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
close_window_and_free :: proc(state: ^State) {
|
||||||
|
if state.window != nil {
|
||||||
|
if state.window.free != nil {
|
||||||
|
state.window->free(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_input_map(&state.window.input_map);
|
||||||
|
free(state.window);
|
||||||
|
|
||||||
|
state.window = nil;
|
||||||
|
state.current_input_map = &state.input_map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
State :: struct {
|
State :: struct {
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
should_close: bool,
|
should_close: bool,
|
||||||
|
@ -22,10 +52,8 @@ State :: struct {
|
||||||
current_buffer: int,
|
current_buffer: int,
|
||||||
buffers: [dynamic]FileBuffer,
|
buffers: [dynamic]FileBuffer,
|
||||||
|
|
||||||
// TODO: replace this with generic pointer to floating window
|
window: ^Window,
|
||||||
buffer_list_window_is_visible: bool,
|
should_close_window: bool,
|
||||||
buffer_list_window_selected_buffer: int,
|
|
||||||
buffer_list_window_input_map: InputMap,
|
|
||||||
|
|
||||||
input_map: InputMap,
|
input_map: InputMap,
|
||||||
current_input_map: ^InputMap,
|
current_input_map: ^InputMap,
|
||||||
|
@ -50,6 +78,10 @@ new_input_map :: proc() -> InputMap {
|
||||||
|
|
||||||
return input_map;
|
return input_map;
|
||||||
}
|
}
|
||||||
|
delete_input_map :: proc(input_map: ^InputMap) {
|
||||||
|
delete(input_map.key_actions);
|
||||||
|
delete(input_map.ctrl_key_actions);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(pcleavelin): might be a bug in the compiler where it can't coerce
|
// NOTE(pcleavelin): might be a bug in the compiler where it can't coerce
|
||||||
// `EditorAction` to `InputGroup` when given as a proc parameter, that is why there
|
// `EditorAction` to `InputGroup` when given as a proc parameter, that is why there
|
||||||
|
|
|
@ -86,8 +86,11 @@ iterate_file_buffer :: proc(it: ^FileBufferIter) -> (character: u8, idx: FileBuf
|
||||||
} else if it.cursor.index.slice_index < len(it.buffer.content_slices)-1 {
|
} else if it.cursor.index.slice_index < len(it.buffer.content_slices)-1 {
|
||||||
it.cursor.index.content_index = 0;
|
it.cursor.index.content_index = 0;
|
||||||
it.cursor.index.slice_index += 1;
|
it.cursor.index.slice_index += 1;
|
||||||
} else {
|
} else if it.hit_end {
|
||||||
return character, it.cursor.index, false;
|
return character, it.cursor.index, false;
|
||||||
|
} else {
|
||||||
|
it.hit_end = true;
|
||||||
|
return character, it.cursor.index, true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if character == '\n' {
|
if character == '\n' {
|
||||||
|
@ -531,6 +534,31 @@ move_cursor_backward_end_of_word :: proc(buffer: ^FileBuffer) {
|
||||||
update_file_buffer_scroll(buffer);
|
update_file_buffer_scroll(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_virtual_file_buffer :: proc(allocator: mem.Allocator) -> FileBuffer {
|
||||||
|
context.allocator = allocator;
|
||||||
|
width := 256;
|
||||||
|
height := 256;
|
||||||
|
|
||||||
|
buffer := FileBuffer {
|
||||||
|
allocator = allocator,
|
||||||
|
file_path = "virtual_buffer",
|
||||||
|
|
||||||
|
original_content = slice.clone_to_dynamic([]u8{'\n'}),
|
||||||
|
added_content = make([dynamic]u8, 0, 1024*1024),
|
||||||
|
content_slices = make([dynamic][]u8, 0, 1024*1024),
|
||||||
|
|
||||||
|
glyph_buffer_width = width,
|
||||||
|
glyph_buffer_height = height,
|
||||||
|
glyph_buffer = make([dynamic]Glyph, width*height, width*height),
|
||||||
|
|
||||||
|
input_buffer = make([dynamic]u8, 0, 1024),
|
||||||
|
};
|
||||||
|
|
||||||
|
append(&buffer.content_slices, buffer.original_content[:]);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
new_file_buffer :: proc(allocator: mem.Allocator, file_path: string) -> (FileBuffer, Error) {
|
new_file_buffer :: proc(allocator: mem.Allocator, file_path: string) -> (FileBuffer, Error) {
|
||||||
context.allocator = allocator;
|
context.allocator = allocator;
|
||||||
|
|
||||||
|
@ -567,6 +595,14 @@ new_file_buffer :: proc(allocator: mem.Allocator, file_path: string) -> (FileBuf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_file_buffer :: proc(buffer: ^FileBuffer) {
|
||||||
|
delete(buffer.original_content);
|
||||||
|
delete(buffer.added_content);
|
||||||
|
delete(buffer.content_slices);
|
||||||
|
delete(buffer.glyph_buffer);
|
||||||
|
delete(buffer.input_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
is_keyword :: proc(start: FileBufferIter, end: FileBufferIter) -> (matches: bool) {
|
is_keyword :: proc(start: FileBufferIter, end: FileBufferIter) -> (matches: bool) {
|
||||||
keywords := []string {
|
keywords := []string {
|
||||||
"using",
|
"using",
|
||||||
|
|
165
src/main.odin
165
src/main.odin
|
@ -19,8 +19,8 @@ FileBuffer :: core.FileBuffer;
|
||||||
// TODO: use buffer list in state
|
// TODO: use buffer list in state
|
||||||
do_normal_mode :: proc(state: ^State, buffer: ^FileBuffer) {
|
do_normal_mode :: proc(state: ^State, buffer: ^FileBuffer) {
|
||||||
if state.current_input_map != nil {
|
if state.current_input_map != nil {
|
||||||
if raylib.IsKeyDown(.ESCAPE) {
|
if raylib.IsKeyPressed(.ESCAPE) {
|
||||||
state.current_input_map = &state.input_map;
|
core.request_window_close(state);
|
||||||
} else if raylib.IsKeyDown(.LEFT_CONTROL) {
|
} else if raylib.IsKeyDown(.LEFT_CONTROL) {
|
||||||
for key, action in &state.current_input_map.ctrl_key_actions {
|
for key, action in &state.current_input_map.ctrl_key_actions {
|
||||||
if raylib.IsKeyPressed(key) {
|
if raylib.IsKeyPressed(key) {
|
||||||
|
@ -87,9 +87,14 @@ switch_to_buffer :: proc(state: ^State, item: ^ui.MenuBarItem) {
|
||||||
|
|
||||||
register_default_leader_actions :: proc(input_map: ^core.InputMap) {
|
register_default_leader_actions :: proc(input_map: ^core.InputMap) {
|
||||||
core.register_key_action(input_map, .B, proc(state: ^State) {
|
core.register_key_action(input_map, .B, proc(state: ^State) {
|
||||||
state.buffer_list_window_is_visible = true;
|
state.window = ui.create_buffer_list_window();
|
||||||
state.current_input_map = &state.buffer_list_window_input_map;
|
state.current_input_map = &state.window.input_map;
|
||||||
}, "show list of open buffers");
|
}, "show list of open buffers");
|
||||||
|
core.register_key_action(input_map, .R, proc(state: ^State) {
|
||||||
|
state.window = ui.create_grep_window();
|
||||||
|
state.current_input_map = &state.window.input_map;
|
||||||
|
state.mode = .Insert;
|
||||||
|
}, "live grep");
|
||||||
core.register_key_action(input_map, .Q, proc(state: ^State) {
|
core.register_key_action(input_map, .Q, proc(state: ^State) {
|
||||||
state.current_input_map = &state.input_map;
|
state.current_input_map = &state.input_map;
|
||||||
}, "close this help");
|
}, "close this help");
|
||||||
|
@ -107,62 +112,70 @@ register_default_go_actions :: proc(input_map: ^core.InputMap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
register_default_input_actions :: proc(input_map: ^core.InputMap) {
|
register_default_input_actions :: proc(input_map: ^core.InputMap) {
|
||||||
core.register_key_action(input_map, .W, proc(state: ^State) {
|
// Cursor Movement
|
||||||
core.move_cursor_forward_start_of_word(&state.buffers[state.current_buffer]);
|
{
|
||||||
}, "move forward one word");
|
core.register_key_action(input_map, .W, proc(state: ^State) {
|
||||||
core.register_key_action(input_map, .E, proc(state: ^State) {
|
core.move_cursor_forward_start_of_word(&state.buffers[state.current_buffer]);
|
||||||
core.move_cursor_forward_end_of_word(&state.buffers[state.current_buffer]);
|
}, "move forward one word");
|
||||||
}, "move forward to end of word");
|
core.register_key_action(input_map, .E, proc(state: ^State) {
|
||||||
|
core.move_cursor_forward_end_of_word(&state.buffers[state.current_buffer]);
|
||||||
|
}, "move forward to end of word");
|
||||||
|
|
||||||
core.register_key_action(input_map, .B, proc(state: ^State) {
|
core.register_key_action(input_map, .B, proc(state: ^State) {
|
||||||
core.move_cursor_backward_start_of_word(&state.buffers[state.current_buffer]);
|
core.move_cursor_backward_start_of_word(&state.buffers[state.current_buffer]);
|
||||||
}, "move backward one word");
|
}, "move backward one word");
|
||||||
|
|
||||||
core.register_key_action(input_map, .K, proc(state: ^State) {
|
core.register_key_action(input_map, .K, proc(state: ^State) {
|
||||||
core.move_cursor_up(&state.buffers[state.current_buffer]);
|
core.move_cursor_up(&state.buffers[state.current_buffer]);
|
||||||
}, "move up one line");
|
}, "move up one line");
|
||||||
core.register_key_action(input_map, .J, proc(state: ^State) {
|
core.register_key_action(input_map, .J, proc(state: ^State) {
|
||||||
core.move_cursor_down(&state.buffers[state.current_buffer]);
|
core.move_cursor_down(&state.buffers[state.current_buffer]);
|
||||||
}, "move down one line");
|
}, "move down one line");
|
||||||
core.register_key_action(input_map, .H, proc(state: ^State) {
|
core.register_key_action(input_map, .H, proc(state: ^State) {
|
||||||
core.move_cursor_left(&state.buffers[state.current_buffer]);
|
core.move_cursor_left(&state.buffers[state.current_buffer]);
|
||||||
}, "move left one char");
|
}, "move left one char");
|
||||||
core.register_key_action(input_map, .L, proc(state: ^State) {
|
core.register_key_action(input_map, .L, proc(state: ^State) {
|
||||||
core.move_cursor_right(&state.buffers[state.current_buffer]);
|
core.move_cursor_right(&state.buffers[state.current_buffer]);
|
||||||
}, "move right one char");
|
}, "move right one char");
|
||||||
|
|
||||||
core.register_ctrl_key_action(input_map, .U, proc(state: ^State) {
|
core.register_ctrl_key_action(input_map, .U, proc(state: ^State) {
|
||||||
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Up);
|
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Up);
|
||||||
}, "scroll buffer up");
|
}, "scroll buffer up");
|
||||||
core.register_ctrl_key_action(input_map, .D, proc(state: ^State) {
|
core.register_ctrl_key_action(input_map, .D, proc(state: ^State) {
|
||||||
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Down);
|
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Down);
|
||||||
}, "scroll buffer up");
|
}, "scroll buffer up");
|
||||||
|
}
|
||||||
|
|
||||||
// Scale font size
|
// Scale font size
|
||||||
core.register_ctrl_key_action(input_map, .MINUS, proc(state: ^State) {
|
{
|
||||||
if state.source_font_height > 16 {
|
core.register_ctrl_key_action(input_map, .MINUS, proc(state: ^State) {
|
||||||
state.source_font_height -= 2;
|
if state.source_font_height > 16 {
|
||||||
|
state.source_font_height -= 2;
|
||||||
|
state.source_font_width = state.source_font_height / 2;
|
||||||
|
|
||||||
|
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
||||||
|
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||||
|
}
|
||||||
|
}, "increase font size");
|
||||||
|
core.register_ctrl_key_action(input_map, .EQUAL, proc(state: ^State) {
|
||||||
|
state.source_font_height += 2;
|
||||||
state.source_font_width = state.source_font_height / 2;
|
state.source_font_width = state.source_font_height / 2;
|
||||||
|
|
||||||
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
||||||
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||||
}
|
}, "decrease font size");
|
||||||
}, "increase font size");
|
}
|
||||||
core.register_ctrl_key_action(input_map, .EQUAL, proc(state: ^State) {
|
|
||||||
state.source_font_height += 2;
|
|
||||||
state.source_font_width = state.source_font_height / 2;
|
|
||||||
|
|
||||||
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
// Inserting Text
|
||||||
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
{
|
||||||
}, "decrease font size");
|
core.register_key_action(input_map, .I, proc(state: ^State) {
|
||||||
|
state.mode = .Insert;
|
||||||
core.register_key_action(input_map, .I, proc(state: ^State) {
|
}, "enter insert mode");
|
||||||
state.mode = .Insert;
|
core.register_key_action(input_map, .A, proc(state: ^State) {
|
||||||
}, "enter insert mode");
|
core.move_cursor_right(&state.buffers[state.current_buffer], false);
|
||||||
core.register_key_action(input_map, .A, proc(state: ^State) {
|
state.mode = .Insert;
|
||||||
core.move_cursor_right(&state.buffers[state.current_buffer], false);
|
}, "enter insert mode after character (append)");
|
||||||
state.mode = .Insert;
|
}
|
||||||
}, "enter insert mode after character (append)");
|
|
||||||
|
|
||||||
core.register_key_action(input_map, .SPACE, core.new_input_map(), "leader commands");
|
core.register_key_action(input_map, .SPACE, core.new_input_map(), "leader commands");
|
||||||
register_default_leader_actions(&(&input_map.key_actions[.SPACE]).action.(core.InputMap));
|
register_default_leader_actions(&(&input_map.key_actions[.SPACE]).action.(core.InputMap));
|
||||||
|
@ -171,44 +184,15 @@ register_default_input_actions :: proc(input_map: ^core.InputMap) {
|
||||||
register_default_go_actions(&(&input_map.key_actions[.G]).action.(core.InputMap));
|
register_default_go_actions(&(&input_map.key_actions[.G]).action.(core.InputMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
register_buffer_list_input_actions :: proc(input_map: ^core.InputMap) {
|
|
||||||
core.register_key_action(input_map, .K, proc(state: ^State) {
|
|
||||||
if state.buffer_list_window_selected_buffer > 0 {
|
|
||||||
state.buffer_list_window_selected_buffer -= 1;
|
|
||||||
} else {
|
|
||||||
state.buffer_list_window_selected_buffer = len(state.buffers)-1;
|
|
||||||
}
|
|
||||||
}, "move selection up");
|
|
||||||
core.register_key_action(input_map, .J, proc(state: ^State) {
|
|
||||||
if state.buffer_list_window_selected_buffer >= len(state.buffers)-1 {
|
|
||||||
state.buffer_list_window_selected_buffer = 0;
|
|
||||||
} else {
|
|
||||||
state.buffer_list_window_selected_buffer += 1;
|
|
||||||
}
|
|
||||||
}, "move selection down");
|
|
||||||
core.register_key_action(input_map, .ENTER, proc(state: ^State) {
|
|
||||||
state.current_buffer = state.buffer_list_window_selected_buffer;
|
|
||||||
|
|
||||||
state.buffer_list_window_is_visible = false;
|
|
||||||
state.current_input_map = &state.input_map;
|
|
||||||
}, "switch to file");
|
|
||||||
|
|
||||||
core.register_key_action(input_map, .Q, proc(state: ^State) {
|
|
||||||
state.buffer_list_window_is_visible = false;
|
|
||||||
state.current_input_map = &state.input_map;
|
|
||||||
}, "close window");
|
|
||||||
}
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
state := State {
|
state := State {
|
||||||
source_font_width = 8,
|
source_font_width = 8,
|
||||||
source_font_height = 16,
|
source_font_height = 16,
|
||||||
input_map = core.new_input_map(),
|
input_map = core.new_input_map(),
|
||||||
buffer_list_window_input_map = core.new_input_map(),
|
window = nil,
|
||||||
};
|
};
|
||||||
state.current_input_map = &state.input_map;
|
state.current_input_map = &state.input_map;
|
||||||
register_default_input_actions(&state.input_map);
|
register_default_input_actions(&state.input_map);
|
||||||
register_buffer_list_input_actions(&state.buffer_list_window_input_map);
|
|
||||||
|
|
||||||
for arg in os.args[1:] {
|
for arg in os.args[1:] {
|
||||||
buffer, err := core.new_file_buffer(context.allocator, arg);
|
buffer, err := core.new_file_buffer(context.allocator, arg);
|
||||||
|
@ -323,8 +307,8 @@ main :: proc() {
|
||||||
0,
|
0,
|
||||||
theme.get_palette_raylib_color(.Background1));
|
theme.get_palette_raylib_color(.Background1));
|
||||||
|
|
||||||
if state.buffer_list_window_is_visible {
|
if state.window != nil && state.window.draw != nil {
|
||||||
ui.draw_buffer_list_window(&state);
|
state.window->draw(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.current_input_map != &state.input_map {
|
if state.current_input_map != &state.input_map {
|
||||||
|
@ -377,9 +361,22 @@ main :: proc() {
|
||||||
|
|
||||||
switch state.mode {
|
switch state.mode {
|
||||||
case .Normal:
|
case .Normal:
|
||||||
do_normal_mode(&state, buffer);
|
if state.window != nil && state.window.get_buffer != nil {
|
||||||
|
do_normal_mode(&state, state.window->get_buffer());
|
||||||
|
} else {
|
||||||
|
do_normal_mode(&state, buffer);
|
||||||
|
}
|
||||||
case .Insert:
|
case .Insert:
|
||||||
do_insert_mode(&state, buffer);
|
if state.window != nil && state.window.get_buffer != nil {
|
||||||
|
do_insert_mode(&state, state.window->get_buffer());
|
||||||
|
} else {
|
||||||
|
do_insert_mode(&state, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.should_close_window {
|
||||||
|
state.should_close_window = false;
|
||||||
|
core.close_window_and_free(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.test_menu_bar(&state, &menu_bar_state, 0,0, mouse_pos, raylib.IsMouseButtonReleased(.LEFT), state.source_font_height);
|
ui.test_menu_bar(&state, &menu_bar_state, 0,0, mouse_pos, raylib.IsMouseButtonReleased(.LEFT), state.source_font_height);
|
||||||
|
|
|
@ -6,7 +6,60 @@ import "vendor:raylib"
|
||||||
import "../core"
|
import "../core"
|
||||||
import "../theme"
|
import "../theme"
|
||||||
|
|
||||||
draw_buffer_list_window :: proc(state: ^core.State) {
|
BufferListWindow :: struct {
|
||||||
|
using window: core.Window,
|
||||||
|
|
||||||
|
selected_buffer: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
create_buffer_list_window :: proc() -> ^BufferListWindow {
|
||||||
|
input_map := core.new_input_map();
|
||||||
|
|
||||||
|
core.register_key_action(&input_map, .K, proc(state: ^core.State) {
|
||||||
|
win := cast(^BufferListWindow)(state.window);
|
||||||
|
|
||||||
|
if win.selected_buffer > 0 {
|
||||||
|
win.selected_buffer -= 1;
|
||||||
|
} else {
|
||||||
|
win.selected_buffer = len(state.buffers)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, "move selection up");
|
||||||
|
core.register_key_action(&input_map, .J, proc(state: ^core.State) {
|
||||||
|
win := cast(^BufferListWindow)(state.window);
|
||||||
|
|
||||||
|
if win.selected_buffer >= len(state.buffers)-1 {
|
||||||
|
win.selected_buffer = 0;
|
||||||
|
} else {
|
||||||
|
win.selected_buffer += 1;
|
||||||
|
}
|
||||||
|
}, "move selection down");
|
||||||
|
core.register_key_action(&input_map, .ENTER, proc(state: ^core.State) {
|
||||||
|
win := cast(^BufferListWindow)(state.window);
|
||||||
|
|
||||||
|
state.current_buffer = win.selected_buffer;
|
||||||
|
|
||||||
|
core.request_window_close(state);
|
||||||
|
}, "switch to file");
|
||||||
|
|
||||||
|
core.register_key_action(&input_map, .Q, proc(state: ^core.State) {
|
||||||
|
core.request_window_close(state);
|
||||||
|
}, "close window");
|
||||||
|
|
||||||
|
list_window := new(BufferListWindow);
|
||||||
|
list_window^ = BufferListWindow {
|
||||||
|
window = core.Window {
|
||||||
|
input_map = input_map,
|
||||||
|
draw = draw_buffer_list_window,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return list_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_buffer_list_window :: proc(win: ^core.Window, state: ^core.State) {
|
||||||
|
win := cast(^BufferListWindow)(win);
|
||||||
|
|
||||||
win_rec := raylib.Rectangle {
|
win_rec := raylib.Rectangle {
|
||||||
x = f32(state.screen_width/8),
|
x = f32(state.screen_width/8),
|
||||||
y = f32(state.screen_height/8),
|
y = f32(state.screen_height/8),
|
||||||
|
@ -37,7 +90,7 @@ draw_buffer_list_window :: proc(state: ^core.State) {
|
||||||
text := raylib.TextFormat("%s:%d", buffer.file_path, buffer.cursor.line+1);
|
text := raylib.TextFormat("%s:%d", buffer.file_path, buffer.cursor.line+1);
|
||||||
text_width := raylib.MeasureTextEx(state.font, text, f32(state.source_font_height), 0);
|
text_width := raylib.MeasureTextEx(state.font, text, f32(state.source_font_height), 0);
|
||||||
|
|
||||||
if index == state.buffer_list_window_selected_buffer {
|
if index == win.selected_buffer {
|
||||||
buffer.glyph_buffer_height = glyph_buffer_height;
|
buffer.glyph_buffer_height = glyph_buffer_height;
|
||||||
buffer.glyph_buffer_width = glyph_buffer_width;
|
buffer.glyph_buffer_width = glyph_buffer_width;
|
||||||
core.draw_file_buffer(
|
core.draw_file_buffer(
|
|
@ -0,0 +1,97 @@
|
||||||
|
package ui;
|
||||||
|
|
||||||
|
import "core:math"
|
||||||
|
import "vendor:raylib"
|
||||||
|
|
||||||
|
import "../core"
|
||||||
|
import "../theme"
|
||||||
|
|
||||||
|
GrepWindow :: struct {
|
||||||
|
using window: core.Window,
|
||||||
|
|
||||||
|
input_buffer: core.FileBuffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
create_grep_window :: proc() -> ^GrepWindow {
|
||||||
|
input_map := core.new_input_map();
|
||||||
|
|
||||||
|
core.register_key_action(&input_map, .ENTER, proc(state: ^core.State) {
|
||||||
|
win := cast(^GrepWindow)(state.window);
|
||||||
|
|
||||||
|
core.request_window_close(state);
|
||||||
|
}, "jump to location");
|
||||||
|
|
||||||
|
core.register_key_action(&input_map, .I, proc(state: ^core.State) {
|
||||||
|
state.mode = .Insert;
|
||||||
|
}, "enter insert mode");
|
||||||
|
|
||||||
|
grep_window := new(GrepWindow);
|
||||||
|
grep_window^ = GrepWindow {
|
||||||
|
window = core.Window {
|
||||||
|
input_map = input_map,
|
||||||
|
draw = draw_grep_window,
|
||||||
|
get_buffer = grep_window_get_buffer,
|
||||||
|
free = free_grep_window,
|
||||||
|
},
|
||||||
|
|
||||||
|
input_buffer = core.new_virtual_file_buffer(context.allocator),
|
||||||
|
};
|
||||||
|
|
||||||
|
return grep_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
free_grep_window :: proc(win: ^core.Window, state: ^core.State) {
|
||||||
|
win := cast(^GrepWindow)(win);
|
||||||
|
|
||||||
|
core.free_file_buffer(&win.input_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
grep_window_get_buffer :: proc(win: ^core.Window) -> ^core.FileBuffer {
|
||||||
|
win := cast(^GrepWindow)(win);
|
||||||
|
|
||||||
|
return &win.input_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@private
|
||||||
|
grep_files :: proc(win: ^core.Window, state: ^core.State) {
|
||||||
|
// TODO: use rip-grep to search through files
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_grep_window :: proc(win: ^core.Window, state: ^core.State) {
|
||||||
|
win := cast(^GrepWindow)(win);
|
||||||
|
|
||||||
|
win_rec := raylib.Rectangle {
|
||||||
|
x = f32(state.screen_width/8),
|
||||||
|
y = f32(state.screen_height/8),
|
||||||
|
width = f32(state.screen_width - state.screen_width/4),
|
||||||
|
height = f32(state.screen_height - state.screen_height/4),
|
||||||
|
};
|
||||||
|
raylib.DrawRectangleRec(
|
||||||
|
win_rec,
|
||||||
|
theme.get_palette_raylib_color(.Background4));
|
||||||
|
|
||||||
|
win_margin := raylib.Vector2 { f32(state.source_font_width), f32(state.source_font_height) };
|
||||||
|
|
||||||
|
buffer_prev_width := (win_rec.width - win_margin.x*2) / 2;
|
||||||
|
buffer_prev_height := win_rec.height - win_margin.y*2;
|
||||||
|
|
||||||
|
glyph_buffer_width := int(buffer_prev_width) / state.source_font_width - 1;
|
||||||
|
glyph_buffer_height := 1;
|
||||||
|
|
||||||
|
raylib.DrawRectangle(
|
||||||
|
i32(win_rec.x + win_margin.x),
|
||||||
|
i32(win_rec.y + win_rec.height - win_margin.y * 2),
|
||||||
|
i32(buffer_prev_width),
|
||||||
|
i32(state.source_font_height),
|
||||||
|
theme.get_palette_raylib_color(.Background2));
|
||||||
|
|
||||||
|
win.input_buffer.glyph_buffer_height = glyph_buffer_height;
|
||||||
|
win.input_buffer.glyph_buffer_width = glyph_buffer_width;
|
||||||
|
core.draw_file_buffer(
|
||||||
|
state,
|
||||||
|
&win.input_buffer,
|
||||||
|
int(win_rec.x + win_margin.x),
|
||||||
|
int(win_rec.y + win_rec.height - win_margin.y * 2),
|
||||||
|
state.font,
|
||||||
|
show_line_numbers = false);
|
||||||
|
}
|
Loading…
Reference in New Issue