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

The numeric keypad. See ui_keypad.h. More...

#include "ui_keypad.h"
#include <stdio.h>
#include <string.h>
#include "ui_text.h"
#include "ui_theme.h"
#include "ui_widgets.h"

Macros

#define KP_PAD   8
 The room around the title, the entry and the keys: 8px.
#define KP_HDR   32
 The title row: the 10 x 20 face and 6px above it.
#define KP_ENTRY_H   60
 The entry: the 32 x 44 numerals and 8px above and below.
#define KP_GAP   8
 The gap between the entry and the keys, and between keys.
#define KP_COLS   4
 The key grid: 4 columns ...
#define KP_ROWS   4
 ... and 4 rows.
#define KP_KEY_PAD   6
 The room a key keeps left and right of its label: 6px.
#define KP_FACES   ((int)(sizeof(k_faces) / sizeof(k_faces[0])))
 The count of k_faces.

Functions

void ui_keypad_open (ui_keypad_t *k, gfx_rect_t area, const char *title, const char *unit, float value, float min, float max, int decimals)
void ui_keypad_open_signed (ui_keypad_t *k, gfx_rect_t area, const char *title, const char *unit, float value, float min, float max, int decimals)
 Open k as ui_keypad_open() does, with the +/- key: for a value whose range reaches below 0 by more than a "not set" -1.
void ui_keypad_close (ui_keypad_t *k)
void ui_keypad_refuse (ui_keypad_t *k)
 Refuse the value the last OK handed back, after the caller has judged it by a rule of its own: the keypad opens again with the entry as typed and the range in the warning colour, as OK on a value outside the range leaves it.
void ui_keypad_refuse_why (ui_keypad_t *k, const char *reason)
 Refuse as ui_keypad_refuse() does, with the reason drawn in place of the range, in the warning colour, until the next key.
void ui_keypad_cancel_press (ui_keypad_t *k)
gfx_rect_t ui_keypad_key_rect (const ui_keypad_t *k, ui_key_t key)
 Where a key is drawn and hit: the grid ends 8px inside the area, or at UI_KEYS_FOOT (4px above the alert band, body coordinates) where the area reaches further.
static float parse (const char *s)
 What has been typed, as a number. The entry holds an optional leading minus, digits and at most one point, so nothing here can fail.
static bool typed (const ui_keypad_t *k)
 Whether the entry holds a digit: "" and "-" are nothing typed.
static void toggle_sign (ui_keypad_t *k)
 The +/- key: a minus sign put in front of the entry, or taken away. An entry already UI_KEYPAD_ENTRY_MAX long takes none.
static int digits_after_point (const ui_keypad_t *k)
static void append (ui_keypad_t *k, char ch)
 A digit or the point added to the entry, if the entry has room and the value keeps it: one point, none on a whole number, no digit past the decimals. A point on nothing typed, or after a lone minus sign, puts a 0 before it.
static ui_keypad_result_t press (ui_keypad_t *k, ui_key_t key, float *out)
 Key key pressed and released.
ui_keypad_result_t ui_keypad_event (ui_keypad_t *k, const touch_event_t *evt, float *out)
static const gfx_font_t * header_face (gfx_rect_t hdr, const char *title, const char *range)
 The face the title and the range share: 10 x 20 when both fit the header side by side with 16px between them, else 8 x 16.
static int digit_face (const ui_keypad_t *k)
 Where the digits' face is in k_faces: the first whose cell fits a digit key with KP_KEY_PAD on each of its 4 sides.
const gfx_font_t * ui_keypad_digit_font (const ui_keypad_t *k)
 The face of the digits and the point: the largest of 20 x 36, 16 x 28, 12 x 24 and 10 x 20 whose cell fits a digit key with 6px on each side, else 8 x 16. Over SUPPLY's 620 x 476px a key is 145 x 76px and takes 20 x 36.
const gfx_font_t * ui_keypad_word_font (const ui_keypad_t *k)
 The face of the word keys (DEL, CLR, CANCEL, OK, +/-) in the language shown: the largest of 20 x 36, 16 x 28, 12 x 24 and 10 x 20, never larger than ui_keypad_digit_font(), in which every one of them fits its key with 6px each side, so the words of one keypad share one face; else 8 x 16.
static void entry_text (gfx_canvas_t *c, gfx_rect_t box, const char *number, const char *unit, gfx_color_t ink)
 The entry: number in the numeral face and unit beside it, right-aligned 10px inside box. 32 x 44 numerals with a 12 x 24 unit where they fit, else 24 x 30 with 10 x 20; what does not fit even then is cut at the box's right, the unit first. A pin word (ui_unit_is_prefix()) stands before the number ("GPIO 4"); every other unit after it.
const char * ui_keypad_range (const ui_keypad_t *k, char *buf, size_t n)
 The range line of the keypad's header: "3.30 to 21.00V", the unit joined to a symbol and after a space to a word (ui_unit_gap()), with the keypad's decimals. A pin word (ui_unit_is_prefix()) leads: "GPIO 0 to 54".
void ui_keypad_render (const ui_keypad_t *k, gfx_canvas_t *c)
 The whole keypad over its area: the title and the range in 10 x 20 (8 x 16 where they do not fit side by side), the entry in the 32 x 44 numerals with its unit in 12 x 24 (24 x 30 and 10 x 20 where those do not fit), the digits in ui_keypad_digit_font() and the words in ui_keypad_word_font(); the +/- key only on a signed keypad. Nothing while it is closed.

Variables

static const char *const k_labels [UI_KEY_COUNT]
static const gfx_font_t *const k_faces []
 The key faces, largest first: 20 x 36, 16 x 28, 12 x 24, 10 x 20 and 8 x 16.

Detailed Description

The numeric keypad. See ui_keypad.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ append()

void append ( ui_keypad_t * k,
char ch )
static

A digit or the point added to the entry, if the entry has room and the value keeps it: one point, none on a whole number, no digit past the decimals. A point on nothing typed, or after a lone minus sign, puts a 0 before it.

Parameters
kThe keypad.
ch'0' to '9' or '.'.

◆ digit_face()

int digit_face ( const ui_keypad_t * k)
static

Where the digits' face is in k_faces: the first whose cell fits a digit key with KP_KEY_PAD on each of its 4 sides.

Parameters
kThe keypad.
Returns
The index; the last, 8 x 16, when none fits.

◆ entry_text()

void entry_text ( gfx_canvas_t * c,
gfx_rect_t box,
const char * number,
const char * unit,
gfx_color_t ink )
static

The entry: number in the numeral face and unit beside it, right-aligned 10px inside box. 32 x 44 numerals with a 12 x 24 unit where they fit, else 24 x 30 with 10 x 20; what does not fit even then is cut at the box's right, the unit first. A pin word (ui_unit_is_prefix()) stands before the number ("GPIO 4"); every other unit after it.

Parameters
cCanvas.
boxThe entry's box.
numberThe number: digits, a minus sign and a point.
unitThe unit, or "".
inkThe colour of both.

◆ header_face()

const gfx_font_t * header_face ( gfx_rect_t hdr,
const char * title,
const char * range )
static

The face the title and the range share: 10 x 20 when both fit the header side by side with 16px between them, else 8 x 16.

Parameters
hdrThe header row.
titleThe title.
rangeThe range, or the caller's reason.
Returns
The face.

◆ parse()

float parse ( const char * s)
static

What has been typed, as a number. The entry holds an optional leading minus, digits and at most one point, so nothing here can fail.

Parameters
sThe entry.
Returns
Its value; "-0" and "-0.0" are 0, never a negative zero.

◆ press()

ui_keypad_result_t press ( ui_keypad_t * k,
ui_key_t key,
float * out )
static

Key key pressed and released.

Parameters
kThe keypad.
keyThe key.
outWhere OK writes a value inside the range.
Returns
UI_KEYPAD_OK with a value, UI_KEYPAD_CANCEL on CANCEL and on OK with nothing typed, UI_KEYPAD_NONE otherwise, a refusal included.

◆ toggle_sign()

void toggle_sign ( ui_keypad_t * k)
static

The +/- key: a minus sign put in front of the entry, or taken away. An entry already UI_KEYPAD_ENTRY_MAX long takes none.

Parameters
kThe keypad.

◆ typed()

bool typed ( const ui_keypad_t * k)
static

Whether the entry holds a digit: "" and "-" are nothing typed.

Parameters
kThe keypad.
Returns
True when a digit has been typed.

◆ ui_keypad_cancel_press()

void ui_keypad_cancel_press ( ui_keypad_t * k)

A press under way is dropped: the touch stream lost an event. The keypad stays open and what was typed stays typed.

◆ ui_keypad_digit_font()

const gfx_font_t * ui_keypad_digit_font ( const ui_keypad_t * k)

The face of the digits and the point: the largest of 20 x 36, 16 x 28, 12 x 24 and 10 x 20 whose cell fits a digit key with 6px on each side, else 8 x 16. Over SUPPLY's 620 x 476px a key is 145 x 76px and takes 20 x 36.

Parameters
kThe keypad, opened.
Returns
The face; 8 x 16 for NULL.

◆ ui_keypad_event()

ui_keypad_result_t ui_keypad_event ( ui_keypad_t * k,
const touch_event_t * evt,
float * out )

One touch event. A key acts on the release of the contact that pressed it, over the same key; a second contact is ignored while one is down. UI_KEYPAD_OK writes the value to out.

◆ ui_keypad_key_rect()

gfx_rect_t ui_keypad_key_rect ( const ui_keypad_t * k,
ui_key_t key )

Where a key is drawn and hit: the grid ends 8px inside the area, or at UI_KEYS_FOOT (4px above the alert band, body coordinates) where the area reaches further.

Parameters
kThe keypad.
keyThe key.
Returns
Its rectangle; an empty one for UI_KEY_SIGN on an unsigned keypad and for a key out of range.

◆ ui_keypad_open()

void ui_keypad_open ( ui_keypad_t * k,
gfx_rect_t area,
const char * title,
const char * unit,
float value,
float min,
float max,
int decimals )

Open over area for a value of min .. max, showing value.

◆ ui_keypad_open_signed()

void ui_keypad_open_signed ( ui_keypad_t * k,
gfx_rect_t area,
const char * title,
const char * unit,
float value,
float min,
float max,
int decimals )

Open k as ui_keypad_open() does, with the +/- key: for a value whose range reaches below 0 by more than a "not set" -1.

Parameters
kThe keypad.
areaWhere it is drawn and hit.
titleIts title.
unitThe value's unit.
valueThe value as it is, shown faint.
minThe range's lower end, below 0.
maxIts upper end.
decimalsThe digits it takes after the point.

◆ ui_keypad_range()

const char * ui_keypad_range ( const ui_keypad_t * k,
char * buf,
size_t n )

The range line of the keypad's header: "3.30 to 21.00V", the unit joined to a symbol and after a space to a word (ui_unit_gap()), with the keypad's decimals. A pin word (ui_unit_is_prefix()) leads: "GPIO 0 to 54".

Parameters
kThe keypad.
bufTakes the line.
nBytes at buf.
Returns
buf; "" for a NULL k, buf or a zero n.

◆ ui_keypad_refuse()

void ui_keypad_refuse ( ui_keypad_t * k)

Refuse the value the last OK handed back, after the caller has judged it by a rule of its own: the keypad opens again with the entry as typed and the range in the warning colour, as OK on a value outside the range leaves it.

Parameters
kThe keypad that returned UI_KEYPAD_OK.

◆ ui_keypad_refuse_why()

void ui_keypad_refuse_why ( ui_keypad_t * k,
const char * reason )

Refuse as ui_keypad_refuse() does, with the reason drawn in place of the range, in the warning colour, until the next key.

Parameters
kThe keypad that returned UI_KEYPAD_OK.
reasonWhy, one line; NULL or "" draws the range. A reason of 64 bytes or more is cut to at most 63 at the start of a UTF-8 character, so no character is drawn half.

◆ ui_keypad_render()

void ui_keypad_render ( const ui_keypad_t * k,
gfx_canvas_t * c )

The whole keypad over its area: the title and the range in 10 x 20 (8 x 16 where they do not fit side by side), the entry in the 32 x 44 numerals with its unit in 12 x 24 (24 x 30 and 10 x 20 where those do not fit), the digits in ui_keypad_digit_font() and the words in ui_keypad_word_font(); the +/- key only on a signed keypad. Nothing while it is closed.

Parameters
kThe keypad.
cThe canvas.

◆ ui_keypad_word_font()

const gfx_font_t * ui_keypad_word_font ( const ui_keypad_t * k)

The face of the word keys (DEL, CLR, CANCEL, OK, +/-) in the language shown: the largest of 20 x 36, 16 x 28, 12 x 24 and 10 x 20, never larger than ui_keypad_digit_font(), in which every one of them fits its key with 6px each side, so the words of one keypad share one face; else 8 x 16.

Parameters
kThe keypad, opened.
Returns
The face; 8 x 16 for NULL.

Variable Documentation

◆ k_faces

const gfx_font_t* const k_faces[]
static
Initial value:
= {
}
const gfx_font_t gfx_font_16x28
const gfx_font_t gfx_font_12x24
12x24 monospaced, ASCII 0x20..0x7E and the German letters. Cap height 15px. Prose: help text,...
const gfx_font_t gfx_font_20x36
20x36 monospaced, ASCII 0x20..0x7E and the German letters. Cap height 23px. Headings,...
const gfx_font_t gfx_font_10x20
10x20 monospaced, ASCII 0x20..0x7E and the German letters. Cap height 12px. Labels,...
const gfx_font_t gfx_font_8x16

The key faces, largest first: 20 x 36, 16 x 28, 12 x 24, 10 x 20 and 8 x 16.

◆ k_labels

const char* const k_labels[UI_KEY_COUNT]
static
Initial value:
= {
"7", "8", "9", "DEL",
"4", "5", "6", "CLR",
"1", "2", "3", NULL,
"0", ".", "OK",
"+/-",
}