💾 Archived View for gemini.rmf-dev.com › repo › Vaati › mz › files › 536a4926139b32ef41e2bcc778d5dfd… captured on 2023-03-20 at 18:36:22. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
0 /*
1 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
2 *
3 * Permission to use, copy, modify, and distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 */
15 #ifdef __linux__
16 #define _GNU_SOURCE
17 #else
18 #define _BSD_SOURCE
19 #endif
20 #include <dirent.h>
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdint.h>
27 #include <unistd.h>
28 #include "termbox.h"
29 #include "client.h"
30 #include "view.h"
31 #include "file.h"
32 #include "util.h"
33 #include "strlcpy.h"
34 #include "utf8.h"
35
36 struct view *view_init(const char *path) {
37 struct view *view = malloc(sizeof(struct view));
38 file_init(view, path);
39 return view;
40 }
41
42 void view_open(struct view *view) {
43
44 char buf[2048];
45
46 if (view->length < 1)
47 return;
48
49 client.error = 0;
50 switch (view->entries[view->selected].type) {
51 case DT_REG:
52 chdir(view->path);
53 if ((size_t)snprintf(V(buf), "xdg-open \"%s\" >/dev/null 2>&1 &",
54 view->entries[view->selected].name) >= sizeof(buf)) {
55 sstrcpy(client.info, "path too long");
56 client.error = 1;
57 break;
58 }
59 system(buf);
60 break;
61 case DT_DIR:
62 if (file_cd(view, view->entries[view->selected].name)) {
63 sstrcpy(client.info, strerror(errno));
64 client.error = 1;
65 break;
66 }
67 file_ls(view);
68 break;
69 }
70 }
71
72 void view_draw(struct view *view) {
73
74 size_t i = 0, start = TABS;
75
76 if (view->selected + 1 > view->scroll + HEIGHT)
77 view->scroll = view->selected - HEIGHT;
78 if (view->selected < view->scroll)
79 view->scroll = view->selected;
80
81 while (i + view->scroll < view->length) {
82 int selected;
83 struct entry *e;
84 uintattr_t fg, bg;
85
86 if (i > HEIGHT)
87 break;
88
89 fg = bg = TB_DEFAULT;
90
91 selected = view->selected == i + view->scroll;
92 e = &view->entries[i + view->scroll];
93 if (selected) {
94 fg = TB_WHITE;
95 bg = TB_CYAN;
96 }
97 if (e->type == DT_DIR)
98 fg = selected ? TB_BLACK : TB_CYAN;
99 if (e->selected)
100 bg = TB_CYAN;
101 if (e->selected && fg == TB_CYAN)
102 fg = TB_WHITE;
103 if (e->selected && selected)
104 fg = e->type == DT_REG ? TB_BLACK : TB_GREEN;
105 tb_print(0, i + start, fg, bg, e->name);
106 if (e->type == DT_DIR) {
107 tb_set_cell(utf8_width(e->name, PATH_MAX), i + start,
108 '/', fg, bg);
109 }
110 i++;
111 }
112 }
113
114 void view_select(struct view *view, const char *name) {
115 file_select(view, name);
116 if (view->length < HEIGHT) return;
117 if (view->selected >= view->length - HEIGHT / 2) {
118 view->scroll = view->length - HEIGHT - 1;
119 } else if (view->selected > HEIGHT / 2) {
120 view->scroll = view->selected - HEIGHT / 2;
121 }
122 }
123
124 void view_unselect(struct view *view) {
125 size_t i = 0;
126 while (i < view->length) {
127 view->entries[i].selected = 0;
128 i++;
129 }
130 }
131