mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-23 14:29:23 -05:00
Keyboard Shift Mode (#1333)
* Add "shift" concept to keyboard * Better shift colors * Better keybaord layout for symbols * Start ShiftLocked for consistency with previous UX. * Fix number layout * PR and test-drive feedback
This commit is contained in:
parent
06b7a0419e
commit
2214533894
@ -5607,6 +5607,44 @@ static constexpr Bitmap bitmap_icon_speaker_and_headphones_mute{
|
||||
{16, 16},
|
||||
bitmap_icon_speaker_and_headphones_mute_data};
|
||||
|
||||
static constexpr uint8_t bitmap_icon_shift_data[] = {
|
||||
0x00,
|
||||
0x00,
|
||||
0x80,
|
||||
0x00,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xE0,
|
||||
0x03,
|
||||
0xF0,
|
||||
0x07,
|
||||
0xF8,
|
||||
0x0F,
|
||||
0xFC,
|
||||
0x1F,
|
||||
0xE0,
|
||||
0x03,
|
||||
0xE0,
|
||||
0x03,
|
||||
0xE0,
|
||||
0x03,
|
||||
0x20,
|
||||
0x02,
|
||||
0xE0,
|
||||
0x03,
|
||||
0x20,
|
||||
0x02,
|
||||
0xE0,
|
||||
0x03,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
static constexpr Bitmap bitmap_icon_shift{
|
||||
{16, 16},
|
||||
bitmap_icon_shift_data};
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
#endif /*__BITMAP_HPP__*/
|
||||
|
@ -22,11 +22,10 @@
|
||||
|
||||
#include "ui_alphanum.hpp"
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "hackrf_hal.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -38,6 +37,7 @@ AlphanumView::AlphanumView(
|
||||
size_t n;
|
||||
|
||||
add_children({
|
||||
&button_shift,
|
||||
&labels,
|
||||
&field_raw,
|
||||
&text_raw_to_char,
|
||||
@ -49,6 +49,16 @@ AlphanumView::AlphanumView(
|
||||
this->on_button(button);
|
||||
};
|
||||
|
||||
button_shift.set_vertical_center(true);
|
||||
button_shift.on_select = [this]() {
|
||||
incr(shift_mode);
|
||||
|
||||
if (shift_mode > ShiftMode::ShiftLock)
|
||||
shift_mode = ShiftMode::None;
|
||||
|
||||
refresh_keys();
|
||||
};
|
||||
|
||||
n = 0;
|
||||
for (auto& button : buttons) {
|
||||
button.id = n;
|
||||
@ -56,9 +66,9 @@ AlphanumView::AlphanumView(
|
||||
focused_button = button.id;
|
||||
};
|
||||
button.on_select = button_fn;
|
||||
button.set_parent_rect({static_cast<Coord>((n % 5) * (240 / 5)),
|
||||
button.set_parent_rect({static_cast<Coord>((n % 5) * (screen_width / 5)),
|
||||
static_cast<Coord>((n / 5) * 38 + 24),
|
||||
240 / 5, 38});
|
||||
screen_width / 5, 38});
|
||||
add_child(&button);
|
||||
n++;
|
||||
}
|
||||
@ -78,38 +88,59 @@ AlphanumView::AlphanumView(
|
||||
char_add(field_raw.value());
|
||||
};
|
||||
|
||||
// make text_raw_to_char widget display the char value from field_raw
|
||||
field_raw.on_change = [this](auto) {
|
||||
text_raw_to_char.set(std::string{static_cast<char>(field_raw.value())});
|
||||
};
|
||||
}
|
||||
|
||||
void AlphanumView::set_mode(const uint32_t new_mode) {
|
||||
size_t n = 0;
|
||||
|
||||
if (new_mode < 3)
|
||||
void AlphanumView::set_mode(uint32_t new_mode, ShiftMode new_shift_mode) {
|
||||
if (new_mode < std::size(key_sets))
|
||||
mode = new_mode;
|
||||
else
|
||||
mode = 0;
|
||||
|
||||
const char* key_list = key_sets[mode].second;
|
||||
shift_mode = new_shift_mode;
|
||||
refresh_keys();
|
||||
|
||||
if (mode + 1 < std::size(key_sets))
|
||||
button_mode.set_text(key_sets[mode + 1].name);
|
||||
else
|
||||
button_mode.set_text(key_sets[0].name);
|
||||
}
|
||||
|
||||
void AlphanumView::refresh_keys() {
|
||||
auto key_list = shift_mode == ShiftMode::None
|
||||
? key_sets[mode].normal
|
||||
: key_sets[mode].shifted;
|
||||
|
||||
size_t n = 0;
|
||||
for (auto& button : buttons) {
|
||||
const std::string label{
|
||||
key_list[n]};
|
||||
button.set_text(label);
|
||||
button.set_text(std::string{key_list[n]});
|
||||
n++;
|
||||
}
|
||||
|
||||
if (mode < 2)
|
||||
button_mode.set_text(key_sets[mode + 1].first);
|
||||
else
|
||||
button_mode.set_text(key_sets[0].first);
|
||||
switch (shift_mode) {
|
||||
case ShiftMode::None:
|
||||
button_shift.set_color(Color::dark_grey());
|
||||
break;
|
||||
case ShiftMode::Shift:
|
||||
button_shift.set_color(Color::black());
|
||||
break;
|
||||
case ShiftMode::ShiftLock:
|
||||
button_shift.set_color(Color::dark_blue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphanumView::on_button(Button& button) {
|
||||
const auto c = button.text()[0];
|
||||
char_add(c);
|
||||
|
||||
// TODO: Consolidate shift handling.
|
||||
if (shift_mode == ShiftMode::Shift) {
|
||||
shift_mode = ShiftMode::None;
|
||||
refresh_keys();
|
||||
}
|
||||
}
|
||||
|
||||
bool AlphanumView::on_encoder(const EncoderEvent delta) {
|
||||
|
@ -29,6 +29,10 @@
|
||||
#include "ui_textentry.hpp"
|
||||
#include "ui_menu.hpp"
|
||||
|
||||
// TODO: Building this as a custom widget instead of using
|
||||
// all the Button controls would save a considerable amount of RAM.
|
||||
// The Buttons each have a backing string but these only need one char.
|
||||
|
||||
namespace ui {
|
||||
|
||||
class AlphanumView : public TextEntryView {
|
||||
@ -43,22 +47,42 @@ class AlphanumView : public TextEntryView {
|
||||
bool on_encoder(const EncoderEvent delta) override;
|
||||
|
||||
private:
|
||||
const char* const keys_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ, ._";
|
||||
const char* const keys_lower = "abcdefghijklmnopqrstuvwxyz, ._";
|
||||
const char* const keys_digit = "0123456789!\"#'()*+-/:;=<>@[\\]?";
|
||||
enum class ShiftMode : uint8_t {
|
||||
None,
|
||||
Shift,
|
||||
ShiftLock,
|
||||
};
|
||||
|
||||
const std::pair<std::string, const char*> key_sets[3] = {
|
||||
{"ABC", keys_upper},
|
||||
{"abc", keys_lower},
|
||||
{"123", keys_digit}};
|
||||
const char* const keys_lower = "abcdefghijklmnopqrstuvwxyz, .";
|
||||
const char* const keys_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ, .";
|
||||
const char* const keys_digit = "1234567890()'`\"+-*/=<>_\\!?, .";
|
||||
const char* const keys_symbl = "!@#$%^&*()[]'`\"{}|:;<>-_~?, .";
|
||||
|
||||
struct key_set_t {
|
||||
const char* name;
|
||||
const char* normal;
|
||||
const char* shifted;
|
||||
};
|
||||
|
||||
const key_set_t key_sets[2] = {
|
||||
{"abc", keys_lower, keys_upper},
|
||||
{"123", keys_digit, keys_symbl}};
|
||||
|
||||
int16_t focused_button = 0;
|
||||
uint32_t mode = 0; // Uppercase
|
||||
uint32_t mode = 0; // Letters.
|
||||
ShiftMode shift_mode = ShiftMode::None;
|
||||
|
||||
void set_mode(const uint32_t new_mode);
|
||||
void set_mode(uint32_t new_mode, ShiftMode new_shift_mode = ShiftMode::None);
|
||||
void refresh_keys();
|
||||
void on_button(Button& button);
|
||||
|
||||
std::array<Button, 30> buttons{};
|
||||
std::array<Button, 29> buttons{};
|
||||
|
||||
NewButton button_shift{
|
||||
{192, 214, screen_width / 5, 38},
|
||||
{},
|
||||
&bitmap_icon_shift,
|
||||
Color::dark_grey()};
|
||||
|
||||
Labels labels{
|
||||
{{1 * 8, 33 * 8}, "Raw:", Color::light_grey()},
|
||||
@ -76,11 +100,11 @@ class AlphanumView : public TextEntryView {
|
||||
"0"};
|
||||
|
||||
Button button_delete{
|
||||
{9 * 8, 33 * 8, 6 * 8, 32},
|
||||
{9 * 8, 32 * 8 - 3, 7 * 8, 3 * 16 + 3},
|
||||
"<DEL"};
|
||||
|
||||
Button button_mode{
|
||||
{16 * 8, 33 * 8, 5 * 8, 32},
|
||||
{16 * 8, 32 * 8 - 3, 5 * 8, 3 * 16 + 3},
|
||||
""};
|
||||
};
|
||||
|
||||
|
@ -21,9 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "ui_textentry.hpp"
|
||||
//#include "portapack_persistent_memory.hpp"
|
||||
#include "ui_alphanum.hpp"
|
||||
//#include "ui_handwrite.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
|
@ -50,7 +50,7 @@ class TextEntryView : public View {
|
||||
|
||||
TextEdit text_input;
|
||||
Button button_ok{
|
||||
{22 * 8, 33 * 8, 7 * 8, 32},
|
||||
{21 * 8, 32 * 8 - 3, 9 * 8, 3 * 16 + 3},
|
||||
"OK"};
|
||||
};
|
||||
|
||||
|
@ -1188,7 +1188,7 @@ void NewButton::paint(Painter& painter) {
|
||||
painter.draw_bitmap(
|
||||
bmp_pos,
|
||||
*bitmap_,
|
||||
color_, // Color::green(), //fg,
|
||||
color_,
|
||||
bg);
|
||||
}
|
||||
|
||||
@ -1667,8 +1667,6 @@ void TextEdit::char_delete() {
|
||||
}
|
||||
|
||||
void TextEdit::paint(Painter& painter) {
|
||||
constexpr int char_width = 8;
|
||||
|
||||
auto rect = screen_rect();
|
||||
auto text_style = has_focus() ? style().invert() : style();
|
||||
auto offset = 0;
|
||||
@ -1677,15 +1675,14 @@ void TextEdit::paint(Painter& painter) {
|
||||
if (cursor_pos_ >= char_count_)
|
||||
offset = cursor_pos_ - char_count_ + 1;
|
||||
|
||||
// Clear the control.
|
||||
painter.fill_rectangle(rect, text_style.background);
|
||||
|
||||
// Draw the text starting at the offset.
|
||||
for (uint32_t i = 0; i < char_count_ && i + offset < text_.length(); i++) {
|
||||
for (uint32_t i = 0; i < char_count_; i++) {
|
||||
// Using draw_char to blank the rest of the line with spaces produces less flicker.
|
||||
auto c = (i + offset < text_.length()) ? text_[i + offset] : ' ';
|
||||
|
||||
painter.draw_char(
|
||||
{rect.location().x() + (static_cast<int>(i) * char_width), rect.location().y()},
|
||||
text_style,
|
||||
text_[i + offset]);
|
||||
text_style, c);
|
||||
}
|
||||
|
||||
// Determine cursor position on screen (either the cursor position or the last char).
|
||||
@ -1698,7 +1695,7 @@ void TextEdit::paint(Painter& painter) {
|
||||
painter.draw_char(cursor_point, cursor_style, text_[cursor_pos_]);
|
||||
|
||||
// Draw the cursor.
|
||||
Rect cursor_box{cursor_point, {char_width, 16}};
|
||||
Rect cursor_box{cursor_point, {char_width, char_height}};
|
||||
painter.draw_rectangle(cursor_box, cursor_style.background);
|
||||
}
|
||||
|
||||
|
BIN
firmware/graphics/icon_shift.png
Normal file
BIN
firmware/graphics/icon_shift.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 267 B |
Loading…
Reference in New Issue
Block a user