Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
72366ef
implement OpMode cycle, allows easier modularity when adding new OpModes
anthonydotmoe Oct 2, 2025
eacb5de
first draft UI architecture
anthonydotmoe Nov 6, 2025
3e44bc3
implement bool settings
anthonydotmoe Nov 6, 2025
06ed860
alter menu API; wire sample setting
anthonydotmoe Nov 6, 2025
a2c533b
implement u8 dial
anthonydotmoe Nov 7, 2025
09736c8
add gps settings page
anthonydotmoe Nov 7, 2025
31b7895
add accessibility settings stub
anthonydotmoe Nov 7, 2025
07b40a0
flesh out menu item callbacks, test with FM CTCSS
anthonydotmoe Nov 7, 2025
cc2eaf3
introduce menu declaration macros
anthonydotmoe Nov 8, 2025
3a551e7
draft: text edit widget
anthonydotmoe Nov 9, 2025
f3a6ba1
text editor working
anthonydotmoe Nov 10, 2025
b9818bb
add UiScreenEvent type for focus; fixes screen paint issue
anthonydotmoe Nov 10, 2025
a68e122
ui_menu: fix compiler warning
anthonydotmoe Nov 10, 2025
d90df3d
executive decision: un-bitfield settings_t
anthonydotmoe Nov 10, 2025
3d784b0
finish MENU_VAL_ENUM, display settings
anthonydotmoe Nov 11, 2025
50979b3
wire up more settings
anthonydotmoe Nov 13, 2025
77d9a99
add GPS status screen
anthonydotmoe Nov 13, 2025
e68bc73
ui_menu: add a scrollbar
anthonydotmoe Nov 13, 2025
6aabab4
ui_menu: clean up scrollbar
anthonydotmoe Nov 14, 2025
a4fa167
ui_textedit: add multi-line, character counter
anthonydotmoe Nov 14, 2025
0099fd4
ui_textedit: allow inserting characters, fixup safety
anthonydotmoe Nov 17, 2025
2f10bac
ui_menu: fix uninitialized variable
anthonydotmoe Nov 17, 2025
2403090
ui_settings: cleanup, add module17 stub
anthonydotmoe Nov 19, 2025
3eaa50f
graphics: introduce font metrics query, drawTextRect function
anthonydotmoe Nov 19, 2025
8e303dd
ui_new: introduce newlayout_t struct
anthonydotmoe Nov 19, 2025
8f5a3fb
ui_textedit: make layout dynamic to screen/font size
anthonydotmoe Nov 19, 2025
76a8f52
ui_menu: make layout dynamic to screen/font size
anthonydotmoe Nov 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ openrtx_def += {'FONT_UBUNTU_REGULAR': ''}
##

openrtx_src = ['openrtx/src/core/state.c',
'openrtx/src/core/settings.c',
'openrtx/src/core/threads.c',
'openrtx/src/core/battery.c',
'openrtx/src/core/graphics.c',
Expand Down Expand Up @@ -78,7 +79,20 @@ openrtx_inc = ['openrtx/include', 'platform']
ui_src_default = ['openrtx/src/ui/default/ui.c',
'openrtx/src/ui/default/ui_main.c',
'openrtx/src/ui/default/ui_menu.c',
'openrtx/src/ui/default/ui_strings.c']
'openrtx/src/ui/default/ui_strings.c',
'openrtx/src/ui/new/ui.c',
'openrtx/src/ui/new/ui_core.c',
'openrtx/src/ui/new/ui_compat.c',
'openrtx/src/ui/new/ui_gps.c',
'openrtx/src/ui/new/ui_menu.c',
'openrtx/src/ui/new/ui_menu_tree.c',
'openrtx/src/ui/new/ui_settings_display.c',
'openrtx/src/ui/new/ui_settings_gps.c',
'openrtx/src/ui/new/ui_settings_radio.c',
'openrtx/src/ui/new/ui_settings_m17.c',
'openrtx/src/ui/new/ui_settings_fm.c',
'openrtx/src/ui/new/ui_settings_accessibility.c',
'openrtx/src/ui/new/ui_textedit.c']

ui_src_module17 = ['openrtx/src/ui/module17/ui.c',
'openrtx/src/ui/module17/ui_main.c',
Expand Down Expand Up @@ -356,7 +370,7 @@ linux_l_args = ['-lm', '-lreadline']
if build_machine.system() == 'darwin'
linux_l_args += '-Wl,-dead_strip'
else
linux_l_args += '-Wl,--gc-sections'
#linux_l_args += '-Wl,--gc-sections'
endif

# Add AddressSanitizer if required
Expand Down Expand Up @@ -799,7 +813,8 @@ cs7000p_opts = {
'c_args' : cs7000p_args,
'cpp_args' : cs7000p_args,
'link_args' : ['-Wl,-T../platform/mcu/STM32H7xx/linker_script_cs7000p.ld',
'-Wl,--print-memory-usage']
'-Wl,--print-memory-usage',
'-Wl,-Map=firmware.map']
}

dm1701_opts = {
Expand Down
45 changes: 45 additions & 0 deletions openrtx/include/core/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ typedef struct point_t
int16_t y;
} point_t;

/**
* Structure that represents the X,Y coordinates, width and height of a rectangle.
*/
typedef struct
{
int16_t x;
int16_t y;
uint16_t w;
uint16_t h;
} gfx_rect_t;

/**
* Structure that represents a single color in the RGB 8 bit per channel format
*/
Expand Down Expand Up @@ -92,6 +103,19 @@ typedef enum
TEXT_ALIGN_RIGHT
} textAlign_t;

typedef enum
{
TEXT_VALIGN_TOP = 0,
TEXT_VALIGN_MIDDLE,
TEXT_VALIGN_BOTTOM
} textValign_t;

typedef struct
{
uint8_t ascent; // pixels above baseline
uint8_t descent; // pixels below baseline
uint8_t line_height; // ascent + descent
} gfx_font_metrics_t;

/**
* This function calls the correspondent method of the low level interface display.h
Expand Down Expand Up @@ -186,6 +210,8 @@ void gfx_drawVLine(int16_t x, uint16_t width, color_t color);
void gfx_drawRect(point_t start, uint16_t width, uint16_t height, color_t color,
bool fill);

void gfx_drawRectRect(gfx_rect_t rect, color_t color, bool fill);

/**
* Draw the outline of a circle of specified radius and color.
* @param start: screen position of the center of the circle, in pixels
Expand All @@ -201,6 +227,18 @@ void gfx_drawCircle(point_t start, uint16_t r, color_t color);
*/
uint8_t gfx_getFontHeight(fontSize_t size);

/**
* Get font metrics for a given font
*/
void gfx_getFontMetrics(fontSize_t size, gfx_font_metrics_t *out);

/**
* Measure text
* @param size: text font size, defined as enum.
* @return text width and height as point_t coordinates
*/
point_t gfx_textSize(fontSize_t size, const char *buf);

/**
* Prints text on the screen at the specified coordinates.
* Reads text from a given char buffer
Expand Down Expand Up @@ -244,6 +282,13 @@ point_t gfx_printLine(uint8_t cur, uint8_t tot, int16_t startY, int16_t endY,
int16_t startX, fontSize_t size, textAlign_t alignment,
color_t color, const char* fmt, ... );

point_t gfx_drawTextRect(gfx_rect_t rect,
fontSize_t size,
textAlign_t halign,
textValign_t valign,
color_t color,
const char *buf);

/**
* Prints an error message surrounded by a red box on the screen.
* @param text: text to print.
Expand Down
45 changes: 14 additions & 31 deletions openrtx/include/core/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "hwconfig.h"
#include <stdbool.h>
#include <stdint.h>

typedef enum
{
Expand Down Expand Up @@ -40,45 +41,27 @@ typedef struct
int8_t utc_timezone; // Timezone, in units of half hours
bool gps_enabled; // GPS active
char callsign[10]; // Plaintext callsign
uint8_t display_timer : 4, // Standby timer
m17_can : 4; // M17 CAN
uint8_t vpLevel : 3, // Voice prompt level
vpPhoneticSpell : 1, // Phonetic spell enabled
macroMenuLatch : 1, // Automatic latch of macro menu
_reserved : 3;
uint8_t display_timer; // Standby timer
uint8_t m17_can; // M17 CAN
uint8_t vpLevel; // Voice prompt level
uint8_t vpPhoneticSpell; // Phonetic spell enabled
bool macroMenuLatch; // Automatic latch of macro menu
bool m17_can_rx; // Check M17 CAN on RX
char m17_dest[10]; // M17 destination
bool showBatteryIcon; // Battery display true: icon, false: percentage
bool gpsSetTime; // Use GPS to ajust RTC time
char M17_meta_text[53]; // M17 Meta Text to send
}
__attribute__((packed)) settings_t;
settings_t;

#ifdef __cplusplus
extern "C" {
#endif

static const settings_t default_settings =
{
100, // Brightness
#ifdef CONFIG_SCREEN_CONTRAST
CONFIG_DEFAULT_CONTRAST, // Contrast
#else
255, // Contrast
extern const settings_t default_settings;

#ifdef __cplusplus
}
#endif
4, // Squelch level, 4 = S3
0, // Vox level
0, // UTC Timezone
false, // GPS enabled
"", // Empty callsign
TIMER_30S, // 30 seconds
0, // M17 CAN
0, // Voice prompts off
0, // Phonetic spell off
1, // Automatic latch of macro menu enabled
0, // not used
false, // Check M17 CAN on RX
"", // Empty M17 destination
false, // Display battery icon
false, // Update RTC with GPS
"OpenRTX", // Default M17 meta text
};

#endif /* SETTINGS_H */
119 changes: 119 additions & 0 deletions openrtx/include/ui/ui_menu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* ui_menu.h */
#ifndef UI_MENU_H
#define UI_MENU_H

#include <stddef.h>
#include <stdint.h>

#include "ui/ui_screen.h"

typedef enum {
MENU_NODE_FOLDER,
MENU_NODE_ACTION,
MENU_NODE_VALUE,
MENU_NODE_UNIMPLEMENTED, // Marker which shows up in the UI
} MenuNodeKind;

typedef enum {
/// @brief Ask the callback to format the right-hand value text.
/// @param arg `MenuDrawValueArgs*`
MENU_CMD_DRAW_VALUE = 0,

/// @brief Called when user presses ENTER on this item while *not* in edit mode.
/// @param arg `const UiEvent*` (can be NULL if you don't need it)
MENU_CMD_SELECT,

/// @brief Called when we're about to enter the generic edit mode on this item.
/// @param arg `NULL`
MENU_CMD_EDIT_BEGIN,

/// @brief A key press while this item is in edit mode.
/// @param arg `const UiEvent*`
MENU_CMD_EDIT_KEY,

/// @brief User cancelled edit (ESC).
/// @param arg `NULL`
MENU_CMD_EDIT_CANCEL,

/// @brief User accepted edit (ESC).
/// @param arg `NULL`
MENU_CMD_EDIT_APPLY,
} MenuCmd;

typedef struct {
char *buf;
size_t buf_len;
} MenuDrawValueArgs;

typedef int (*MenuCb)(MenuCmd cmd, void *arg, void *cb_ctx);

/* type mask values for MENU_VAL_STR */
#define UI_TYPE_UPPERCASE 0x01
#define UI_TYPE_LOWERCASE 0x02
#define UI_TYPE_NUMBER 0x04
#define UI_TYPE_HEX 0x08
#define UI_TYPE_TEXT UI_TYPE_LOWERCASE | UI_TYPE_UPPERCASE
#define UI_TYPE_ALL UI_TYPE_LOWERCASE | UI_TYPE_UPPERCASE | UI_TYPE_NUMBER

typedef enum {

/// @brief general text entry
UI_STR_PROFILE_TEXT,

/// @brief callsigns / IDs
UI_STR_PROFILE_CALLSIGN,

/// @brief PINs, purely digits
UI_STR_PROFILE_NUMERIC,

/* TODO: Maybe more later? */
} UiStrProfile;

typedef enum {
MENU_VAL_BOOL,
MENU_VAL_U8,
MENU_VAL_I32,
MENU_VAL_ENUM,
MENU_VAL_STR,
} MenuValueKind;

typedef struct {
MenuValueKind kind;
void *ptr; // pointer to the underlying value
void (*on_change)(void *ptr); // optional side-effect on change

union {
struct { uint8_t min, max, step; bool wrap; } u8;
struct { int32_t min, max, step; bool wrap; } i32;
struct { const char *const *names; uint8_t count; } enm;
struct {
uint8_t max_len;
//uint8_t type_mask; TODO: Use this or `profile`?
UiStrProfile profile;
} str;
} u;
} MenuValueBinding;

typedef struct MenuItem MenuItem;
struct MenuItem {
MenuNodeKind kind;
const char *label;
uint8_t child_count;
const MenuItem *const *children; // only for FOLDER

const MenuValueBinding *binding; // generic value (if any)

MenuCb cb; // optional custom callback
void *cb_ctx; // context pointer for cb
};

/* The menu screen itself */
UiScreen *ui_get_menu_screen(void);

/* Helper to reset state to root and push the menu screen on the stack */
void ui_menu_open_root(void);

/* Root menu entry point (global tree) */
extern const MenuItem g_root_menu;

#endif
54 changes: 54 additions & 0 deletions openrtx/include/ui/ui_menu_dsl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef UI_MENU_DSL_H
#define UI_MENU_DSL_H

#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0]))

/// @brief Simple value item driven entirely by a MenuValueBinding
#define MENU_ITEM_VALUE_BINDING(_label, _binding_ptr) \
{ \
.kind = MENU_NODE_VALUE, \
.label = (_label), \
.child_count = 0, \
.children = NULL, \
.binding = (_binding_ptr), \
.cb = NULL, \
.cb_ctx = NULL, \
}

/// @brief Value item that is fully custom via callback
#define MENU_ITEM_VALUE_CB(_label, _cb, _ctx) \
{ \
.kind = MENU_NODE_VALUE, \
.label = (_label), \
.child_count = 0, \
.children = NULL, \
.binding = NULL, \
.cb = (_cb), \
.cb_ctx = (_ctx), \
}

/// @brief Folder whose children were declared as a separate array
#define MENU_FOLDER_FROM_CHILDREN(_label, _children_array) \
{ \
.kind = MENU_NODE_FOLDER, \
.label = (_label), \
.child_count = ARRAY_LEN(_children_array), \
.children = (_children_array), \
.binding = NULL, \
.cb = NULL, \
.cb_ctx = NULL, \
}

/// @brief Placeholder unimplemented item
#define MENU_ITEM_UNIMPLEMENTED(_label) \
{ \
.kind = MENU_NODE_UNIMPLEMENTED, \
.label = (_label), \
.child_count = 0, \
.children = NULL, \
.binding = NULL, \
.cb = NULL, \
.cb_ctx = NULL, \
}

#endif
Loading