2 * Copyright (c) 2023 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.
32 /** @file Navigator panel.
34 * Displays a file listing.
38 #include <gfx/render.h>
42 #include <ui/control.h>
43 #include <ui/filelist.h>
45 #include <ui/resource.h>
49 static void panel_ctl_destroy(void *);
50 static errno_t
panel_ctl_paint(void *);
51 static ui_evclaim_t
panel_ctl_kbd_event(void *, kbd_event_t
*);
52 static ui_evclaim_t
panel_ctl_pos_event(void *, pos_event_t
*);
54 /** Panel control ops */
55 static ui_control_ops_t panel_ctl_ops
= {
56 .destroy
= panel_ctl_destroy
,
57 .paint
= panel_ctl_paint
,
58 .kbd_event
= panel_ctl_kbd_event
,
59 .pos_event
= panel_ctl_pos_event
62 static void panel_flist_activate_req(ui_file_list_t
*, void *);
63 static void panel_flist_selected(ui_file_list_t
*, void *, const char *);
65 /** Panel file list callbacks */
66 static ui_file_list_cb_t panel_flist_cb
= {
67 .activate_req
= panel_flist_activate_req
,
68 .selected
= panel_flist_selected
,
73 * @param window Containing window
74 * @param active @c true iff panel should be active
75 * @param rpanel Place to store pointer to new panel
76 * @return EOK on success or an error code
78 errno_t
panel_create(ui_window_t
*window
, bool active
, panel_t
**rpanel
)
83 panel
= calloc(1, sizeof(panel_t
));
87 rc
= ui_control_new(&panel_ctl_ops
, (void *)panel
,
94 rc
= gfx_color_new_ega(0x07, &panel
->color
);
98 rc
= gfx_color_new_ega(0x0f, &panel
->act_border_color
);
102 rc
= ui_file_list_create(window
, active
, &panel
->flist
);
106 ui_file_list_set_cb(panel
->flist
, &panel_flist_cb
, (void *)panel
);
108 panel
->window
= window
;
109 panel
->active
= active
;
113 if (panel
->color
!= NULL
)
114 gfx_color_delete(panel
->color
);
115 if (panel
->act_border_color
!= NULL
)
116 gfx_color_delete(panel
->act_border_color
);
117 if (panel
->flist
!= NULL
)
118 ui_file_list_destroy(panel
->flist
);
119 ui_control_delete(panel
->control
);
128 void panel_destroy(panel_t
*panel
)
130 gfx_color_delete(panel
->color
);
131 gfx_color_delete(panel
->act_border_color
);
132 ui_control_delete(panel
->control
);
136 /** Set panel callbacks.
139 * @param cb Callbacks
140 * @param arg Argument to callback functions
142 void panel_set_cb(panel_t
*panel
, panel_cb_t
*cb
, void *arg
)
152 errno_t
panel_paint(panel_t
*panel
)
154 gfx_context_t
*gc
= ui_window_get_gc(panel
->window
);
155 ui_resource_t
*res
= ui_window_get_res(panel
->window
);
156 ui_box_style_t bstyle
;
161 rc
= gfx_set_color(gc
, panel
->color
);
165 rc
= gfx_fill_rect(gc
, &panel
->rect
);
170 bstyle
= ui_box_double
;
171 bcolor
= panel
->act_border_color
;
173 bstyle
= ui_box_single
;
174 bcolor
= panel
->color
;
177 rc
= ui_paint_text_box(res
, &panel
->rect
, bstyle
, bcolor
);
181 ctl
= ui_file_list_ctl(panel
->flist
);
182 rc
= ui_control_paint(ctl
);
193 /** Handle panel keyboard event.
196 * @param event Keyboard event
197 * @return ui_claimed iff event was claimed
199 ui_evclaim_t
panel_kbd_event(panel_t
*panel
, kbd_event_t
*event
)
206 ctl
= ui_file_list_ctl(panel
->flist
);
207 return ui_control_kbd_event(ctl
, event
);
210 /** Handle panel position event.
213 * @param event Position event
214 * @return ui_claimed iff event was claimed
216 ui_evclaim_t
panel_pos_event(panel_t
*panel
, pos_event_t
*event
)
224 if (!gfx_pix_inside_rect(&pos
, &panel
->rect
))
227 ctl
= ui_file_list_ctl(panel
->flist
);
228 claim
= ui_control_pos_event(ctl
, event
);
229 if (claim
== ui_claimed
)
232 if (!panel
->active
&& event
->type
== POS_PRESS
)
233 panel_activate_req(panel
);
238 /** Get base control for panel.
241 * @return Base UI control
243 ui_control_t
*panel_ctl(panel_t
*panel
)
245 return panel
->control
;
248 /** Set panel rectangle.
251 * @param rect Rectangle
253 void panel_set_rect(panel_t
*panel
, gfx_rect_t
*rect
)
259 irect
.p0
.x
= panel
->rect
.p0
.x
+ 1;
260 irect
.p0
.y
= panel
->rect
.p0
.y
+ 1;
261 irect
.p1
.x
= panel
->rect
.p1
.x
;
262 irect
.p1
.y
= panel
->rect
.p1
.y
- 1;
264 ui_file_list_set_rect(panel
->flist
, &irect
);
267 /** Determine if panel is active.
270 * @return @c true iff panel is active
272 bool panel_is_active(panel_t
*panel
)
274 return panel
->active
;
281 * @return EOK on success or an error code
283 errno_t
panel_activate(panel_t
*panel
)
287 rc
= ui_file_list_activate(panel
->flist
);
291 panel
->active
= true;
292 (void) panel_paint(panel
);
296 /** Deactivate panel.
300 void panel_deactivate(panel_t
*panel
)
302 ui_file_list_deactivate(panel
->flist
);
303 panel
->active
= false;
304 (void) panel_paint(panel
);
307 /** Destroy panel control.
309 * @param arg Argument (panel_t *)
311 void panel_ctl_destroy(void *arg
)
313 panel_t
*panel
= (panel_t
*) arg
;
315 panel_destroy(panel
);
318 /** Paint panel control.
320 * @param arg Argument (panel_t *)
321 * @return EOK on success or an error code
323 errno_t
panel_ctl_paint(void *arg
)
325 panel_t
*panel
= (panel_t
*) arg
;
327 return panel_paint(panel
);
330 /** Handle panel control keyboard event.
332 * @param arg Argument (panel_t *)
333 * @param kbd_event Keyboard event
334 * @return @c ui_claimed iff the event is claimed
336 ui_evclaim_t
panel_ctl_kbd_event(void *arg
, kbd_event_t
*event
)
338 panel_t
*panel
= (panel_t
*) arg
;
340 return panel_kbd_event(panel
, event
);
343 /** Handle panel control position event.
345 * @param arg Argument (panel_t *)
346 * @param pos_event Position event
347 * @return @c ui_claimed iff the event is claimed
349 ui_evclaim_t
panel_ctl_pos_event(void *arg
, pos_event_t
*event
)
351 panel_t
*panel
= (panel_t
*) arg
;
353 return panel_pos_event(panel
, event
);
356 /** Read directory into panel entry list.
359 * @param dirname Directory path
360 * @return EOK on success or an error code
362 errno_t
panel_read_dir(panel_t
*panel
, const char *dirname
)
364 return ui_file_list_read_dir(panel
->flist
, dirname
);
367 /** Request panel activation.
369 * Call back to request panel activation.
373 void panel_activate_req(panel_t
*panel
)
375 if (panel
->cb
!= NULL
&& panel
->cb
->activate_req
!= NULL
)
376 panel
->cb
->activate_req(panel
->cb_arg
, panel
);
379 /** Open panel file entry.
381 * Perform Open action on a file entry (i.e. try running it).
384 * @param fname File name
386 * @return EOK on success or an error code
388 static errno_t
panel_open_file(panel_t
*panel
, const char *fname
)
397 ui
= ui_window_get_ui(panel
->window
);
399 /* Free up and clean console for the child task. */
404 rc
= task_spawnl(&id
, &wait
, fname
, fname
, NULL
);
408 rc
= task_wait(&wait
, &texit
, &retval
);
409 if ((rc
!= EOK
) || (texit
!= TASK_EXIT_NORMAL
))
412 /* Resume UI operation */
417 (void) ui_paint(ui_window_get_ui(panel
->window
));
420 (void) ui_resume(ui
);
421 (void) ui_paint(ui_window_get_ui(panel
->window
));
425 /** File list in panel requests activation.
427 * @param flist File list
428 * @param arg Argument (panel_t *)
430 static void panel_flist_activate_req(ui_file_list_t
*flist
, void *arg
)
432 panel_t
*panel
= (panel_t
*)arg
;
434 panel_activate_req(panel
);
437 /** File in panel file list was selected.
439 * @param flist File list
440 * @param arg Argument (panel_t *)
441 * @param fname File name
443 static void panel_flist_selected(ui_file_list_t
*flist
, void *arg
,
446 panel_t
*panel
= (panel_t
*)arg
;
448 (void) panel_open_file(panel
, fname
);