rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
log_viewer_screen.c File Reference

The log viewer: browse the card, review the import, plot the file. More...

#include "log_viewer_screen.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "card_tree.h"
#include "log_name.h"
#include "settings.h"
#include "ui_screen.h"
#include "ui_tabs.h"
#include "ui_text.h"
#include "ui_widgets.h"
#include "log_viewer_int.h"

Functions

log_viewer_view_t log_viewer_view (void)
const char * log_viewer_open_name (void)
const log_analysis_t * log_viewer_analysis (void)
const log_data_t * log_viewer_data (void)
const log_text_t * log_viewer_text (void)
 The report the TEXT view shows.
int log_viewer_text_first (void)
 The TEXT view's first row on screen.
void log_viewer_window (int *first, int *count)
gfx_color_t log_viewer_series_color (int k)
void log_viewer_range_text (char *out, size_t n, double lo, double hi, const char *unit)
int log_viewer_cursor (void)
const char * log_viewer_message (void)
 The footer message: the last result or refusal, worded in the language showing; "" for none.
void log_viewer_invalidate (void)
void log_viewer_set_io (const log_viewer_io_t *io)
const char * log_viewer_tab_dir (log_viewer_tab_t tab)
log_viewer_tab_t log_viewer_tab (void)
void lv_point (log_viewer_tab_t tab)
 Points the I/O at the folder of tab, for the call that follows.
const char * lv_volume_now (void)
 Returns the card's name as the I/O reports it now.
unsigned lv_mounts_now (void)
 Returns the I/O's mount number now.
static bool volume_changed (void)
const char * lv_page_edge (int sign)
 Returns the entry on the page that log_name_rank() puts first or last: the edges PREV, NEXT and RESCAN name.
static int list_once (log_page_dir_t dir, const char *key, int cap)
void lv_read_page (log_page_dir_t dir, const char *key)
 Read the page dir and key name, and select its newest run.
void log_viewer_refresh (void)
void lv_rescan (void)
 Reads the page on screen again: the first page from the top, any other from its first entry; another card's name reads from its first page.
bool lv_paged (void)
 Returns whether the card holds more than the page shows, either side of it.
bool lv_can_prev (void)
 Returns whether a page precedes this one.
bool lv_can_next (void)
 Returns whether a page follows this one.
void log_viewer_browse_title (char *out, size_t n)
void lv_drop_data (void)
 Frees the plot's samples and clears the cursor.
bool lv_can_delete (void)
 Returns whether DELETE is offered: the I/O can delete and a file is selected.
void lv_bar_thumb_of (int total, int visible, int scroll, int *y, int *h)
 The thumb of a scroll bar on BR_BAR: the whole track while every row shows.
void lv_bar_thumb (int *y, int *h)
 The browse list's thumb (lv_bar_thumb_of()).
int lv_bar_scroll_of (int total, int visible, int top)
 The scroll that puts a thumb's top on BR_BAR nearest top.
int lv_bar_scroll_at (int top)
 The browse list's scroll for a thumb at top (lv_bar_scroll_of()).
int lv_text_total (void)
 Rows the TEXT view scrolls through: the text's, and the line that says it was cut.
void lv_close_text (void)
 Leave the TEXT view for the list and free the report's text.
static int tab_pos (log_viewer_tab_t tab)
static void cancel (void)
 The panel could not hand over every touch event, so this screen's record of the glass is stale. Every view here acts on the release – a button refreshes the card, opens a file or changes an import setting, a row selects or opens – so a press left standing would let a later contact's release do any of those without a press of its own.
void log_viewer_set_tab (log_viewer_tab_t tab)
log_viewer_show_t log_viewer_show (log_viewer_tab_t tab, const char *name, unsigned mount)
 Show tab with file name open, as a tap on the tab, a tap on the file's row and OPEN do: FILES' OPEN on a file of one of the three folders. The page read is the one that starts at the name, and it must come from the mount FILES listed the file from.
static void reset (void)
 The screen as a start leaves it: the BENCH tab, nothing open, nothing selected.
static void enter (void)
static bool back (void)
 The home tag: one level up, as each view's BACK.
static void leave (void)
 Leaving LOGS: a report's text is freed, and LOGS opens on the list next time. The import and the plot stay as they were left.
const ui_screen_t * log_viewer_screen (void)

Variables

const ui_color_id_t lv_series_color [LOG_MAX_SERIES]
 Colour id of each plot series.
lv_state_t lv_s
 The viewer's state, in log_viewer_screen.c.
int16_t lv_span [LOG_MAX_SERIES][PV_W][2]
 Per series and pixel column, the plot's minimum and maximum row, filled by lv_compute_spans().
gfx_color_t lv_band [PV_W *PV_BAND]
 One band of PV_BAND rows of the plot, drawn at a time.
float lv_lo [LOG_MAX_SERIES]
 Per series, the lowest value in the window.
float lv_hi [LOG_MAX_SERIES]
 Per series, the highest value in the window.
const log_viewer_tab_t lv_tab_at [LOG_TAB_COUNT]
 Folder tab shown for each tab index.
static const ui_text_id_t k_tab_text [LOG_TAB_COUNT]
static const ui_screen_t s_screen

Detailed Description

The log viewer: browse the card, review the import, plot the file.

Three views behind one tile: a file browser, an import view that shows what the CSV (comma-separated values) reader made of the file, and the plot. The reader detects the delimiter, the decimal convention and the time column (see shared/logfile); the import view shows the detection and its evidence before anything is plotted, and offers overrides.

lv_compute_spans() turns the chosen columns into scaled traces when the data changes, so the plot render walks prepared spans rather than reparsing on every frame.

This file holds the state, the card's listing and paging and the screen's interface; log_viewer_load.c opens a file, log_viewer_draw.c draws the four views, log_viewer_events.c takes their touch events, and log_viewer_int.h is what the four share.

DELETE in the browse view asks before it acts: a second panel names the file and its size, and only its own DELETE, pressed and released on that button, calls the I/O's remove().

The browse view lists one folder at a time, chosen by three tabs in its header row: ROOT, USER and BENCH, in that order (log_viewer_tab_t holds the ids; the tabs' order on screen is lv_tab_at).

A report, ATESTnnn.TXT or LIMITnnn.TXT, opens in a fourth view as text: the browse list's panel, scroll bar and BACK, with the file's rows in place of the files (log_text.h).

SPDX-License-Identifier: MIT

Function Documentation

◆ back()

bool back ( void )
static

The home tag: one level up, as each view's BACK.

The plot to the import, the import and a report's text to the file list; the text is freed (lv_close_text()). Over the DELETE question it is CANCEL: the file stays. On the file list it leaves the screen. A press held, a drag, a pan and a pinch end with the view they were made on.

Returns
True when it climbed inside the screen, false to leave it.

◆ cancel()

void cancel ( void )
static

The panel could not hand over every touch event, so this screen's record of the glass is stale. Every view here acts on the release – a button refreshes the card, opens a file or changes an import setting, a row selects or opens – so a press left standing would let a later contact's release do any of those without a press of its own.

The DELETE question's press goes with them, and that one matters most: the contact it is bound to may be among the events lost, and the controller reuses track ids, so a later finger lifting off DELETE could carry it. The question itself stays open; it needs a fresh press to answer it.

◆ log_viewer_analysis()

const log_analysis_t * log_viewer_analysis ( void )

What was detected, or NULL when nothing has been analysed.

◆ log_viewer_browse_title()

void log_viewer_browse_title ( char * out,
size_t n )

The browse list's tab into out of n bytes: the page's place in the card, "FILES 49 TO 96 OF 121", on a card of more than one page, and "FILES" otherwise. The list draws this text.

◆ log_viewer_cursor()

int log_viewer_cursor ( void )

The sample the cursor is on, or -1 with nothing plotted.

◆ log_viewer_data()

const log_data_t * log_viewer_data ( void )

The loaded traces, or NULL when nothing is plotted.

◆ log_viewer_message()

const char * log_viewer_message ( void )

The footer message: the last result or refusal, worded in the language showing; "" for none.

Returns
the message, in a buffer the next call overwrites

◆ log_viewer_open_name()

const char * log_viewer_open_name ( void )

The file currently open, or "" – the overview header shows this.

◆ log_viewer_refresh()

void log_viewer_refresh ( void )

Re-read the directory from its first page, e.g. after a card was inserted. Closes an open DELETE question: the name it asked about may be on another card now. Selects the newest numbered run, so the run just recorded is the one OPEN opens.

◆ log_viewer_series_color()

gfx_color_t log_viewer_series_color ( int k)

The colour series k is drawn in.

◆ log_viewer_set_tab()

void log_viewer_set_tab ( log_viewer_tab_t tab)

Show tab and read its folder from the first page, as a tap on the tab does. A tab outside the three is ignored.

◆ log_viewer_show()

log_viewer_show_t log_viewer_show ( log_viewer_tab_t tab,
const char * name,
unsigned mount )

Show tab with file name open, as a tap on the tab, a tap on the file's row and OPEN do: FILES' OPEN on a file of one of the three folders. The page read is the one that starts at the name, and it must come from the mount FILES listed the file from.

Parameters
tabthe folder's tab
namethe file's name in that folder
mountthe mount number (log_viewer_io_t mounts()) FILES read the name from
Returns
what was found

◆ log_viewer_tab()

log_viewer_tab_t log_viewer_tab ( void )

The tab BROWSE shows.

◆ log_viewer_tab_dir()

const char * log_viewer_tab_dir ( log_viewer_tab_t tab)

The folder of tab, a path from the card's root ("" the root itself); "" for a tab outside the three. USER and BENCH list the folders SETUP > SD CARD names in force, as the logger writes them (card_folder_use(): the default folder for one card_folder_check() refuses). Valid until the next call for the same tab.

◆ log_viewer_text()

const log_text_t * log_viewer_text ( void )

The report the TEXT view shows.

Returns
its text and rows (log_text.h), or NULL with no report open

◆ log_viewer_text_first()

int log_viewer_text_first ( void )

The TEXT view's first row on screen.

Returns
the row, 0 at the top and with no report open

◆ log_viewer_view()

log_viewer_view_t log_viewer_view ( void )

Which of the three views is showing.

◆ log_viewer_window()

void log_viewer_window ( int * first,
int * count )

The samples the plot shows: the first in first and how many in count. The whole file until two fingers zoom in; both 0 with nothing plotted.

◆ lv_bar_scroll_at()

int lv_bar_scroll_at ( int top)

The browse list's scroll for a thumb at top (lv_bar_scroll_of()).

Parameters
topThe thumb's top the finger asks for.
Returns
The first row on screen.

◆ lv_bar_scroll_of()

int lv_bar_scroll_of ( int total,
int visible,
int top )

The scroll that puts a thumb's top on BR_BAR nearest top.

Parameters
totalRows of the list.
visibleRows on screen.
topThe thumb's top the finger asks for.
Returns
The first row on screen, 0 to total - visible.

◆ lv_bar_thumb()

void lv_bar_thumb ( int * y,
int * h )

The browse list's thumb (lv_bar_thumb_of()).

Parameters
yTakes the thumb's top.
hTakes its height.

◆ lv_bar_thumb_of()

void lv_bar_thumb_of ( int total,
int visible,
int scroll,
int * y,
int * h )

The thumb of a scroll bar on BR_BAR: the whole track while every row shows.

Parameters
totalRows of the list.
visibleRows on screen.
scrollThe first row on screen.
yTakes the thumb's top.
hTakes its height, BR_BAR_MIN px at least.

◆ lv_can_delete()

bool lv_can_delete ( void )

Returns whether DELETE is offered: the I/O can delete and a file is selected.

Returns
true when DELETE is enabled

◆ lv_can_next()

bool lv_can_next ( void )

Returns whether a page follows this one.

Returns
true when NEXT is enabled

◆ lv_can_prev()

bool lv_can_prev ( void )

Returns whether a page precedes this one.

Returns
true when PREV is enabled

◆ lv_close_text()

void lv_close_text ( void )

Leave the TEXT view for the list and free the report's text.

The text is up to 32KiB of the file; the list does not need it, and OPEN reads it again.

◆ lv_mounts_now()

unsigned lv_mounts_now ( void )

Returns the I/O's mount number now.

Returns
the mount number, 0 without one

◆ lv_page_edge()

const char * lv_page_edge ( int sign)

Returns the entry on the page that log_name_rank() puts first or last: the edges PREV, NEXT and RESCAN name.

Parameters
sign1 for the first entry, -1 for the last
Returns
the entry's name, "" with an empty page

◆ lv_paged()

bool lv_paged ( void )

Returns whether the card holds more than the page shows, either side of it.

Returns
true when the list is paged

◆ lv_point()

void lv_point ( log_viewer_tab_t tab)

Points the I/O at the folder of tab, for the call that follows.

Parameters
tabthe folder tab

◆ lv_read_page()

void lv_read_page ( log_page_dir_t dir,
const char * key )

Read the page dir and key name, and select its newest run.

Pages are cut from the top, LOG_VIEWER_MAX_FILES at a time. A page before the key that starts less than a page from the top is the first page, read again from the top: a run recorded since the key was read stands ahead of it, and so does nothing when everything ahead of the key has gone. A page that comes back empty from a card that is not, is a page past the end: the card has fewer entries than when the key was read, after a DELETE or behind the screen's back. The last page is read instead, as the pages from the first one cut it: what is left of the count after whole pages. The newest is the highest number on the page, a report included.

Parameters
dirWhich side of key the page is on.
keyThe name at the page's edge; "" or NULL for the top.

◆ lv_text_total()

int lv_text_total ( void )

Rows the TEXT view scrolls through: the text's, and the line that says it was cut.

Returns
The rows.

◆ lv_volume_now()

const char * lv_volume_now ( void )

Returns the card's name as the I/O reports it now.

Returns
the name, "" when there is none

◆ reset()

void reset ( void )
static

The screen as a start leaves it: the BENCH tab, nothing open, nothing selected.

The I/O stays; the data, the analysis and a report's text are freed.

Variable Documentation

◆ k_tab_text

const ui_text_id_t k_tab_text[LOG_TAB_COUNT]
static
Initial value:
= {
TX_LOG_TAB_ROOT, TX_LOG_TAB_USER, TX_LOG_TAB_BENCH,
}

◆ lv_series_color

const ui_color_id_t lv_series_color[LOG_MAX_SERIES]
Initial value:
= {
UI_C_VOLT, UI_C_CURR, UI_C_POWER, UI_C_RPM,
}

Colour id of each plot series.

◆ lv_tab_at

const log_viewer_tab_t lv_tab_at[LOG_TAB_COUNT]
Initial value:
= {
}
@ LOG_TAB_USER
Definition log_viewer_screen.h:116
@ LOG_TAB_ROOT
Definition log_viewer_screen.h:118
@ LOG_TAB_BENCH
Definition log_viewer_screen.h:117

Folder tab shown for each tab index.

◆ s_screen

const ui_screen_t s_screen
static
Initial value:
= {
.title = "LOGS",
.reset = reset,
.enter = enter,
.leave = leave,
.tick = NULL,
.event = lv_event,
.cancel = cancel,
.render = lv_render,
.back = back,
}
static void enter(void)
On the way in: both panes read, from their first pages the first time and as they were left after tha...
Definition files_screen.c:1026
static bool back(void)
The home tag: a box or the keyboard closes, a job's box cancels a copy and stays; with the panes on t...
Definition files_screen.c:1096
static void leave(void)
On the way out: the keyboard and the boxes close; a job under way goes on, and its box shows again on...
Definition files_screen.c:1045
static void reset(void)
The screen as a start leaves it: the card's root on the left, USER LOG FOLDER on the right,...
Definition files_screen.c:1006
void lv_render(gfx_canvas_t *c, int buffer_index)
Draws the view on screen into frame buffer buffer_index.
Definition log_viewer_draw.c:785
void lv_event(const touch_event_t *e)
Takes a touch event for the view on screen.
Definition log_viewer_events.c:804
static void cancel(void)
The panel could not hand over every touch event, so this screen's record of the glass is stale....
Definition log_viewer_screen.c:545