source: mainline/uspace/app/nav/nav.c@ f59212cc

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f59212cc was f59212cc, checked in by jxsvoboda <5887334+jxsvoboda@…>, 4 years ago

Add File / Open, properly deliver menu events to Navigator

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup nav
30 * @{
31 */
32/** @file Navigator.
33 *
34 * HelenOS file manager.
35 */
36
37#include <gfx/coord.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <str.h>
41#include <ui/fixed.h>
42#include <ui/resource.h>
43#include <ui/ui.h>
44#include <ui/window.h>
45#include "menu.h"
46#include "nav.h"
47#include "panel.h"
48
49static void wnd_close(ui_window_t *, void *);
50static void wnd_kbd(ui_window_t *, void *, kbd_event_t *);
51
52static ui_window_cb_t window_cb = {
53 .close = wnd_close,
54 .kbd = wnd_kbd
55};
56
57static void navigator_file_open(void *);
58static void navigator_file_exit(void *);
59
60static nav_menu_cb_t navigator_menu_cb = {
61 .file_open = navigator_file_open,
62 .file_exit = navigator_file_exit
63};
64
65/** Window close button was clicked.
66 *
67 * @param window Window
68 * @param arg Argument (navigator)
69 */
70static void wnd_close(ui_window_t *window, void *arg)
71{
72 navigator_t *navigator = (navigator_t *) arg;
73
74 ui_quit(navigator->ui);
75}
76
77/** Window keyboard event handler.
78 *
79 * @param window Window
80 * @param arg Argument (navigator)
81 * @param event Keyboard event
82 */
83static void wnd_kbd(ui_window_t *window, void *arg, kbd_event_t *event)
84{
85 navigator_t *navigator = (navigator_t *) arg;
86
87 if (event->type == KEY_PRESS &&
88 ((event->mods & KM_ALT) == 0) &&
89 ((event->mods & KM_SHIFT) == 0) &&
90 (event->mods & KM_CTRL) != 0) {
91 switch (event->key) {
92 case KC_Q:
93 ui_quit(navigator->ui);
94 break;
95 default:
96 break;
97 }
98 }
99
100 if (event->type == KEY_PRESS &&
101 ((event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0)) {
102 switch (event->key) {
103 case KC_TAB:
104 navigator_switch_panel(navigator);
105 break;
106 default:
107 break;
108 }
109 }
110
111 ui_window_def_kbd(window, event);
112}
113
114/** Create navigator.
115 *
116 * @param display_spec Display specification
117 * @param rnavigator Place to store pointer to new navigator
118 * @return EOK on success or ane error code
119 */
120errno_t navigator_create(const char *display_spec,
121 navigator_t **rnavigator)
122{
123 navigator_t *navigator;
124 ui_wnd_params_t params;
125 gfx_rect_t rect;
126 unsigned i;
127 errno_t rc;
128
129 navigator = calloc(1, sizeof(navigator_t));
130 if (navigator == NULL)
131 return ENOMEM;
132
133 rc = ui_create(display_spec, &navigator->ui);
134 if (rc != EOK) {
135 printf("Error creating UI on display %s.\n", display_spec);
136 goto error;
137 }
138
139 ui_wnd_params_init(&params);
140 params.caption = "Navigator";
141 params.style &= ~ui_wds_decorated;
142 params.placement = ui_wnd_place_full_screen;
143
144 rc = ui_window_create(navigator->ui, &params, &navigator->window);
145 if (rc != EOK) {
146 printf("Error creating window.\n");
147 goto error;
148 }
149
150 ui_window_set_cb(navigator->window, &window_cb, (void *) navigator);
151
152 rc = ui_fixed_create(&navigator->fixed);
153 if (rc != EOK) {
154 printf("Error creating fixed layout.\n");
155 goto error;
156 }
157
158 ui_window_add(navigator->window, ui_fixed_ctl(navigator->fixed));
159
160 rc = nav_menu_create(navigator->window, &navigator->menu);
161 if (rc != EOK)
162 goto error;
163
164 nav_menu_set_cb(navigator->menu, &navigator_menu_cb,
165 (void *)navigator);
166
167 rc = ui_fixed_add(navigator->fixed, nav_menu_ctl(navigator->menu));
168 if (rc != EOK) {
169 printf("Error adding control to layout.\n");
170 return rc;
171 }
172
173 for (i = 0; i < 2; i++) {
174 rc = panel_create(navigator->window, i == 0,
175 &navigator->panel[i]);
176 if (rc != EOK)
177 goto error;
178
179 rect.p0.x = 40 * i;
180 rect.p0.y = 1;
181 rect.p1.x = 40 * (i + 1);
182 rect.p1.y = 24;
183 panel_set_rect(navigator->panel[i], &rect);
184
185 rc = ui_fixed_add(navigator->fixed,
186 panel_ctl(navigator->panel[i]));
187 if (rc != EOK) {
188 printf("Error adding control to layout.\n");
189 goto error;
190 }
191
192 rc = panel_read_dir(navigator->panel[i], ".");
193 if (rc != EOK) {
194 printf("Error reading directory.\n");
195 goto error;
196 }
197 }
198
199 rc = ui_window_paint(navigator->window);
200 if (rc != EOK) {
201 printf("Error painting window.\n");
202 goto error;
203 }
204
205 *rnavigator = navigator;
206 return EOK;
207error:
208 navigator_destroy(navigator);
209 return rc;
210}
211
212void navigator_destroy(navigator_t *navigator)
213{
214 unsigned i;
215
216 for (i = 0; i < 2; i++) {
217 ui_fixed_remove(navigator->fixed,
218 panel_ctl(navigator->panel[i]));
219 panel_destroy(navigator->panel[i]);
220 }
221
222 ui_fixed_remove(navigator->fixed, nav_menu_ctl(navigator->menu));
223
224 if (navigator->menu != NULL)
225 nav_menu_destroy(navigator->menu);
226 if (navigator->window != NULL)
227 ui_window_destroy(navigator->window);
228 if (navigator->ui != NULL)
229 ui_destroy(navigator->ui);
230 free(navigator);
231}
232
233/** Run navigator on the specified display. */
234errno_t navigator_run(const char *display_spec)
235{
236 navigator_t *navigator;
237 errno_t rc;
238
239 rc = navigator_create(display_spec, &navigator);
240 if (rc != EOK)
241 return rc;
242
243 ui_run(navigator->ui);
244
245 navigator_destroy(navigator);
246 return EOK;
247}
248
249/** Get the currently active navigator panel.
250 *
251 * @param navigator Navigator
252 * @return Currently active panel
253 */
254panel_t *navigator_get_active_panel(navigator_t *navigator)
255{
256 int i;
257
258 for (i = 0; i < navigator_panels; i++) {
259 if (panel_is_active(navigator->panel[i]))
260 return navigator->panel[i];
261 }
262
263 /* This should not happen */
264 assert(false);
265 return NULL;
266}
267
268/** Switch to another navigator panel.
269 *
270 * Changes the currently active navigator panel to the next panel.
271 *
272 * @param navigator Navigator
273 */
274void navigator_switch_panel(navigator_t *navigator)
275{
276 errno_t rc;
277
278 if (panel_is_active(navigator->panel[0])) {
279 rc = panel_activate(navigator->panel[1]);
280 if (rc != EOK)
281 return;
282 panel_deactivate(navigator->panel[0]);
283 } else {
284 rc = panel_activate(navigator->panel[0]);
285 if (rc != EOK)
286 return;
287 panel_deactivate(navigator->panel[1]);
288 }
289}
290
291/** File / Open menu entry selected */
292static void navigator_file_open(void *arg)
293{
294 navigator_t *navigator = (navigator_t *)arg;
295 panel_t *panel;
296
297 panel = navigator_get_active_panel(navigator);
298 panel_open(panel, panel->cursor);
299}
300
301/** File / Exit menu entry selected */
302static void navigator_file_exit(void *arg)
303{
304 navigator_t *navigator = (navigator_t *)arg;
305
306 ui_quit(navigator->ui);
307}
308
309/** @}
310 */
Note: See TracBrowser for help on using the repository browser.