Usability improvements

Remove DMR from macro menu until we actually support it.
Remove print of M17 source callsign
Bank and channel visualization is more compact to make room for
additional data on a single screen.
Refactor mode screen to fit all data into a single screen.
pull/116/head
Niccolò Izzo 2022-09-15 15:59:52 +02:00
rodzic 91d608cc6b
commit 6a9ce50f6b
4 zmienionych plików z 187 dodań i 359 usunięć

Wyświetl plik

@ -53,7 +53,6 @@ openrtx_src = ['openrtx/src/core/state.c',
'openrtx/src/core/memory_profiling.cpp',
'openrtx/src/ui/ui.c',
'openrtx/src/ui/ui_main.c',
'openrtx/src/ui/ui_mode.c',
'openrtx/src/ui/ui_menu.c',
'openrtx/src/rtx/rtx.cpp',
'openrtx/src/rtx/OpMode_FM.cpp',

Wyświetl plik

@ -85,11 +85,9 @@ extern void _ui_drawVFOMiddle();
extern void _ui_drawMEMMiddle();
extern void _ui_drawVFOBottom();
extern void _ui_drawMEMBottom();
extern void _ui_drawMainVFO();
extern void _ui_drawMainVFO(ui_state_t* ui_state);
extern void _ui_drawMainVFOInput(ui_state_t* ui_state);
extern void _ui_drawMainMEM();
extern void _ui_drawModeVFO();
extern void _ui_drawModeMEM();
extern void _ui_drawMainMEM(ui_state_t* ui_state);
/* UI menu functions, their implementation is in "ui_menu.c" */
extern void _ui_drawMenuTop(ui_state_t* ui_state);
extern void _ui_drawMenuBank(ui_state_t* ui_state);
@ -787,8 +785,6 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
case 5:
// Cycle through radio modes
if(state.channel.mode == OPMODE_FM)
state.channel.mode = OPMODE_DMR;
else if(state.channel.mode == OPMODE_DMR)
state.channel.mode = OPMODE_M17;
else if(state.channel.mode == OPMODE_M17)
state.channel.mode = OPMODE_FM;
@ -995,66 +991,109 @@ void ui_updateFSM(bool *sync_rtx)
{
// VFO screen
case MAIN_VFO:
if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
// M17 Destination callsign input
if(ui_state.edit_mode)
{
// Increment TX and RX frequency of 12.5KHz
if(_ui_freq_check_limits(state.channel.rx_frequency + 12500) &&
_ui_freq_check_limits(state.channel.tx_frequency + 12500))
if(state.channel.mode == OPMODE_M17)
{
state.channel.rx_frequency += 12500;
state.channel.tx_frequency += 12500;
*sync_rtx = true;
if(msg.keys & KEY_ENTER)
{
_ui_textInputConfirm(ui_state.new_callsign);
// Save selected dst ID and disable input mode
strncpy(state.m17_data.dst_addr, ui_state.new_callsign, 10);
ui_state.edit_mode = false;
*sync_rtx = true;
}
else if(msg.keys & KEY_HASH)
{
// Save selected dst ID and disable input mode
strncpy(state.m17_data.dst_addr, "", 1);
ui_state.edit_mode = false;
*sync_rtx = true;
}
else if(msg.keys & KEY_ESC)
// Discard selected dst ID and disable input mode
ui_state.edit_mode = false;
else if(msg.keys & KEY_UP || msg.keys & KEY_DOWN ||
msg.keys & KEY_LEFT || msg.keys & KEY_RIGHT)
_ui_textInputDel(ui_state.new_callsign);
else if(input_isNumberPressed(msg))
_ui_textInputKeypad(ui_state.new_callsign, 9, msg, true);
break;
}
}
else if(msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT)
else
{
// Decrement TX and RX frequency of 12.5KHz
if(_ui_freq_check_limits(state.channel.rx_frequency - 12500) &&
_ui_freq_check_limits(state.channel.tx_frequency - 12500))
if(msg.keys & KEY_ENTER)
{
state.channel.rx_frequency -= 12500;
state.channel.tx_frequency -= 12500;
*sync_rtx = true;
// Save current main state
ui_state.last_main_state = state.ui_screen;
// Open Menu
state.ui_screen = MENU_TOP;
}
}
else if(msg.keys & KEY_ENTER)
{
// Save current main state
ui_state.last_main_state = state.ui_screen;
// Open Menu
state.ui_screen = MENU_TOP;
}
else if(msg.keys & KEY_ESC)
{
// Save VFO channel
state.vfo_channel = state.channel;
int result = _ui_fsm_loadChannel(state.channel_index, sync_rtx);
// Read successful and channel is valid
if(result != -1)
else if(msg.keys & KEY_HASH)
{
// Switch to MEM screen
state.ui_screen = MAIN_MEM;
// Enable dst ID input
ui_state.edit_mode = true;
// Reset text input variables
_ui_textInputReset(ui_state.new_callsign);
}
else if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
{
// Increment TX and RX frequency of 12.5KHz
if(_ui_freq_check_limits(state.channel.rx_frequency + 12500) &&
_ui_freq_check_limits(state.channel.tx_frequency + 12500))
{
state.channel.rx_frequency += 12500;
state.channel.tx_frequency += 12500;
*sync_rtx = true;
}
}
else if(msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT)
{
// Decrement TX and RX frequency of 12.5KHz
if(_ui_freq_check_limits(state.channel.rx_frequency - 12500) &&
_ui_freq_check_limits(state.channel.tx_frequency - 12500))
{
state.channel.rx_frequency -= 12500;
state.channel.tx_frequency -= 12500;
*sync_rtx = true;
}
}
else if(msg.keys & KEY_ENTER)
{
// Save current main state
ui_state.last_main_state = state.ui_screen;
// Open Menu
state.ui_screen = MENU_TOP;
}
else if(msg.keys & KEY_ESC)
{
// Save VFO channel
state.vfo_channel = state.channel;
int result = _ui_fsm_loadChannel(state.channel_index, sync_rtx);
// Read successful and channel is valid
if(result != -1)
{
// Switch to MEM screen
state.ui_screen = MAIN_MEM;
}
}
else if(input_isNumberPressed(msg))
{
// Open Frequency input screen
state.ui_screen = MAIN_VFO_INPUT;
// Reset input position and selection
ui_state.input_position = 1;
ui_state.input_set = SET_RX;
ui_state.new_rx_frequency = 0;
ui_state.new_tx_frequency = 0;
// Save pressed number to calculare frequency and show in GUI
ui_state.input_number = input_getPressedNumber(msg);
// Calculate portion of the new frequency
ui_state.new_rx_frequency = _ui_freq_add_digit(ui_state.new_rx_frequency,
ui_state.input_position, ui_state.input_number);
}
}
else if(msg.keys & KEY_F1)
{
// Switch to Digital Mode VFO screen
state.ui_screen = MODE_VFO;
}
else if(input_isNumberPressed(msg))
{
// Open Frequency input screen
state.ui_screen = MAIN_VFO_INPUT;
// Reset input position and selection
ui_state.input_position = 1;
ui_state.input_set = SET_RX;
ui_state.new_rx_frequency = 0;
ui_state.new_tx_frequency = 0;
// Save pressed number to calculare frequency and show in GUI
ui_state.input_number = input_getPressedNumber(msg);
// Calculate portion of the new frequency
ui_state.new_rx_frequency = _ui_freq_add_digit(ui_state.new_rx_frequency,
ui_state.input_position, ui_state.input_number);
}
break;
// VFO frequency input screen
@ -1084,42 +1123,10 @@ void ui_updateFSM(bool *sync_rtx)
break;
// MEM screen
case MAIN_MEM:
if(msg.keys & KEY_ENTER)
// M17 Destination callsign input
if(ui_state.edit_mode)
{
// Save current main state
ui_state.last_main_state = state.ui_screen;
// Open Menu
state.ui_screen = MENU_TOP;
}
else if(msg.keys & KEY_ESC)
{
// Restore VFO channel
state.channel = state.vfo_channel;
// Update RTX configuration
*sync_rtx = true;
// Switch to VFO screen
state.ui_screen = MAIN_VFO;
}
else if(msg.keys & KEY_F1)
{
// Switch to Digital Mode MEM screen
state.ui_screen = MODE_MEM;
}
else if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
{
_ui_fsm_loadChannel(state.channel_index + 1, sync_rtx);
}
else if(msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT)
{
_ui_fsm_loadChannel(state.channel_index - 1, sync_rtx);
}
break;
// Digital Mode VFO screen
case MODE_VFO:
if(state.channel.mode == OPMODE_M17)
{
// Dst ID input
if(ui_state.edit_mode)
if(state.channel.mode == OPMODE_M17)
{
if(msg.keys & KEY_ENTER)
{
@ -1129,6 +1136,13 @@ void ui_updateFSM(bool *sync_rtx)
ui_state.edit_mode = false;
*sync_rtx = true;
}
else if(msg.keys & KEY_HASH)
{
// Save selected dst ID and disable input mode
strncpy(state.m17_data.dst_addr, "", 1);
ui_state.edit_mode = false;
*sync_rtx = true;
}
else if(msg.keys & KEY_ESC)
// Discard selected dst ID and disable input mode
ui_state.edit_mode = false;
@ -1137,35 +1151,7 @@ void ui_updateFSM(bool *sync_rtx)
_ui_textInputDel(ui_state.new_callsign);
else if(input_isNumberPressed(msg))
_ui_textInputKeypad(ui_state.new_callsign, 9, msg, true);
}
else
{
if(msg.keys & KEY_ENTER)
{
// Save current main state
ui_state.last_main_state = state.ui_screen;
// Open Menu
state.ui_screen = MENU_TOP;
}
else if(msg.keys & KEY_ESC)
{
// Switch to VFO screen
state.ui_screen = MAIN_VFO;
}
else if(msg.keys & KEY_F1)
{
// Switch to Main VFO screen
state.ui_screen = MAIN_VFO;
}
else if(input_isNumberPressed(msg))
{
// Enable dst ID input
ui_state.edit_mode = true;
// Reset text input variables
_ui_textInputReset(ui_state.new_callsign);
// Type first character
_ui_textInputKeypad(ui_state.new_callsign, 9, msg, true);
}
break;
}
}
else
@ -1179,88 +1165,27 @@ void ui_updateFSM(bool *sync_rtx)
}
else if(msg.keys & KEY_ESC)
{
// Restore VFO channel
state.channel = state.vfo_channel;
// Update RTX configuration
*sync_rtx = true;
// Switch to VFO screen
state.ui_screen = MAIN_VFO;
}
else if(msg.keys & KEY_F1)
else if(msg.keys & KEY_HASH)
{
// Switch to Main VFO screen
state.ui_screen = MAIN_VFO;
// Enable dst ID input
ui_state.edit_mode = true;
// Reset text input variables
_ui_textInputReset(ui_state.new_callsign);
}
}
break;
// Digital Mode MEM screen
case MODE_MEM:
if(state.channel.mode == OPMODE_M17)
{
// Dst ID input
if(ui_state.edit_mode)
else if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
{
if(msg.keys & KEY_ENTER)
{
_ui_textInputConfirm(ui_state.new_callsign);
// Save selected dst ID and disable input mode
strncpy(state.m17_data.dst_addr, ui_state.new_callsign, 10);
ui_state.edit_mode = false;
*sync_rtx = true;
}
else if(msg.keys & KEY_ESC)
// Discard selected dst ID and disable input mode
ui_state.edit_mode = false;
else if(msg.keys & KEY_UP || msg.keys & KEY_DOWN ||
msg.keys & KEY_LEFT || msg.keys & KEY_RIGHT)
_ui_textInputDel(ui_state.new_callsign);
else if(input_isNumberPressed(msg))
_ui_textInputKeypad(ui_state.new_callsign, 9, msg, true);
_ui_fsm_loadChannel(state.channel_index + 1, sync_rtx);
}
else
else if(msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT)
{
if(msg.keys & KEY_ENTER)
{
// Save current main state
ui_state.last_main_state = state.ui_screen;
// Open Menu
state.ui_screen = MENU_TOP;
}
else if(msg.keys & KEY_ESC)
{
// Switch to MEM screen
state.ui_screen = MAIN_MEM;
}
else if(msg.keys & KEY_F1)
{
// Switch to Main MEM screen
state.ui_screen = MAIN_MEM;
}
else if(input_isNumberPressed(msg))
{
// Enable dst ID input
ui_state.edit_mode = true;
// Reset text input variables
_ui_textInputReset(ui_state.new_callsign);
// Type first character
_ui_textInputKeypad(ui_state.new_callsign, 9, msg, true);
}
}
}
else
{
if(msg.keys & KEY_ENTER)
{
// Save current main state
ui_state.last_main_state = state.ui_screen;
// Open Menu
state.ui_screen = MENU_TOP;
}
else if(msg.keys & KEY_ESC)
{
// Switch to MEM screen
state.ui_screen = MAIN_MEM;
}
else if(msg.keys & KEY_F1)
{
// Switch to Main MEM screen
state.ui_screen = MAIN_MEM;
_ui_fsm_loadChannel(state.channel_index - 1, sync_rtx);
}
}
break;
@ -1690,7 +1615,7 @@ bool ui_updateGUI()
{
// VFO main screen
case MAIN_VFO:
_ui_drawMainVFO();
_ui_drawMainVFO(&ui_state);
break;
// VFO frequency input screen
case MAIN_VFO_INPUT:
@ -1698,15 +1623,7 @@ bool ui_updateGUI()
break;
// MEM main screen
case MAIN_MEM:
_ui_drawMainMEM();
break;
// Digital Mode VFO screen
case MODE_VFO:
_ui_drawModeVFO(&ui_state);
break;
// Digital Mode MEM screen
case MODE_MEM:
_ui_drawModeMEM(&ui_state);
_ui_drawMainMEM(&ui_state);
break;
// Top menu screen
case MENU_TOP:

Wyświetl plik

@ -75,20 +75,68 @@ void _ui_drawMainTop()
void _ui_drawBankChannel()
{
// Print Bank name
if(!last_state.bank_enabled)
gfx_print(layout.line1_pos, layout.line1_font, TEXT_ALIGN_LEFT,
color_white, "bank: All channels");
else {
bankHdr_t bank = { 0 };
cps_readBankHeader(&bank, last_state.bank);
gfx_print(layout.line1_pos, layout.line1_font, TEXT_ALIGN_LEFT,
color_white, "bank: %.13s", bank.name);
// Print Bank number, channel number and Channel name
uint16_t b = (last_state.bank_enabled) ? last_state.bank : 0;
gfx_print(layout.line1_pos, layout.line1_font, TEXT_ALIGN_CENTER,
color_white, "%01d-%03d: %.12s",
b, last_state.channel_index + 1, last_state.channel.name);
}
void _ui_drawModeInfo(ui_state_t* ui_state)
{
char bw_str[8] = { 0 };
char encdec_str[9] = { 0 };
rtxStatus_t cfg = rtx_getCurrentStatus();
switch(last_state.channel.mode)
{
case OPMODE_FM:
// Get Bandwidth string
if(last_state.channel.bandwidth == BW_12_5)
snprintf(bw_str, 8, "12.5");
else if(last_state.channel.bandwidth == BW_20)
snprintf(bw_str, 8, "20");
else if(last_state.channel.bandwidth == BW_25)
snprintf(bw_str, 8, "25");
// Get encdec string
bool tone_tx_enable = last_state.channel.fm.txToneEn;
bool tone_rx_enable = last_state.channel.fm.rxToneEn;
if (tone_tx_enable && tone_rx_enable)
snprintf(encdec_str, 9, "E+D");
else if (tone_tx_enable && !tone_rx_enable)
snprintf(encdec_str, 9, "E");
else if (!tone_tx_enable && tone_rx_enable)
snprintf(encdec_str, 9, "D");
else
snprintf(encdec_str, 9, " ");
// Print Bandwidth, Tone and encdec info
gfx_print(layout.line2_pos, layout.line2_font, TEXT_ALIGN_CENTER,
color_white, "B:%s T:%4.1f S:%s",
bw_str, ctcss_tone[last_state.channel.fm.txTone]/10.0f,
encdec_str);
break;
case OPMODE_DMR:
// Print talkgroup
gfx_print(layout.line2_pos, layout.line2_font, TEXT_ALIGN_CENTER,
color_white, "TG:%s",
"");
break;
case OPMODE_M17:
{
// Print M17 Destination ID on line 3 of 3
char *dst = NULL;
if(ui_state->edit_mode)
dst = ui_state->new_callsign;
else
dst = (!strnlen(cfg.destination_address, 10)) ?
"Broadcast" : cfg.destination_address;
gfx_print(layout.line2_pos, layout.line2_font, TEXT_ALIGN_CENTER,
color_white, "#%s", dst);
break;
}
}
// Print Channel name
gfx_print(layout.line2_pos, layout.line2_font, TEXT_ALIGN_LEFT,
color_white, " %03d: %.12s",
last_state.channel_index + 1, last_state.channel.name);
}
void _ui_drawFrequency()
@ -195,10 +243,11 @@ void _ui_drawMainBottom()
}
}
void _ui_drawMainVFO()
void _ui_drawMainVFO(ui_state_t* ui_state)
{
gfx_clearScreen();
_ui_drawMainTop();
_ui_drawModeInfo(ui_state);
_ui_drawFrequency();
_ui_drawMainBottom();
}
@ -211,11 +260,12 @@ void _ui_drawMainVFOInput(ui_state_t* ui_state)
_ui_drawMainBottom();
}
void _ui_drawMainMEM()
void _ui_drawMainMEM(ui_state_t* ui_state)
{
gfx_clearScreen();
_ui_drawMainTop();
_ui_drawBankChannel();
_ui_drawModeInfo(ui_state);
_ui_drawFrequency();
_ui_drawMainBottom();
}

Wyświetl plik

@ -1,138 +0,0 @@
/***************************************************************************
* Copyright (C) 2021 - 2022 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN *
* Frederik Saraci IU2NRO *
* Silvano Seva IU2KWO *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <ui.h>
#include <string.h>
#include <rtx.h>
/* UI main screen helper functions, their implementation is in "ui_main.c" */
extern void _ui_drawMainTop();
extern void _ui_drawMainBottom();
void _ui_drawModeVFOFreq()
{
// Print VFO RX Frequency on line 1 of 3
gfx_printLine(1, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_big,
TEXT_ALIGN_CENTER, color_white, "%03lu.%05lu",
(unsigned long)last_state.channel.rx_frequency/1000000,
(unsigned long)last_state.channel.rx_frequency%1000000/10);
}
void _ui_drawMEMChannel()
{
// Print Channel name on line 1 of 3
gfx_printLine(1, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_CENTER, color_white, "%03d: %.12s",
last_state.channel_index, last_state.channel.name);
}
void _ui_drawModeDetails(ui_state_t* ui_state)
{
char bw_str[8] = { 0 };
char encdec_str[9] = { 0 };
rtxStatus_t cfg = rtx_getCurrentStatus();
switch(last_state.channel.mode)
{
case OPMODE_FM:
// Get Bandwith string
if(last_state.channel.bandwidth == BW_12_5)
snprintf(bw_str, 8, "12.5");
else if(last_state.channel.bandwidth == BW_20)
snprintf(bw_str, 8, "20");
else if(last_state.channel.bandwidth == BW_25)
snprintf(bw_str, 8, "25");
// Get encdec string
bool tone_tx_enable = last_state.channel.fm.txToneEn;
bool tone_rx_enable = last_state.channel.fm.rxToneEn;
if (tone_tx_enable && tone_rx_enable)
snprintf(encdec_str, 9, "E+D");
else if (tone_tx_enable && !tone_rx_enable)
snprintf(encdec_str, 9, "E");
else if (!tone_tx_enable && tone_rx_enable)
snprintf(encdec_str, 9, "D");
else
snprintf(encdec_str, 9, " ");
// Print Bandwidth info
gfx_printLine(2, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_LEFT, color_white, "BW:%s", bw_str);
// Print Tone and encdec info
gfx_printLine(3, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_LEFT, color_white, "T:%4.1f S:%s",
ctcss_tone[last_state.channel.fm.txTone]/10.0f,
encdec_str);
break;
case OPMODE_DMR:
// Print talkgroup on line 2 of 3
gfx_printLine(2, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_LEFT, color_white, "TG:");
// Print User ID on line 3 of 3
gfx_printLine(3, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_LEFT, color_white, "ID:");
break;
case OPMODE_M17:
// Print M17 Source ID on line 2 of 3
gfx_printLine(2, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_LEFT, color_white, "Src ID: %s", cfg.source_address);
// Print M17 Destination ID on line 3 of 3
if(ui_state->edit_mode)
{
gfx_printLine(3, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_LEFT, color_white, "Dst ID: %s_", ui_state->new_callsign);
}
else
{
gfx_printLine(3, 3, layout.top_h, SCREEN_HEIGHT - layout.bottom_h,
layout.horizontal_pad, layout.mode_font_small,
TEXT_ALIGN_LEFT, color_white, "Dst ID: %s", cfg.destination_address);
}
break;
}
}
void _ui_drawModeVFO(ui_state_t* ui_state)
{
gfx_clearScreen();
_ui_drawMainTop();
_ui_drawModeVFOFreq();
_ui_drawModeDetails(ui_state);
_ui_drawMainBottom();
}
void _ui_drawModeMEM(ui_state_t* ui_state)
{
gfx_clearScreen();
_ui_drawMainTop();
_ui_drawMEMChannel();
_ui_drawModeDetails(ui_state);
_ui_drawMainBottom();
}