| 1 | module pane_mod |
| 2 | use terminal_mod |
| 3 | use pty_mod |
| 4 | use parser_mod |
| 5 | implicit none |
| 6 | private |
| 7 | |
| 8 | public :: pane_t |
| 9 | public :: pane_init, pane_destroy |
| 10 | public :: pane_resize, pane_set_viewport |
| 11 | |
| 12 | ! Maximum panes per tab |
| 13 | integer, parameter, public :: MAX_PANES = 16 |
| 14 | |
| 15 | type :: pane_t |
| 16 | type(terminal_t) :: term |
| 17 | type(pty_t) :: pty |
| 18 | type(parser_t) :: parser |
| 19 | |
| 20 | ! Viewport/layout (in pixels) |
| 21 | integer :: x = 0 ! Left edge |
| 22 | integer :: y = 0 ! Top edge |
| 23 | integer :: width = 800 ! Width in pixels |
| 24 | integer :: height = 600 ! Height in pixels |
| 25 | |
| 26 | ! Terminal dimensions (in cells) |
| 27 | integer :: rows = 24 |
| 28 | integer :: cols = 80 |
| 29 | |
| 30 | ! Split tracking for layout recalculation |
| 31 | integer :: split_type = 0 ! 0=none, 1=vertical, 2=horizontal |
| 32 | integer :: parent_idx = 0 ! Index of parent pane (0 if root) |
| 33 | real :: split_ratio = 0.5 ! Position in parent (0.0-1.0) |
| 34 | |
| 35 | logical :: active = .false. |
| 36 | end type pane_t |
| 37 | |
| 38 | contains |
| 39 | |
| 40 | ! Initialize a new pane with terminal, PTY, and parser |
| 41 | subroutine pane_init(pane, rows, cols) |
| 42 | type(pane_t), intent(inout) :: pane |
| 43 | integer, intent(in) :: rows, cols |
| 44 | |
| 45 | pane%rows = rows |
| 46 | pane%cols = cols |
| 47 | |
| 48 | ! Initialize terminal |
| 49 | call terminal_init(pane%term, rows, cols) |
| 50 | |
| 51 | ! Initialize parser |
| 52 | call parser_init(pane%parser) |
| 53 | |
| 54 | ! Open PTY with shell |
| 55 | pane%pty = pty_open("", rows, cols) |
| 56 | |
| 57 | pane%active = .false. |
| 58 | pane%split_type = 0 |
| 59 | pane%parent_idx = 0 |
| 60 | pane%split_ratio = 0.5 |
| 61 | end subroutine pane_init |
| 62 | |
| 63 | ! Destroy a pane and clean up resources |
| 64 | subroutine pane_destroy(pane) |
| 65 | type(pane_t), intent(inout) :: pane |
| 66 | |
| 67 | call pty_close(pane%pty) |
| 68 | call terminal_destroy(pane%term) |
| 69 | |
| 70 | pane%active = .false. |
| 71 | pane%x = 0 |
| 72 | pane%y = 0 |
| 73 | pane%width = 0 |
| 74 | pane%height = 0 |
| 75 | pane%rows = 0 |
| 76 | pane%cols = 0 |
| 77 | end subroutine pane_destroy |
| 78 | |
| 79 | ! Resize a pane's terminal and PTY |
| 80 | subroutine pane_resize(pane, new_rows, new_cols) |
| 81 | type(pane_t), intent(inout) :: pane |
| 82 | integer, intent(in) :: new_rows, new_cols |
| 83 | |
| 84 | if (new_rows /= pane%rows .or. new_cols /= pane%cols) then |
| 85 | pane%rows = new_rows |
| 86 | pane%cols = new_cols |
| 87 | call pty_resize(pane%pty, new_rows, new_cols) |
| 88 | call terminal_resize(pane%term, new_rows, new_cols) |
| 89 | end if |
| 90 | end subroutine pane_resize |
| 91 | |
| 92 | ! Set a pane's viewport and recalculate terminal dimensions |
| 93 | subroutine pane_set_viewport(pane, x, y, w, h, cell_w, cell_h) |
| 94 | type(pane_t), intent(inout) :: pane |
| 95 | integer, intent(in) :: x, y, w, h |
| 96 | integer, intent(in) :: cell_w, cell_h |
| 97 | integer :: new_rows, new_cols |
| 98 | |
| 99 | pane%x = x |
| 100 | pane%y = y |
| 101 | pane%width = w |
| 102 | pane%height = h |
| 103 | |
| 104 | ! Calculate terminal dimensions from pixel size |
| 105 | new_cols = w / cell_w |
| 106 | new_rows = h / cell_h |
| 107 | |
| 108 | ! Ensure minimum dimensions |
| 109 | if (new_cols < 2) new_cols = 2 |
| 110 | if (new_rows < 2) new_rows = 2 |
| 111 | |
| 112 | ! Resize if dimensions changed |
| 113 | call pane_resize(pane, new_rows, new_cols) |
| 114 | end subroutine pane_set_viewport |
| 115 | |
| 116 | end module pane_mod |
| 117 |