add debug panel, don't open same file twice
parent
ba312efe1a
commit
d27c566ff1
|
@ -96,10 +96,14 @@ Panel_VTable :: struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelType :: union {
|
PanelType :: union {
|
||||||
|
DebugPanel,
|
||||||
FileBufferPanel,
|
FileBufferPanel,
|
||||||
GrepPanel,
|
GrepPanel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DebugPanel :: struct {
|
||||||
|
}
|
||||||
|
|
||||||
FileBufferPanel :: struct {
|
FileBufferPanel :: struct {
|
||||||
buffer_id: int,
|
buffer_id: int,
|
||||||
viewed_symbol: Maybe(string),
|
viewed_symbol: Maybe(string),
|
||||||
|
@ -136,10 +140,12 @@ GrepQueryResult :: struct {
|
||||||
current_buffer :: proc(state: ^State) -> ^FileBuffer {
|
current_buffer :: proc(state: ^State) -> ^FileBuffer {
|
||||||
if current_panel, ok := state.current_panel.?; ok {
|
if current_panel, ok := state.current_panel.?; ok {
|
||||||
if panel, ok := util.get(&state.panels, current_panel).?; ok {
|
if panel, ok := util.get(&state.panels, current_panel).?; ok {
|
||||||
|
if panel.buffer != nil {
|
||||||
buffer, _ := panel->buffer(state)
|
buffer, _ := panel->buffer(state)
|
||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -149,6 +155,15 @@ new_buffer_virtual :: proc(state: ^State) -> (id: int, buffer: ^FileBuffer, ok:
|
||||||
}
|
}
|
||||||
|
|
||||||
new_buffer_file :: proc(state: ^State, file_path: string, line: int = 0, col: int = 0) -> (id: int, buffer: ^FileBuffer, ok: bool) {
|
new_buffer_file :: proc(state: ^State, file_path: string, line: int = 0, col: int = 0) -> (id: int, buffer: ^FileBuffer, ok: bool) {
|
||||||
|
for i in 0..<len(state.buffers.data) {
|
||||||
|
if buffer, ok := util.get(&state.buffers, i).?; ok {
|
||||||
|
if buffer.file_path == file_path {
|
||||||
|
move_cursor_to_location(buffer, line, col)
|
||||||
|
return i, buffer, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new_buffer, err := make_file_buffer(context.allocator, file_path, state.directory)
|
new_buffer, err := make_file_buffer(context.allocator, file_path, state.directory)
|
||||||
if err.type != .None {
|
if err.type != .None {
|
||||||
ok = false
|
ok = false
|
||||||
|
|
|
@ -749,6 +749,8 @@ new_virtual_file_buffer :: proc(allocator := context.allocator) -> FileBuffer {
|
||||||
glyphs = make_glyph_buffer(width, height),
|
glyphs = make_glyph_buffer(width, height),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
push_new_snapshot(&buffer.history)
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,6 +814,7 @@ make_file_buffer :: proc(allocator: mem.Allocator, file_path: string, base_dir:
|
||||||
glyphs = make_glyph_buffer(width, height),
|
glyphs = make_glyph_buffer(width, height),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
push_new_snapshot(&buffer.history)
|
||||||
ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(&buffer))
|
ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(&buffer))
|
||||||
|
|
||||||
return buffer, error();
|
return buffer, error();
|
||||||
|
@ -905,8 +908,8 @@ color_character :: proc(buffer: ^FileBuffer, start: Cursor, end: Cursor, palette
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x, y, w, h: int, show_line_numbers: bool = true, show_cursor: bool = true) {
|
draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x, y, w, h: int, show_line_numbers: bool = true, show_cursor: bool = true) {
|
||||||
glyph_width := math.min(256, int(w / state.source_font_width));
|
glyph_width := math.max(math.min(256, int(w / state.source_font_width)), 1);
|
||||||
glyph_height := math.min(256, int(h / state.source_font_height)) + 1;
|
glyph_height := math.max(math.min(256, int(h / state.source_font_height)) + 1, 1);
|
||||||
|
|
||||||
update_glyph_buffer(buffer, glyph_width, glyph_height);
|
update_glyph_buffer(buffer, glyph_width, glyph_height);
|
||||||
|
|
||||||
|
|
|
@ -265,6 +265,10 @@ main :: proc() {
|
||||||
panels.open(&state, panels.make_file_buffer_panel(""))
|
panels.open(&state, panels.make_file_buffer_panel(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
panels.open(&state, panels.make_debug_panel())
|
||||||
|
panels.open(&state, panels.make_debug_panel())
|
||||||
|
|
||||||
if sdl2.Init({.VIDEO}) < 0 {
|
if sdl2.Init({.VIDEO}) < 0 {
|
||||||
log.error("SDL failed to initialize:", sdl2.GetError());
|
log.error("SDL failed to initialize:", sdl2.GetError());
|
||||||
return;
|
return;
|
||||||
|
@ -331,8 +335,6 @@ main :: proc() {
|
||||||
|
|
||||||
sdl2.AddEventWatch(expose_event_watcher, &state);
|
sdl2.AddEventWatch(expose_event_watcher, &state);
|
||||||
|
|
||||||
core.push_new_snapshot(&core.current_buffer(&state).history)
|
|
||||||
|
|
||||||
control_key_pressed: bool;
|
control_key_pressed: bool;
|
||||||
for !state.should_close {
|
for !state.should_close {
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
package panels
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
import "core:mem"
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strings"
|
||||||
|
import "core:log"
|
||||||
|
|
||||||
|
import "vendor:sdl2"
|
||||||
|
|
||||||
|
import "../core"
|
||||||
|
import "../util"
|
||||||
|
import "../ui"
|
||||||
|
|
||||||
|
make_debug_panel :: proc() -> core.Panel {
|
||||||
|
return core.Panel {
|
||||||
|
type = core.DebugPanel {},
|
||||||
|
create = proc(panel: ^core.Panel, state: ^core.State) {
|
||||||
|
context.allocator = panel.allocator
|
||||||
|
|
||||||
|
panel_state := &panel.type.(core.DebugPanel)
|
||||||
|
panel.input_map = core.new_input_map(show_help = true)
|
||||||
|
|
||||||
|
panel_actions := core.new_input_actions(show_help = true)
|
||||||
|
register_default_panel_actions(&panel_actions)
|
||||||
|
core.register_ctrl_key_action(&panel.input_map.mode[.Normal], .W, panel_actions, "Panel Navigation")
|
||||||
|
},
|
||||||
|
render = proc(panel: ^core.Panel, state: ^core.State) -> (ok: bool) {
|
||||||
|
if panel_state, ok := &panel.type.(core.DebugPanel); ok {
|
||||||
|
s := transmute(^ui.State)state.ui
|
||||||
|
|
||||||
|
ui.open_element(s, nil,
|
||||||
|
{
|
||||||
|
dir = .TopToBottom,
|
||||||
|
kind = {ui.Fit{}, ui.Grow{}},
|
||||||
|
},
|
||||||
|
style = {
|
||||||
|
background_color = .Background1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
{
|
||||||
|
render_buffer_list(state, s)
|
||||||
|
|
||||||
|
ui.open_element(s, nil, {
|
||||||
|
kind = {ui.Fit{}, ui.Exact(8)},
|
||||||
|
})
|
||||||
|
ui.close_element(s)
|
||||||
|
|
||||||
|
render_panel_list(state, s)
|
||||||
|
}
|
||||||
|
ui.close_element(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_buffer_list :: proc(state: ^core.State, s: ^ui.State) {
|
||||||
|
ui.open_element(s, nil,
|
||||||
|
{
|
||||||
|
dir = .TopToBottom,
|
||||||
|
kind = {ui.Fit{}, ui.Fit{}},
|
||||||
|
},
|
||||||
|
style = {
|
||||||
|
background_color = .Background1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ui.open_element(s, "Open Buffers",
|
||||||
|
{
|
||||||
|
kind = {ui.Grow{}, ui.Fit{}},
|
||||||
|
},
|
||||||
|
style = {
|
||||||
|
border = {.Bottom},
|
||||||
|
border_color = .Background4,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ui.close_element(s)
|
||||||
|
|
||||||
|
ui.open_element(s, nil, {
|
||||||
|
kind = {ui.Fit{}, ui.Exact(8)},
|
||||||
|
})
|
||||||
|
ui.close_element(s)
|
||||||
|
|
||||||
|
for i in 0..<len(state.buffers.data) {
|
||||||
|
if buffer, ok := util.get(&state.buffers, i).?; ok {
|
||||||
|
buffer_label := fmt.tprintf("buf '%v' - %v", i, buffer.file_path[len(state.directory):])
|
||||||
|
ui.open_element(s, buffer_label, {})
|
||||||
|
ui.close_element(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.close_element(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
render_panel_list :: proc(state: ^core.State, s: ^ui.State) {
|
||||||
|
ui.open_element(s, nil,
|
||||||
|
{
|
||||||
|
dir = .TopToBottom,
|
||||||
|
kind = {ui.Fit{}, ui.Fit{}},
|
||||||
|
},
|
||||||
|
style = {
|
||||||
|
background_color = .Background1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ui.open_element(s, "Open Panels",
|
||||||
|
{
|
||||||
|
kind = {ui.Grow{}, ui.Fit{}},
|
||||||
|
},
|
||||||
|
style = {
|
||||||
|
border = {.Bottom},
|
||||||
|
border_color = .Background4,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ui.close_element(s)
|
||||||
|
|
||||||
|
ui.open_element(s, nil, {
|
||||||
|
kind = {ui.Fit{}, ui.Exact(8)},
|
||||||
|
})
|
||||||
|
ui.close_element(s)
|
||||||
|
|
||||||
|
for i in 0..<len(state.panels.data) {
|
||||||
|
if panel, ok := util.get(&state.panels, i).?; ok {
|
||||||
|
info: string
|
||||||
|
switch v in &panel.type {
|
||||||
|
case core.DebugPanel: info = "DebugPanel"
|
||||||
|
case core.FileBufferPanel: info = "FileBufferPanel"
|
||||||
|
case core.GrepPanel: info = "GrepPanel"
|
||||||
|
}
|
||||||
|
|
||||||
|
panel_label := fmt.tprintf("panel id '%v' - %v", i, info)
|
||||||
|
ui.open_element(s, panel_label, {})
|
||||||
|
ui.close_element(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.close_element(s)
|
||||||
|
}
|
|
@ -136,6 +136,8 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout {
|
||||||
case Exact: { e.layout.size.x = int(v) }
|
case Exact: { e.layout.size.x = int(v) }
|
||||||
case Fit: {
|
case Fit: {
|
||||||
it := e.first
|
it := e.first
|
||||||
|
|
||||||
|
if it != nil {
|
||||||
for child in iterate_siblings(state, &it) {
|
for child in iterate_siblings(state, &it) {
|
||||||
if child.layout.floating { continue }
|
if child.layout.floating { continue }
|
||||||
|
|
||||||
|
@ -151,6 +153,18 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
switch v in e.kind {
|
||||||
|
case UI_Element_Kind_Text: {
|
||||||
|
// FIXME: properly use font size
|
||||||
|
e.layout.size.x = len(v) * 12
|
||||||
|
}
|
||||||
|
case UI_Element_Kind_Image: {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
case UI_Element_Kind_Custom: { }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case Grow: {
|
case Grow: {
|
||||||
if _, ok := e.parent.?; !ok {
|
if _, ok := e.parent.?; !ok {
|
||||||
|
@ -177,6 +191,8 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout {
|
||||||
case Exact: { e.layout.size.y = int(v) }
|
case Exact: { e.layout.size.y = int(v) }
|
||||||
case Fit: {
|
case Fit: {
|
||||||
it := e.first
|
it := e.first
|
||||||
|
|
||||||
|
if it != nil {
|
||||||
for child in iterate_siblings(state, &it) {
|
for child in iterate_siblings(state, &it) {
|
||||||
if child.layout.floating { continue }
|
if child.layout.floating { continue }
|
||||||
|
|
||||||
|
@ -192,6 +208,19 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
switch v in e.kind {
|
||||||
|
case UI_Element_Kind_Text: {
|
||||||
|
// TODO: wrap text
|
||||||
|
// FIXME: properly use font size
|
||||||
|
e.layout.size.y = 16
|
||||||
|
}
|
||||||
|
case UI_Element_Kind_Image: {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
case UI_Element_Kind_Custom: { }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case Grow: {
|
case Grow: {
|
||||||
if _, ok := e.parent.?; !ok {
|
if _, ok := e.parent.?; !ok {
|
||||||
|
@ -316,7 +345,7 @@ grow_children :: proc(state: ^State, index: int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if num_growing.x > 0 || num_growing.y > 0 {
|
if true || num_growing.x > 0 || num_growing.y > 0 {
|
||||||
remaining_size := [2]int{ x_e, y_e } - children_size
|
remaining_size := [2]int{ x_e, y_e } - children_size
|
||||||
to_grow: [2]int
|
to_grow: [2]int
|
||||||
to_grow.x = 0 if num_growing.x < 1 else remaining_size.x/num_growing.x
|
to_grow.x = 0 if num_growing.x < 1 else remaining_size.x/num_growing.x
|
||||||
|
@ -348,9 +377,9 @@ grow_children :: proc(state: ^State, index: int) {
|
||||||
_, x_growing := child.layout.kind.x.(Grow)
|
_, x_growing := child.layout.kind.x.(Grow)
|
||||||
_, y_growing := child.layout.kind.y.(Grow)
|
_, y_growing := child.layout.kind.y.(Grow)
|
||||||
|
|
||||||
if x_growing || y_growing || child.layout.floating {
|
// if x_growing || y_growing || child.layout.floating {
|
||||||
grow_children(state, child_index)
|
grow_children(state, child_index)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue