C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
pick_engine.c File Reference

pick from a list of choices More...

#include "common.h"
#include <fcntl.h>
#include <stdbool.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
Include dependency graph for pick_engine.c:

Go to the source code of this file.

Functions

void deselect_object (Pick *pick)
 Deselects the currently selected object in pick window.
void destroy_pick_view (Init *init)
 Destroys pick view, unmaps file buffer, and cleans up resources.
void display_pick_help (Init *init)
 Displays the help screen for the pick interface using view.
void display_pick_page (Pick *pick)
 Displays current page of objects in pick window.
void end_pick_view (Init *)
int exec_objects (Init *init)
 Executes specified command with selected objects as arguments.
int init_pick (Init *init, int argc, char **argv, uint by, uint bx)
 Initializes pick structure and opens pick input file or pipe.
int match_objects (Pick *pick, char *s)
 Displays current page of objects in pick window.
int new_pick_view (Init *init)
 Initializes a new view for displaying file contents in the pick interface.
void new_view_file (Init *init, char *file)
 Initializes a new view for displaying the contents of a specified file in the pick interface.
int open_pick_win (Init *)
int output_objects (Pick *pick)
 Outputs selected objects to specified output file.
int pick_engine (Init *)
void pick_std_chyron (Pick *pick)
 Sets standard chyron key states based on pick structure.
int picker (Init *init, char *field)
 Main loop for handling user input and interactions in the pick interface.
int read_pick_input (Init *init)
 Reads pick input from file pointer and saves objects into pick structure.
int read_theme (Init *)
void remove_right_angle (Pick *)
void reverse_object (Pick *pick)
 Reverses the display of the currently selected object in pick window.
void save_object (Pick *pick, char *s)
 Saves a string as an object in the pick structure.
void toggle_object (Pick *pick)
 Toggles the selection state of the currently selected object in pick window.
void unreverse_object (Pick *pick)
 Unreverses the display of the currently selected object in pick window.

Variables

int calculated_idx
int obj_idx
char const pagers_editors [12][10]
int pg_lines
int pipe_fd [2]
int tbl_col
int tbl_cols
int tbl_line
int tbl_page
int tbl_pages
UiMultiMedia ui_mm

Detailed Description

pick from a list of choices

Author
Bill Waller Copyright (c) 2025 MIT License billx.nosp@m.wall.nosp@m.er@gm.nosp@m.ail..nosp@m.com
Date
2026-02-09

Definition in file pick_engine.c.

Function Documentation

◆ end_pick_view()

void end_pick_view ( Init * )

◆ open_pick_win()

int open_pick_win ( Init * init)

Definition at line 247 of file pick_engine.c.

247 {
248 uint maxy, maxx;
249 uint whitespace_ratio = 15;
250 uint usable_lines;
251 uint pick_ratio = 50;
252 uint tbl_max_cols, pg_max_objs;
253
254 Pick *pick = init->pick;
255 ui_get_screen_size(&maxy, &maxx);
256 // Screen Geometry
257 // Calculate pick window size and position based on terminal size and pick
258 // parameters
259 //
260 // Calculate line usage:
261 if (pick->begy == 0)
262 pick->begy = (maxy * whitespace_ratio) / 200;
263 usable_lines = maxy - (maxy * whitespace_ratio) / 100;
264 usable_lines -= pick->begy;
265 usable_lines -= 5; // Pick overhead lines
266 if (pick->p_view_files) {
267 if (pick->lines == 0) {
268 pick->lines = usable_lines * pick_ratio / 100;
269 usable_lines -= pick->lines;
270 }
271 init->begy = pick->begy + 5 + pick->lines;
272 init->begx = 0;
273 usable_lines -= 3; // View overhead lines
274 init->lines = usable_lines;
275 init->cols = maxx - 2;
276 } else if (pick->lines == 0)
277 pick->lines = usable_lines;
278
279 pick->tbl_col_width = max(pick->tbl_col_width, 4);
280 pick->tbl_col_width = min(pick->tbl_col_width, (maxx - (2 + pick->begx)));
281 pick->m_idx = 0; // master index
282 pick->d_idx = 0; // display index
283 while (pick->m_idx < pick->m_cnt)
284 pick->d_object[pick->d_idx++] = pick->m_object[pick->m_idx++];
285 pick->d_cnt = pick->d_idx;
286 if (pick->d_cnt <= pick->lines) {
287 pick->tbl_lines = pick->d_cnt;
288 pick->lines = pick->d_cnt;
289 pick->tbl_cols = 1;
290 } else {
291 tbl_max_cols = ((maxx - (2 + pick->begx)) / (pick->tbl_col_width + 1));
292 pg_max_objs = pick->lines * tbl_max_cols;
293 if (pick->d_cnt > pg_max_objs)
294 pick->tbl_cols = tbl_max_cols;
295 else
296 pick->tbl_cols = pick->d_cnt / pick->lines;
297 pick->tbl_lines = pick->d_cnt / tbl_max_cols;
298 }
299 pick->tbl_pages = (pick->tbl_lines / (pick->lines - 1)) + 1;
300 // pick->lines = (pick->tbl_lines + pick->tbl_pages - 1) / pick->tbl_pages;
301 pick->tbl_page = 0;
302 // if (pick->begy == 0)
303 // pick->begy = (LINES - pick->lines) / 5;
304 // else if (pick->begy + pick->lines > LINES - 4)
305 // pick->begy = LINES - pick->lines - 2;
306 pick->width = (pick->tbl_col_width + 1) * pick->tbl_cols;
307
308 pick->width = max(pick->width, 60);
309 char tmp_str[MAXLEN];
310
311 int ui_split_win_lines = 2;
312 if (ui_tracked_sfc_split_box(pick->lines, pick->width, ui_split_win_lines, 0, pick->begy, pick->begx, pick->title)) {
313 ssnprintf(tmp_str, MAXLEN - 1, "ui_tracked_sfc_split_box(%d, %d, %d, %d, %d, %d, %s) failed",
314 pick->lines, pick->width, ui_split_win_lines, 0, pick->begy, pick->begx, pick->title);
315 ui_perror(tmp_str);
316 return (1);
317 }
318 pick->surface = ui_surface[sfc_ptr];
319 UiSurface *sfc = pick->surface;
320 ui_setscrreg(sfc, WIN, 0, pick->lines - 1);
321 ui_scrollok(sfc, WIN, true);
322 ui_keypad(sfc, WIN, true);
323 pick->separator_line = pick->lines + 1;
324
325 pick->x = 1;
326
327 pick->chyron = ui_new_chyron(pick->surface, WIN2);
328 ui_set_chyron_key(pick->chyron, 1, _("F1 Help"), UIKEY_F01);
329 ui_set_chyron_key(pick->chyron, 2, _("F9 Cancel"),
330 UIKEY_F09);
331 ui_set_chyron_key(pick->chyron, 3, _("F10 Accept"),
332 UIKEY_F10);
333 ui_set_chyron_key(pick->chyron, 4, _("F11 View"),
334 UIKEY_F11);
335 ui_set_chyron_key(pick->chyron, 5, _("<q> Quit View"),
336 'q');
337 ui_set_chyron_key(pick->chyron, 6, _("<Sp> Process"), ' ');
338 ui_set_chyron_key(pick->chyron, 7, _("<Sp> Edit"), ' ');
339 ui_set_chyron_key(pick->chyron, 9, _("<Tab> Search"),
340 '\t');
341 ui_set_chyron_key(pick->chyron, 10, _("<Tab> Select"),
342 '\t');
343 ui_set_chyron_key(pick->chyron, 11, "PgUp",
345 ui_set_chyron_key(pick->chyron, 12, "PgDn",
347 ui_set_chyron_key(pick->chyron, 13, "INS", UIKEY_IC);
349 ui_compile_chyron(pick->chyron);
350 return 0;
351}
#define min(x, y)
min macro evaluates two expressions, returning least result
Definition cm.h:104
#define max(a, b)
max macro evaluates two expressions, returning greatest result.
Definition cm.h:97
int ui_tracked_sfc_split_box(uint wlines, uint wcols, uint split_y, uint split_x, uint wbegy, uint wbegx, const char *wtitle)
Create a new surface with a split box window.
Definition ui_common.c:425
int ui_setscrreg(UiSurface *s, ss_t w, uint top, uint bottom)
Set the scrolling region for a UiSurface.
Definition ui_ncurses.c:820
void ui_get_screen_size(uint *lines, uint *cols)
Get the current screen size (number of lines and columns).
Definition ui_ncurses.c:722
int sfc_ptr
Definition ui_ncurses.c:42
int ui_scrollok(UiSurface *s, ss_t w, bool enable)
Enable or disable scrolling for a UiSurface.
Definition ui_ncurses.c:755
int ui_keypad(UiSurface *s, ss_t w, bool enable)
Enable or disable the keypad for a UiSurface.
Definition ui_ncurses.c:771
#define UIKEY_F09
#define UIKEY_IC
#define UIKEY_PPAGE
#define UIKEY_F01
#define UIKEY_F10
#define UIKEY_F11
#define UIKEY_NPAGE
void ui_set_chyron_key(UiChyron *chyron, uint k, char *s, uint kc)
Set chyron key with default color pair (cp_nt_rev).
Definition ui_common.c:717
UiChyron * ui_new_chyron(UiSurface *sfc, ss_t w)
Create new chyron structure.
Definition ui_common.c:601
void ui_compile_chyron(UiChyron *chyron)
construct the chyron string from the chyron structure
Definition ui_common.c:782
UiSurface * ui_surface[UI_SFC_MAX]
Definition ui_ncurses.c:40
Pick * pick
Definition mem.c:36
#define MAXLEN
Definition curskeys.c:15
#define _(String)
Definition amort.c:23
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:390
void pick_std_chyron(Pick *)
Sets standard chyron key states based on pick structure.
int ui_perror(char *emsg_str)
Display a simple error message window or print to stderr.
Definition ui_common.c:1257
int begx
Definition common.h:121
int cols
Definition common.h:119
int begy
Definition common.h:120
int lines
Definition common.h:118
Pick * pick
Definition common.h:191
Pick data structure.
Definition pick.h:25

References Init::begx, Pick::begx, Init::begy, Pick::begy, Pick::chyron, Init::cols, Pick::d_cnt, Pick::d_idx, Pick::d_object, Init::lines, Pick::lines, Pick::m_cnt, Pick::m_idx, Pick::m_object, Pick::p_view_files, Init::pick, pick_std_chyron(), Pick::separator_line, sfc_ptr, ssnprintf(), Pick::surface, Pick::tbl_col_width, Pick::tbl_cols, Pick::tbl_lines, Pick::tbl_page, Pick::tbl_pages, Pick::title, ui_compile_chyron(), ui_get_screen_size(), ui_keypad(), ui_new_chyron(), ui_perror(), ui_scrollok(), ui_set_chyron_key(), ui_setscrreg(), ui_surface, ui_tracked_sfc_split_box(), Pick::width, and Pick::x.

Referenced by init_pick().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pick_engine()

int pick_engine ( Init * init)

Enter picker loop to handle user input and interactions

< Buffer for user input in the field

Definition at line 353 of file pick_engine.c.

353 {
354 int rc = 0;
355 bool f_processed = false;
356 Pick *pick = init->pick;
359 char field[MAXLEN];
360 field[0] = '\0';
362 do {
363 rc = picker(init, field);
364 if (rc == UIKEY_F09)
365 break;
366 if (rc == -1)
367 break;
368 else {
369 if (pick->select_cnt > 0) {
370 if (pick->f_out_spec && pick->out_spec[0]) {
372 f_processed = true;
373 }
374 if (pick->f_cmd && pick->cmd[0]) {
375 exec_objects(init);
376 f_processed = true;
377 }
378 if (pick->f_read_theme) {
379 read_theme(init);
380 f_processed = true;
381 }
382 if (f_processed) {
383 ui_mvwaddstr(pick->surface, WIN2, 0, 0, _("Selection Processed"));
384 ui_wclrtoeol(pick->surface, WIN2);
385 }
386 }
387 }
389 } while (1);
390 ui_destroy_chyron(pick->chyron);
391 return (rc);
392}
int ui_wclrtoeol(UiSurface *s, ss_t w)
Clear to the end of the line in a surface window.
UiChyron * ui_destroy_chyron(UiChyron *chyron)
Destroy UiChyron structure.
Definition ui_common.c:656
int ui_mvwaddstr(UiSurface *s, ss_t w, uint y, uint x, const char *text)
Draw a text string at a specific position in a surface window.
int read_theme(Init *)
int picker(Init *, char *field)
Main loop for handling user input and interactions in the pick interface.
int output_objects(Pick *)
Outputs selected objects to specified output file.
void deselect_object(Pick *)
Deselects the currently selected object in pick window.
void display_pick_page(Pick *)
Displays current page of objects in pick window.
int exec_objects(Init *)
Executes specified command with selected objects as arguments.

References Pick::chyron, Pick::cmd, deselect_object(), display_pick_page(), exec_objects(), Pick::f_cmd, Pick::f_out_spec, Pick::f_read_theme, Pick::out_spec, output_objects(), Init::pick, picker(), read_theme(), Pick::select_cnt, Pick::surface, ui_destroy_chyron(), ui_mvwaddstr(), and ui_wclrtoeol().

Referenced by init_pick().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_theme()

int read_theme ( Init * init)

Definition at line 615 of file pick_engine.c.

615 {
616 int rc;
617 expand_tilde(init->mapp_theme, MAXLEN - 1);
618 rc = process_config_file(init->mapp_theme, init);
619 if (rc)
620 return rc;
621 SIO *sio = init->sio;
623 ui_render();
624 return 0;
625}
void ui_render()
Render the UI by updating panels and refreshing the display.
Definition ui_ncurses.c:884
void ui_initialize_sio(SIO *sio)
Definition ui_common.c:182
int process_config_file(char *, Init *)
Definition init.c:694
bool expand_tilde(char *, uint)
Replaces "~/" in string with the user's home directory.
Definition futil.c:989
SIO * sio
Definition common.h:117
char mapp_theme[MAXLEN]
Definition common.h:155

References expand_tilde(), Init::mapp_theme, process_config_file(), Init::sio, ui_initialize_sio(), and ui_render().

Referenced by pick_engine().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_right_angle()

void remove_right_angle ( Pick * pick)

Definition at line 564 of file pick_engine.c.

564 {
565 UiSurface *sfc = pick->surface;
566 if (pick->d_idx >= pick->d_cnt)
567 pick->d_idx = pick->d_cnt - 1;
568 pick->tbl_line = (pick->d_idx / pick->tbl_cols) % pick->lines;
569 pick->y = pick->tbl_line + pick->y_offset;
570 pick->d_idx = pick->tbl_page * pick->lines * pick->tbl_cols + pick->tbl_col * pick->lines + pick->tbl_line;
571 if (pick->f_selected[pick->d_idx])
572 ui_mvwadd_wchnstr(sfc, WIN, pick->y, 0, &cell_chk, 1);
573 else
574 ui_mvwadd_wchnstr(sfc, WIN, pick->y, 0, &cell_sp, 1);
575 ui_cursor_move(sfc, WIN, pick->y, 0);
576}
UiCell cell_sp
Definition ui_common.c:132
int ui_cursor_move(UiSurface *s, ss_t w, uint y, uint x)
Move the cursor to a specified position within a UiSurface.
Definition ui_ncurses.c:666
UiCell cell_chk
Definition ui_common.c:116
int ui_mvwadd_wchnstr(UiSurface *s, ss_t w, uint y, uint x, const UiCell *cmplx_buf, uint n)
Draw a complex character string at a specific position in a surface window, with a maximum length.

References cell_chk, cell_sp, Pick::d_cnt, Pick::d_idx, Pick::f_selected, Pick::lines, Pick::surface, Pick::tbl_col, Pick::tbl_cols, Pick::tbl_line, Pick::tbl_page, ui_cursor_move(), ui_mvwadd_wchnstr(), Pick::y, and Pick::y_offset.

Referenced by picker().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ calculated_idx

int calculated_idx

Definition at line 24 of file pick_engine.c.

◆ obj_idx

int obj_idx

Definition at line 24 of file pick_engine.c.

◆ pagers_editors

char const pagers_editors
Initial value:
= {"view", "view", "less", "more",
"vi", "vim", "nano", "nvim",
"pico", "emacs", "edit", ""}

Definition at line 50 of file pick_engine.c.

50 {"view", "view", "less", "more",
51 "vi", "vim", "nano", "nvim",
52 "pico", "emacs", "edit", ""};

◆ pg_lines

int pg_lines

Definition at line 23 of file pick_engine.c.

◆ pipe_fd

int pipe_fd

Definition at line 46 of file pick_engine.c.

Referenced by init_pick().

◆ tbl_col

int tbl_col

Definition at line 23 of file pick_engine.c.

◆ tbl_cols

int tbl_cols

Definition at line 23 of file pick_engine.c.

◆ tbl_line

int tbl_line

Definition at line 23 of file pick_engine.c.

◆ tbl_page

int tbl_page

Definition at line 23 of file pick_engine.c.

◆ tbl_pages

int tbl_pages

Definition at line 23 of file pick_engine.c.

◆ ui_mm

UiMultiMedia ui_mm

Definition at line 48 of file pick_engine.c.