2 * Copyright (c) 2022 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
34 * HelenOS file manager.
37 #include <gfx/coord.h>
42 #include <ui/filelist.h>
43 #include <ui/resource.h>
45 #include <ui/window.h>
50 static void wnd_close(ui_window_t
*, void *);
51 static void wnd_kbd(ui_window_t
*, void *, kbd_event_t
*);
53 static ui_window_cb_t window_cb
= {
58 static void navigator_file_open(void *);
59 static void navigator_file_exit(void *);
61 static nav_menu_cb_t navigator_menu_cb
= {
62 .file_open
= navigator_file_open
,
63 .file_exit
= navigator_file_exit
66 static void navigator_panel_activate_req(void *, panel_t
*);
68 static panel_cb_t navigator_panel_cb
= {
69 .activate_req
= navigator_panel_activate_req
72 /** Window close button was clicked.
74 * @param window Window
75 * @param arg Argument (navigator)
77 static void wnd_close(ui_window_t
*window
, void *arg
)
79 navigator_t
*navigator
= (navigator_t
*) arg
;
81 ui_quit(navigator
->ui
);
84 /** Window keyboard event handler.
86 * @param window Window
87 * @param arg Argument (navigator)
88 * @param event Keyboard event
90 static void wnd_kbd(ui_window_t
*window
, void *arg
, kbd_event_t
*event
)
92 navigator_t
*navigator
= (navigator_t
*) arg
;
94 if (event
->type
== KEY_PRESS
&&
95 ((event
->mods
& KM_ALT
) == 0) &&
96 ((event
->mods
& KM_SHIFT
) == 0) &&
97 (event
->mods
& KM_CTRL
) != 0) {
100 ui_quit(navigator
->ui
);
107 if (event
->type
== KEY_PRESS
&&
108 ((event
->mods
& (KM_CTRL
| KM_ALT
| KM_SHIFT
)) == 0)) {
109 switch (event
->key
) {
111 navigator_switch_panel(navigator
);
118 ui_window_def_kbd(window
, event
);
121 /** Create navigator.
123 * @param display_spec Display specification
124 * @param rnavigator Place to store pointer to new navigator
125 * @return EOK on success or ane error code
127 errno_t
navigator_create(const char *display_spec
,
128 navigator_t
**rnavigator
)
130 navigator_t
*navigator
;
131 ui_wnd_params_t params
;
138 navigator
= calloc(1, sizeof(navigator_t
));
139 if (navigator
== NULL
)
142 rc
= ui_create(display_spec
, &navigator
->ui
);
144 printf("Error creating UI on display %s.\n", display_spec
);
148 ui_wnd_params_init(¶ms
);
149 params
.caption
= "Navigator";
150 params
.style
&= ~ui_wds_decorated
;
151 params
.placement
= ui_wnd_place_full_screen
;
153 rc
= ui_window_create(navigator
->ui
, ¶ms
, &navigator
->window
);
155 printf("Error creating window.\n");
159 ui_window_set_cb(navigator
->window
, &window_cb
, (void *) navigator
);
160 ui_window_get_app_rect(navigator
->window
, &arect
);
162 rc
= ui_fixed_create(&navigator
->fixed
);
164 printf("Error creating fixed layout.\n");
168 ui_window_add(navigator
->window
, ui_fixed_ctl(navigator
->fixed
));
170 rc
= nav_menu_create(navigator
->window
, &navigator
->menu
);
174 nav_menu_set_cb(navigator
->menu
, &navigator_menu_cb
,
177 rc
= ui_fixed_add(navigator
->fixed
, nav_menu_ctl(navigator
->menu
));
179 printf("Error adding control to layout.\n");
184 pw
= (arect
.p1
.x
- arect
.p0
.x
) / 2;
186 for (i
= 0; i
< 2; i
++) {
187 rc
= panel_create(navigator
->window
, i
== 0,
188 &navigator
->panel
[i
]);
192 rect
.p0
.x
= arect
.p0
.x
+ pw
* i
;
193 rect
.p0
.y
= arect
.p0
.y
+ 1;
194 rect
.p1
.x
= arect
.p0
.x
+ pw
* (i
+ 1);
195 rect
.p1
.y
= arect
.p1
.y
- 1;
196 panel_set_rect(navigator
->panel
[i
], &rect
);
198 panel_set_cb(navigator
->panel
[i
], &navigator_panel_cb
,
201 rc
= ui_fixed_add(navigator
->fixed
,
202 panel_ctl(navigator
->panel
[i
]));
204 printf("Error adding control to layout.\n");
208 rc
= panel_read_dir(navigator
->panel
[i
], ".");
210 printf("Error reading directory.\n");
215 rc
= ui_window_paint(navigator
->window
);
217 printf("Error painting window.\n");
221 *rnavigator
= navigator
;
224 navigator_destroy(navigator
);
228 void navigator_destroy(navigator_t
*navigator
)
232 for (i
= 0; i
< 2; i
++) {
233 if (navigator
->panel
[i
] != NULL
) {
234 ui_fixed_remove(navigator
->fixed
,
235 panel_ctl(navigator
->panel
[i
]));
236 panel_destroy(navigator
->panel
[i
]);
240 if (navigator
->menu
!= NULL
) {
241 ui_fixed_remove(navigator
->fixed
, nav_menu_ctl(navigator
->menu
));
242 nav_menu_destroy(navigator
->menu
);
245 if (navigator
->window
!= NULL
)
246 ui_window_destroy(navigator
->window
);
247 if (navigator
->ui
!= NULL
)
248 ui_destroy(navigator
->ui
);
252 /** Run navigator on the specified display. */
253 errno_t
navigator_run(const char *display_spec
)
255 navigator_t
*navigator
;
258 rc
= navigator_create(display_spec
, &navigator
);
262 ui_run(navigator
->ui
);
264 navigator_destroy(navigator
);
268 /** Get the currently active navigator panel.
270 * @param navigator Navigator
271 * @return Currently active panel
273 panel_t
*navigator_get_active_panel(navigator_t
*navigator
)
277 for (i
= 0; i
< navigator_panels
; i
++) {
278 if (panel_is_active(navigator
->panel
[i
]))
279 return navigator
->panel
[i
];
282 /* This should not happen */
287 /** Switch to another navigator panel.
289 * Changes the currently active navigator panel to the next panel.
291 * @param navigator Navigator
293 void navigator_switch_panel(navigator_t
*navigator
)
297 if (panel_is_active(navigator
->panel
[0])) {
298 rc
= panel_activate(navigator
->panel
[1]);
301 panel_deactivate(navigator
->panel
[0]);
303 rc
= panel_activate(navigator
->panel
[0]);
306 panel_deactivate(navigator
->panel
[1]);
310 /** File / Open menu entry selected */
311 static void navigator_file_open(void *arg
)
313 navigator_t
*navigator
= (navigator_t
*)arg
;
316 panel
= navigator_get_active_panel(navigator
);
317 ui_file_list_open(panel
->flist
, ui_file_list_get_cursor(panel
->flist
));
320 /** File / Exit menu entry selected */
321 static void navigator_file_exit(void *arg
)
323 navigator_t
*navigator
= (navigator_t
*)arg
;
325 ui_quit(navigator
->ui
);
328 /** Panel callback requesting panel activation.
330 * @param arg Argument (navigator_t *)
333 void navigator_panel_activate_req(void *arg
, panel_t
*panel
)
335 navigator_t
*navigator
= (navigator_t
*)arg
;
337 if (!panel_is_active(panel
))
338 navigator_switch_panel(navigator
);