Fortran · 5860 bytes Raw Blame History
1 module ui_display
2 use iso_fortran_env, only: output_unit
3 use terminal_control
4 use git_ops, only: write_git_indicators
5 use filesystem_ops, only: MAX_PATH, MAX_FILES
6 implicit none
7 private
8
9 public :: draw_interface, get_file_color
10
11 contains
12
13 subroutine draw_interface(r, c, current_dir, current_files, current_is_dir, current_is_exec, &
14 current_is_staged, current_is_unstaged, current_is_untracked, current_count, &
15 parent_files, parent_is_dir, parent_is_exec, parent_count, &
16 selected, parent_selected, scroll_offset, parent_scroll_offset, &
17 in_git_repo, repo_name, branch_name)
18 integer, intent(in) :: r, c, current_count, parent_count, selected, parent_selected
19 integer, intent(in) :: scroll_offset, parent_scroll_offset
20 character(len=*), intent(in) :: current_dir, repo_name, branch_name
21 character(len=*), dimension(*), intent(in) :: current_files, parent_files
22 logical, dimension(*), intent(in) :: current_is_dir, parent_is_dir
23 logical, dimension(*), intent(in) :: current_is_exec, parent_is_exec
24 logical, dimension(*), intent(in) :: current_is_staged, current_is_unstaged, current_is_untracked
25 logical, intent(in) :: in_git_repo
26 integer :: left_w, i, parent_idx, current_idx, vis_h
27 character(len=256) :: fname
28 character(len=20) :: color_code
29
30 left_w = c * 3 / 10
31 vis_h = r - 3 ! Visible height
32
33 ! Header
34 write(output_unit, '(a)') BOLD // "FORTRESS" // RESET // " - " // trim(current_dir)
35
36 ! Files (render based on scroll offsets)
37 do i = 1, vis_h
38 parent_idx = i + parent_scroll_offset
39 current_idx = i + scroll_offset
40
41 ! Parent pane
42 if (parent_idx >= 1 .and. parent_idx <= parent_count) then
43 fname = parent_files(parent_idx)
44 if (parent_is_dir(parent_idx) .and. fname /= "." .and. fname /= "..") then
45 fname = trim(fname) // "/"
46 end if
47
48 ! Get color for parent file
49 color_code = get_file_color(parent_files(parent_idx), parent_is_dir(parent_idx), parent_is_exec(parent_idx))
50
51 if (parent_idx == parent_selected) then
52 write(output_unit, '(a)', advance='no') DIM // BOLD // trim(color_code) // &
53 fname(1:min(len_trim(fname),left_w)) // RESET
54 else
55 write(output_unit, '(a)', advance='no') DIM // trim(color_code) // &
56 fname(1:min(len_trim(fname),left_w)) // RESET
57 end if
58 write(output_unit, '(a)', advance='no') repeat(" ", max(0, left_w - len_trim(fname)))
59 else
60 write(output_unit, '(a)', advance='no') repeat(" ", left_w)
61 end if
62
63 ! Separator
64 write(output_unit, '(a)', advance='no') " │ "
65
66 ! Current pane
67 if (current_idx >= 1 .and. current_idx <= current_count) then
68 fname = current_files(current_idx)
69 if (current_is_dir(current_idx) .and. fname /= "." .and. fname /= "..") then
70 fname = trim(fname) // "/"
71 end if
72
73 ! Get color for current file
74 color_code = get_file_color(current_files(current_idx), current_is_dir(current_idx), current_is_exec(current_idx))
75
76 if (current_idx == selected) then
77 write(output_unit, '(a)', advance='no') REVERSE // trim(color_code) // trim(fname)
78 ! Add git indicators if in repo
79 if (in_git_repo) then
80 call write_git_indicators(current_is_staged(current_idx), &
81 current_is_unstaged(current_idx), &
82 current_is_untracked(current_idx), .true.)
83 end if
84 write(output_unit, '(a)') RESET
85 else
86 write(output_unit, '(a)', advance='no') trim(color_code) // trim(fname)
87 ! Add git indicators if in repo
88 if (in_git_repo) then
89 call write_git_indicators(current_is_staged(current_idx), &
90 current_is_unstaged(current_idx), &
91 current_is_untracked(current_idx), .false.)
92 end if
93 write(output_unit, '(a)') RESET
94 end if
95 else
96 write(output_unit, *)
97 end if
98 end do
99
100 ! Footer
101 if (in_git_repo) then
102 write(output_unit, '(a)') DIM // trim(repo_name) // ":" // trim(branch_name) // " | " // RESET // &
103 DIM // "↑↓:nav →:enter ←:back f:find A:add U:unstage M:commit c:cd q:quit" // RESET
104 else
105 write(output_unit, '(a)') DIM // "↑↓:nav →:enter ←:back f:find c:cd q:quit" // RESET
106 end if
107 end subroutine draw_interface
108
109 function get_file_color(filename, is_dir, is_exec) result(color)
110 character(len=*), intent(in) :: filename
111 logical, intent(in) :: is_dir, is_exec
112 character(len=20) :: color
113
114 ! Directories: Blue and bold
115 if (is_dir) then
116 color = BOLD // BLUE
117 ! Dotfiles: Grey
118 else if (filename(1:1) == '.') then
119 color = GREY
120 ! Executable files: Green
121 else if (is_exec) then
122 color = GREEN
123 ! All other files: White
124 else
125 color = WHITE
126 end if
127 end function get_file_color
128
129 end module ui_display
130