From: Lukáš Jiřiště Date: Tue, 11 Aug 2026 15:15:02 +0000 (+0200) Subject: Implement moving around in schematic view X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=09283a74ba075067a85efb66900aff15483a0b47;p=FET_sim.git Implement moving around in schematic view --- diff --git a/inc/FET_sim.h b/inc/FET_sim.h index b284b9e..1fc9fa1 100644 --- a/inc/FET_sim.h +++ b/inc/FET_sim.h @@ -144,6 +144,7 @@ typedef struct s_schematics_window { WINDOW *win; t_position view_pos; + t_position view_size; } t_schem_win; typedef struct s_windows @@ -166,6 +167,13 @@ int merge_nodes(t_vec *nodes, t_vec *mosfets, t_node *node1, t_node *node2); void free_node(void *node); int process_input(t_windows *windows, t_vec *nodes, t_vec *mosfets); int get_input(WINDOW *command_win, t_input *input); +void get_viewport_size(t_schem_win *schematics_win); + +int is_in_viewport(t_schem_win schematics_win, t_position position); +t_position get_cursor_pos(t_schem_win schematics_win); +int cursor_move_unprivileged(t_schem_win schematics_win, long y, long x); +int cursor_move(t_schem_win *schematics_win, long y, long x); +void draw_symbol(t_schem_win schematics_win, t_position position, t_symbol ch); const char *state_color_escape(t_state state); void draw_single(WINDOW *command_win, t_vec *nodes, const t_mosfet *mosfet); diff --git a/src/colors.c b/src/colors.c index 2ce8aad..18136b9 100644 --- a/src/colors.c +++ b/src/colors.c @@ -113,9 +113,9 @@ void schema_draw_mosfet(t_schem_win schematics_win, t_vec *nodes, const t_mosfet t_position old_pos; t_position work_pos; - getyx(schematics_win.win, old_pos.y, old_pos.x); + old_pos = get_cursor_pos(schematics_win); work_pos = mosfet->position; - mvwaddch(schematics_win.win, work_pos.y, work_pos.x, mosfet->type); + draw_symbol(schematics_win, work_pos, mosfet->type); if (mosfet->orientation == UP) ++work_pos.y; else if (mosfet->orientation == DOWN) @@ -124,9 +124,11 @@ void schema_draw_mosfet(t_schem_win schematics_win, t_vec *nodes, const t_mosfet ++work_pos.x; else if (mosfet->orientation == RIGHT) --work_pos.x; - wmove(schematics_win.win, work_pos.y, work_pos.x); - draw_switch(schematics_win.win, nodes, mosfet, mosfet->orientation); - wmove(schematics_win.win, old_pos.y, old_pos.x); + if (!cursor_move_unprivileged(schematics_win, work_pos.y, work_pos.x)) + { + draw_switch(schematics_win.win, nodes, mosfet, mosfet->orientation); + } + cursor_move_unprivileged(schematics_win, old_pos.y, old_pos.x); return ; } @@ -153,13 +155,34 @@ t_symbol seg_connects_to_symbol(t_bitflag connects) } } +int is_in_viewport(t_schem_win schematics_win, t_position position) +{ + return (! + ( position.x < schematics_win.view_pos.x + || position.x > schematics_win.view_pos.x + schematics_win.view_size.x - 1 + || position.y < schematics_win.view_pos.y + || position.y > schematics_win.view_pos.y + schematics_win.view_size.y - 1)); +} + +void draw_symbol(t_schem_win schematics_win, t_position position, t_symbol symbol) +{ + if (is_in_viewport(schematics_win, position)) + { + mvwaddch(schematics_win.win, + position.y - schematics_win.view_pos.y, + position.x - schematics_win.view_pos.x, + symbol); + } + return ; +} + void schema_draw_segment(t_schem_win schematics_win, const t_node_segment *segment) { t_symbol symbol; symbol = seg_connects_to_symbol(segment->connects); if (symbol != '\0') - mvwaddch(schematics_win.win, segment->position.y, segment->position.x, symbol); + draw_symbol(schematics_win, segment->position, symbol); return ; } @@ -238,7 +261,9 @@ int refresh_schema_win(t_schem_win schematics_win, t_vec *nodes, t_vec *mosfets) size_t i; const t_mosfet *mosfet; const t_node *node; + t_position pos; + pos = get_cursor_pos(schematics_win); werase(schematics_win.win); i = 0; while (i < mosfets->size) @@ -254,6 +279,7 @@ int refresh_schema_win(t_schem_win schematics_win, t_vec *nodes, t_vec *mosfets) schema_draw_node(schematics_win, node); ++i; } + cursor_move_unprivileged(schematics_win, pos.y, pos.x); wrefresh(schematics_win.win); return (1); } diff --git a/src/main.c b/src/main.c index 4d044ab..1f8340b 100644 --- a/src/main.c +++ b/src/main.c @@ -231,6 +231,12 @@ int construct_input(t_input *input, char **split_inp) return (1); } +void get_viewport_size(t_schem_win *schematics_win) +{ + getmaxyx(schematics_win->win, schematics_win->view_size.y, schematics_win->view_size.x); + return ; +} + int process_input(t_windows *windows, t_vec *nodes, t_vec *mosfets) { int res; @@ -238,6 +244,7 @@ int process_input(t_windows *windows, t_vec *nodes, t_vec *mosfets) if (!get_input(windows->command_win, &input)) return (1); + get_viewport_size(&windows->schematics_win); res = 1; if (input.command == next) { diff --git a/src/schema_mode.c b/src/schema_mode.c index 4a677c9..cf7a7ab 100644 --- a/src/schema_mode.c +++ b/src/schema_mode.c @@ -127,8 +127,8 @@ void schema_add_mosfet(t_schem_win schematics_win, t_vec *nodes, t_vec *mosfets, if (ch == 'r' || ch == 'R') { gate_pos = pos_add(mosfet->position, mosfet_channel_rel_pos(mosfet)); - mvwaddch(schematics_win.win, gate_pos.y, gate_pos.x, ' '); - wmove(schematics_win.win, mosfet->position.y, mosfet->position.x); + draw_symbol(schematics_win, gate_pos, ' '); + cursor_move_unprivileged(schematics_win, mosfet->position.y, mosfet->position.x); } if (ch == 't' && mosfet->type == p) mosfet->type = n; @@ -143,7 +143,7 @@ void schema_add_mosfet(t_schem_win schematics_win, t_vec *nodes, t_vec *mosfets, add_terminal_node(schematics_win, nodes, mosfet, source); add_terminal_node(schematics_win, nodes, mosfet, gate); add_terminal_node(schematics_win, nodes, mosfet, drain); - wmove(schematics_win.win, mosfet->position.y, mosfet->position.x); + cursor_move_unprivileged(schematics_win, mosfet->position.y, mosfet->position.x); ungetch(ch); return ; } @@ -192,7 +192,7 @@ int place_segment(t_schem_win *schematics_win, t_node *node, t_node_segment *pre char ch; t_node_segment tmp; - wmove(schematics_win->win, prediction->position.y, prediction->position.x); + cursor_move(schematics_win, prediction->position.y, prediction->position.x); ch = wgetch(schematics_win->win); tmp = *prediction; if (ch == 'l') @@ -291,7 +291,10 @@ void schema_user_draw_node(t_schem_win *schematics_win, t_vec *nodes, t_vec *mos ft_vec_find_index(&chosen_node->segments, &seg, &index, cmp_seg); ft_vec_erase(&chosen_node->segments, index, NULL); } - while (!place_segment(schematics_win, chosen_node, &seg)); + while (!place_segment(schematics_win, chosen_node, &seg)) + { + refresh_schema_win(*schematics_win, nodes, mosfets); + } if (chosen_node->segments.size == 0) { remove_node(nodes, chosen_node); @@ -317,7 +320,7 @@ void schema_user_draw_node(t_schem_win *schematics_win, t_vec *nodes, t_vec *mos } merge_overlapping_segments(chosen_node); schema_draw_node(*schematics_win, chosen_node); - wmove(schematics_win->win, seg.position.y, seg.position.x); + cursor_move_unprivileged(*schematics_win, seg.position.y, seg.position.x); return ; } @@ -334,7 +337,6 @@ void schema_switch_node(t_schem_win schematics_win, t_vec *nodes, t_vec *mosfets ++chosen_node->set_state; update_nodes(nodes, mosfets); refresh_schema_win(schematics_win, nodes, mosfets); - wmove(schematics_win.win, pos.y, pos.x); return ; } @@ -351,32 +353,74 @@ void schema_reverse_switch_node(t_schem_win schematics_win, t_vec *nodes, t_vec --chosen_node->set_state; update_nodes(nodes, mosfets); refresh_schema_win(schematics_win, nodes, mosfets); - wmove(schematics_win.win, pos.y, pos.x); return ; } -int schema_next(t_schem_win schematics_win, t_vec *nodes, t_vec *mosfets, t_position pos) +int schema_next(t_schem_win schematics_win, t_vec *nodes, t_vec *mosfets) { if (sim_step(nodes, mosfets)) return (1); refresh_schema_win(schematics_win, nodes, mosfets); - wmove(schematics_win.win, pos.y, pos.x); return (0); } +t_position get_cursor_pos(t_schem_win schematics_win) +{ + t_position pos; + + getyx(schematics_win.win, pos.y, pos.x); + pos.y += schematics_win.view_pos.y; + pos.x += schematics_win.view_pos.x; + return (pos); +} + +int cursor_move(t_schem_win *schematics_win, long y, long x) +{ + t_position cursor_pos; + + if (is_in_viewport(*schematics_win, (t_position){.x = x, .y = y})) + { + y -= schematics_win->view_pos.y; + x -= schematics_win->view_pos.x; + wmove(schematics_win->win, y, x); + return (0); + } + else + { + cursor_pos = get_cursor_pos(*schematics_win); + schematics_win->view_pos.y += y - cursor_pos.y; + schematics_win->view_pos.x += x - cursor_pos.x; + return (1); + } +} + +int cursor_move_unprivileged(t_schem_win schematics_win, long y, long x) +{ + if (is_in_viewport(schematics_win, (t_position){.x = x, .y = y})) + { + y -= schematics_win.view_pos.y; + x -= schematics_win.view_pos.x; + wmove(schematics_win.win, y, x); + return (0); + } + return (1);; +} + int handle_key_press(int ch, t_schem_win *schematics_win, t_vec *nodes, t_vec *mosfets) { t_position pos; + int viewport_moved; - getyx(schematics_win->win, pos.y, pos.x); + viewport_moved = 0; + pos = get_cursor_pos(*schematics_win); if (ch == 'h') - wmove(schematics_win->win, pos.y, --pos.x); + viewport_moved = cursor_move(schematics_win, pos.y, --pos.x); else if (ch == 'l') - wmove(schematics_win->win, pos.y, ++pos.x); + viewport_moved = cursor_move(schematics_win, pos.y, ++pos.x); else if (ch == 'j') - wmove(schematics_win->win, ++pos.y, pos.x); + viewport_moved = cursor_move(schematics_win, ++pos.y, pos.x); else if (ch == 'k') - wmove(schematics_win->win, --pos.y, pos.x); + viewport_moved = cursor_move(schematics_win, --pos.y, pos.x); else if (ch == 't') schema_add_mosfet(*schematics_win, nodes, mosfets, pos); else if (ch == 'c') @@ -386,7 +430,11 @@ int handle_key_press(int ch, t_schem_win *schematics_win, t_vec *nodes, t_vec *m else if (ch == 'S') schema_reverse_switch_node(*schematics_win, nodes, mosfets, pos); else if (ch == 'n') - schema_next(*schematics_win, nodes, mosfets, pos); + schema_next(*schematics_win, nodes, mosfets); + if (viewport_moved) + { + refresh_schema_win(*schematics_win, nodes, mosfets); + } return (0); } @@ -400,6 +448,7 @@ int schema_loop(t_schem_win *schematics_win, t_vec *nodes, t_vec *mosfets) ch = wgetch(schematics_win->win); while (ch != 27) { + get_viewport_size(schematics_win); res = handle_key_press(ch, schematics_win, nodes, mosfets); if (res) return (res); diff --git a/src/terminal.c b/src/terminal.c index c34f350..c54e7bc 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -13,8 +13,9 @@ void setup_terminal(t_windows *windows) windows->command_win = newwin(0, COMMAND_WIN_COLS, 0, COLS - COMMAND_WIN_COLS); windows->schematics_win.win = newwin(0, COLS - COMMAND_WIN_COLS - 2, 0, 0); windows->schematics_win.view_pos = (t_position){.x = 0, .y = 0}; + get_viewport_size(&windows->schematics_win); windows->border_win = newwin(0, 1, 0, COLS - COMMAND_WIN_COLS - 1); - wmove(windows->schematics_win.win, LINES / 2, (COLS - COMMAND_WIN_COLS - 2) / 2); + wmove(windows->schematics_win.win, windows->schematics_win.view_size.y / 2, windows->schematics_win.view_size.x / 2 ); set_escdelay(50); keypad(windows->command_win, TRUE); keypad(windows->schematics_win.win, TRUE);