Skip to content

Commit

Permalink
Keyboard Shift Mode (#1333)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
kallanreed committed Aug 1, 2023
1 parent 06b7a04 commit 2214533
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 44 deletions.
38 changes: 38 additions & 0 deletions firmware/application/bitmap.hpp
Expand Up @@ -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__*/
67 changes: 49 additions & 18 deletions firmware/application/ui/ui_alphanum.cpp
Expand Up @@ -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 {

Expand All @@ -38,6 +37,7 @@ AlphanumView::AlphanumView(
size_t n;

add_children({
&button_shift,
&labels,
&field_raw,
&text_raw_to_char,
Expand All @@ -49,16 +49,26 @@ 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;
button.on_highlight = [this](Button& button) {
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++;
}
Expand All @@ -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) {
Expand Down
50 changes: 37 additions & 13 deletions firmware/application/ui/ui_alphanum.hpp
Expand Up @@ -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 {
Expand All @@ -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!\"#'()*+-/:;=<>@[\\]?";

const std::pair<std::string, const char*> key_sets[3] = {
{"ABC", keys_upper},
{"abc", keys_lower},
{"123", keys_digit}};
enum class ShiftMode : uint8_t {
None,
Shift,
ShiftLock,
};

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()},
Expand All @@ -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},
""};
};

Expand Down
2 changes: 0 additions & 2 deletions firmware/application/ui/ui_textentry.cpp
Expand Up @@ -21,9 +21,7 @@
*/

#include "ui_textentry.hpp"
//#include "portapack_persistent_memory.hpp"
#include "ui_alphanum.hpp"
//#include "ui_handwrite.hpp"

using namespace portapack;

Expand Down
2 changes: 1 addition & 1 deletion firmware/application/ui/ui_textentry.hpp
Expand Up @@ -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"};
};

Expand Down
17 changes: 7 additions & 10 deletions firmware/common/ui_widget.cpp
Expand Up @@ -1188,7 +1188,7 @@ void NewButton::paint(Painter& painter) {
painter.draw_bitmap(
bmp_pos,
*bitmap_,
color_, // Color::green(), //fg,
color_,
bg);
}

Expand Down Expand Up @@ -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;
Expand All @@ -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).
Expand All @@ -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);
}

Expand Down
Binary file added firmware/graphics/icon_shift.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2214533

Please sign in to comment.