]> www.ljiriste.work Git - FET_sim.git/commitdiff
Implement moving around in schematic view
authorLukáš Jiřiště <redacted>
Tue, 11 Aug 2026 15:15:02 +0000 (17:15 +0200)
committerLukáš Jiřiště <redacted>
Tue, 11 Aug 2026 15:16:33 +0000 (17:16 +0200)
inc/FET_sim.h
src/colors.c
src/main.c
src/schema_mode.c
src/terminal.c

index b284b9eeaf2695e19ede6736352437ed6cd6a494..1fc9fa19a93ebee2a399a8294054cd3be3f047ed 100644 (file)
@@ -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);
index 2ce8aadaea5b38f62f3dd1636d05d0d300a084fd..18136b94ef0151118a4c22d3ba665154408eb778 100644 (file)
@@ -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);
 }
index 4d044abec2459c1aab183485a6a20b2f0277da8f..1f8340b0e8bbaef811d2bda6f662a27ac6ad350f 100644 (file)
@@ -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)
        {
index 4a677c9f6b4f7de47d09dcac69742c43033dbf3b..cf7a7abbc50b1a942470a1c199571d66cb401096 100644 (file)
@@ -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);
index c34f350b539ae9a341955f58e5e64cffafd534de..c54e7bcf1ddfbdddab56c207a9148e4d661f2784 100644 (file)
@@ -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);