source: mainline/uspace/app/nav/nav.c@ 8edec53

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8edec53 was 8edec53, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Support double-click

Needed to open Navigator entries using the mouse.

  • Property mode set to 100644
File size: 8.0 KB
RevLine 
[748c8bd]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>
[5d466a1]39#include <stdlib.h>
[748c8bd]40#include <str.h>
41#include <ui/fixed.h>
42#include <ui/resource.h>
43#include <ui/ui.h>
44#include <ui/window.h>
[5d466a1]45#include "menu.h"
[748c8bd]46#include "nav.h"
[b36ebb42]47#include "panel.h"
[748c8bd]48
49static void wnd_close(ui_window_t *, void *);
[9f7e9bb]50static void wnd_kbd(ui_window_t *, void *, kbd_event_t *);
[748c8bd]51
52static ui_window_cb_t window_cb = {
[9f7e9bb]53 .close = wnd_close,
54 .kbd = wnd_kbd
[748c8bd]55};
56
[f59212cc]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
[39ab17c]65static void navigator_panel_activate_req(void *, panel_t *);
66
67static panel_cb_t navigator_panel_cb = {
68 .activate_req = navigator_panel_activate_req
69};
70
[748c8bd]71/** Window close button was clicked.
72 *
73 * @param window Window
74 * @param arg Argument (navigator)
75 */
76static void wnd_close(ui_window_t *window, void *arg)
77{
78 navigator_t *navigator = (navigator_t *) arg;
79
80 ui_quit(navigator->ui);
81}
82
[9f7e9bb]83/** Window keyboard event handler.
84 *
85 * @param window Window
86 * @param arg Argument (navigator)
87 * @param event Keyboard event
88 */
89static void wnd_kbd(ui_window_t *window, void *arg, kbd_event_t *event)
90{
91 navigator_t *navigator = (navigator_t *) arg;
92
93 if (event->type == KEY_PRESS &&
94 ((event->mods & KM_ALT) == 0) &&
95 ((event->mods & KM_SHIFT) == 0) &&
96 (event->mods & KM_CTRL) != 0) {
[692c7f40]97 switch (event->key) {
98 case KC_Q:
[9f7e9bb]99 ui_quit(navigator->ui);
[692c7f40]100 break;
101 default:
102 break;
103 }
104 }
105
106 if (event->type == KEY_PRESS &&
107 ((event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0)) {
108 switch (event->key) {
109 case KC_TAB:
110 navigator_switch_panel(navigator);
111 break;
112 default:
113 break;
114 }
[9f7e9bb]115 }
116
117 ui_window_def_kbd(window, event);
118}
119
[5d466a1]120/** Create navigator.
121 *
122 * @param display_spec Display specification
123 * @param rnavigator Place to store pointer to new navigator
124 * @return EOK on success or ane error code
125 */
[6aa85c1]126errno_t navigator_create(const char *display_spec,
[5d466a1]127 navigator_t **rnavigator)
[748c8bd]128{
[5d466a1]129 navigator_t *navigator;
[748c8bd]130 ui_wnd_params_t params;
[b36ebb42]131 gfx_rect_t rect;
[8edec53]132 gfx_rect_t arect;
133 gfx_coord_t pw;
[b36ebb42]134 unsigned i;
[748c8bd]135 errno_t rc;
136
[5d466a1]137 navigator = calloc(1, sizeof(navigator_t));
138 if (navigator == NULL)
139 return ENOMEM;
140
141 rc = ui_create(display_spec, &navigator->ui);
[748c8bd]142 if (rc != EOK) {
143 printf("Error creating UI on display %s.\n", display_spec);
[5d466a1]144 goto error;
[748c8bd]145 }
146
147 ui_wnd_params_init(&params);
148 params.caption = "Navigator";
[5d466a1]149 params.style &= ~ui_wds_decorated;
150 params.placement = ui_wnd_place_full_screen;
[748c8bd]151
[5d466a1]152 rc = ui_window_create(navigator->ui, &params, &navigator->window);
[748c8bd]153 if (rc != EOK) {
154 printf("Error creating window.\n");
[5d466a1]155 goto error;
[748c8bd]156 }
157
[5d466a1]158 ui_window_set_cb(navigator->window, &window_cb, (void *) navigator);
[8edec53]159 ui_window_get_app_rect(navigator->window, &arect);
[748c8bd]160
[5d466a1]161 rc = ui_fixed_create(&navigator->fixed);
[748c8bd]162 if (rc != EOK) {
163 printf("Error creating fixed layout.\n");
[5d466a1]164 goto error;
[748c8bd]165 }
166
[5d466a1]167 ui_window_add(navigator->window, ui_fixed_ctl(navigator->fixed));
[748c8bd]168
[6aa85c1]169 rc = nav_menu_create(navigator->window, &navigator->menu);
[5d466a1]170 if (rc != EOK)
171 goto error;
[748c8bd]172
[f59212cc]173 nav_menu_set_cb(navigator->menu, &navigator_menu_cb,
174 (void *)navigator);
175
[6aa85c1]176 rc = ui_fixed_add(navigator->fixed, nav_menu_ctl(navigator->menu));
177 if (rc != EOK) {
178 printf("Error adding control to layout.\n");
179 return rc;
180 }
181
[8edec53]182 /* Panel width */
183 pw = (arect.p1.x - arect.p0.x) / 2;
184
[b36ebb42]185 for (i = 0; i < 2; i++) {
[692c7f40]186 rc = panel_create(navigator->window, i == 0,
187 &navigator->panel[i]);
[b36ebb42]188 if (rc != EOK)
189 goto error;
190
[8edec53]191 rect.p0.x = arect.p0.x + pw * i;
192 rect.p0.y = arect.p0.y + 1;
193 rect.p1.x = arect.p0.x + pw * (i + 1);
194 rect.p1.y = arect.p1.y - 1;
[b36ebb42]195 panel_set_rect(navigator->panel[i], &rect);
196
[39ab17c]197 panel_set_cb(navigator->panel[i], &navigator_panel_cb,
198 navigator);
199
[b36ebb42]200 rc = ui_fixed_add(navigator->fixed,
201 panel_ctl(navigator->panel[i]));
202 if (rc != EOK) {
203 printf("Error adding control to layout.\n");
[0e80e40]204 goto error;
205 }
206
207 rc = panel_read_dir(navigator->panel[i], ".");
208 if (rc != EOK) {
209 printf("Error reading directory.\n");
210 goto error;
[b36ebb42]211 }
212 }
213
[5d466a1]214 rc = ui_window_paint(navigator->window);
[748c8bd]215 if (rc != EOK) {
[5d466a1]216 printf("Error painting window.\n");
217 goto error;
[748c8bd]218 }
219
[5d466a1]220 *rnavigator = navigator;
221 return EOK;
222error:
223 navigator_destroy(navigator);
224 return rc;
225}
[748c8bd]226
[6aa85c1]227void navigator_destroy(navigator_t *navigator)
[5d466a1]228{
[b36ebb42]229 unsigned i;
230
231 for (i = 0; i < 2; i++) {
232 ui_fixed_remove(navigator->fixed,
233 panel_ctl(navigator->panel[i]));
234 panel_destroy(navigator->panel[i]);
235 }
236
[6aa85c1]237 ui_fixed_remove(navigator->fixed, nav_menu_ctl(navigator->menu));
238
[5d466a1]239 if (navigator->menu != NULL)
240 nav_menu_destroy(navigator->menu);
241 if (navigator->window != NULL)
242 ui_window_destroy(navigator->window);
243 if (navigator->ui != NULL)
244 ui_destroy(navigator->ui);
245 free(navigator);
246}
247
248/** Run navigator on the specified display. */
[6aa85c1]249errno_t navigator_run(const char *display_spec)
[5d466a1]250{
251 navigator_t *navigator;
252 errno_t rc;
[748c8bd]253
[5d466a1]254 rc = navigator_create(display_spec, &navigator);
255 if (rc != EOK)
256 return rc;
[748c8bd]257
[5d466a1]258 ui_run(navigator->ui);
[748c8bd]259
[5d466a1]260 navigator_destroy(navigator);
[748c8bd]261 return EOK;
262}
263
[692c7f40]264/** Get the currently active navigator panel.
265 *
266 * @param navigator Navigator
267 * @return Currently active panel
268 */
269panel_t *navigator_get_active_panel(navigator_t *navigator)
270{
271 int i;
272
273 for (i = 0; i < navigator_panels; i++) {
274 if (panel_is_active(navigator->panel[i]))
275 return navigator->panel[i];
276 }
277
278 /* This should not happen */
279 assert(false);
280 return NULL;
281}
282
283/** Switch to another navigator panel.
284 *
285 * Changes the currently active navigator panel to the next panel.
286 *
287 * @param navigator Navigator
288 */
289void navigator_switch_panel(navigator_t *navigator)
290{
[4fcc2de]291 errno_t rc;
292
[692c7f40]293 if (panel_is_active(navigator->panel[0])) {
[4fcc2de]294 rc = panel_activate(navigator->panel[1]);
295 if (rc != EOK)
296 return;
[692c7f40]297 panel_deactivate(navigator->panel[0]);
298 } else {
[4fcc2de]299 rc = panel_activate(navigator->panel[0]);
300 if (rc != EOK)
301 return;
[692c7f40]302 panel_deactivate(navigator->panel[1]);
303 }
304}
305
[f59212cc]306/** File / Open menu entry selected */
307static void navigator_file_open(void *arg)
308{
309 navigator_t *navigator = (navigator_t *)arg;
310 panel_t *panel;
311
312 panel = navigator_get_active_panel(navigator);
313 panel_open(panel, panel->cursor);
314}
315
316/** File / Exit menu entry selected */
317static void navigator_file_exit(void *arg)
318{
319 navigator_t *navigator = (navigator_t *)arg;
320
321 ui_quit(navigator->ui);
322}
323
[39ab17c]324/** Panel callback requesting panel activation.
325 *
326 * @param arg Argument (navigator_t *)
327 * @param panel Panel
328 */
329void navigator_panel_activate_req(void *arg, panel_t *panel)
330{
331 navigator_t *navigator = (navigator_t *)arg;
332
333 if (!panel_is_active(panel))
334 navigator_switch_panel(navigator);
335}
336
[748c8bd]337/** @}
338 */
Note: See TracBrowser for help on using the repository browser.