Gui: refactor text input module and fix debug on MacOS 12.3 (#1045)
* Gui: refactor text input module * Gui: simplify TextInput input processing * Gui: simplify TextInput consume flag processing * Fix debug with gdb broken by MacOS 12.3
This commit is contained in:
parent
e7dd715289
commit
6470aa8ff9
3
Brewfile
3
Brewfile
@ -1,7 +1,8 @@
|
|||||||
cask "gcc-arm-embedded"
|
cask "gcc-arm-embedded"
|
||||||
brew "protobuf"
|
brew "protobuf"
|
||||||
|
brew "gdb"
|
||||||
brew "heatshrink"
|
brew "heatshrink"
|
||||||
brew "open-ocd"
|
brew "open-ocd"
|
||||||
brew "clang-format"
|
brew "clang-format"
|
||||||
brew "dfu-util"
|
brew "dfu-util"
|
||||||
brew "imagemagick"
|
brew "imagemagick"
|
||||||
|
240
applications/gui/modules/text_input.c
Executable file → Normal file
240
applications/gui/modules/text_input.c
Executable file → Normal file
@ -259,173 +259,159 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_up(TextInput* text_input) {
|
static void text_input_handle_up(TextInput* text_input, TextInputModel* model) {
|
||||||
with_view_model(
|
if(model->selected_row > 0) {
|
||||||
text_input->view, (TextInputModel * model) {
|
model->selected_row--;
|
||||||
if(model->selected_row > 0) {
|
if(model->selected_column > get_row_size(model->selected_row) - 6) {
|
||||||
model->selected_row--;
|
model->selected_column = model->selected_column + 1;
|
||||||
if(model->selected_column > get_row_size(model->selected_row) - 6) {
|
}
|
||||||
model->selected_column = model->selected_column + 1;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_down(TextInput* text_input) {
|
static void text_input_handle_down(TextInput* text_input, TextInputModel* model) {
|
||||||
with_view_model(
|
if(model->selected_row < keyboard_row_count - 1) {
|
||||||
text_input->view, (TextInputModel * model) {
|
model->selected_row++;
|
||||||
if(model->selected_row < keyboard_row_count - 1) {
|
if(model->selected_column > get_row_size(model->selected_row) - 4) {
|
||||||
model->selected_row++;
|
model->selected_column = model->selected_column - 1;
|
||||||
if(model->selected_column > get_row_size(model->selected_row) - 4) {
|
}
|
||||||
model->selected_column = model->selected_column - 1;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_left(TextInput* text_input) {
|
static void text_input_handle_left(TextInput* text_input, TextInputModel* model) {
|
||||||
with_view_model(
|
if(model->selected_column > 0) {
|
||||||
text_input->view, (TextInputModel * model) {
|
model->selected_column--;
|
||||||
if(model->selected_column > 0) {
|
} else {
|
||||||
model->selected_column--;
|
model->selected_column = get_row_size(model->selected_row) - 1;
|
||||||
} else {
|
}
|
||||||
model->selected_column = get_row_size(model->selected_row) - 1;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_right(TextInput* text_input) {
|
static void text_input_handle_right(TextInput* text_input, TextInputModel* model) {
|
||||||
with_view_model(
|
if(model->selected_column < get_row_size(model->selected_row) - 1) {
|
||||||
text_input->view, (TextInputModel * model) {
|
model->selected_column++;
|
||||||
if(model->selected_column < get_row_size(model->selected_row) - 1) {
|
} else {
|
||||||
model->selected_column++;
|
model->selected_column = 0;
|
||||||
} else {
|
}
|
||||||
model->selected_column = 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_ok(TextInput* text_input, bool shift) {
|
static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, bool shift) {
|
||||||
with_view_model(
|
char selected = get_selected_char(model);
|
||||||
text_input->view, (TextInputModel * model) {
|
uint8_t text_length = strlen(model->text_buffer);
|
||||||
char selected = get_selected_char(model);
|
|
||||||
uint8_t text_length = strlen(model->text_buffer);
|
|
||||||
|
|
||||||
if(shift) {
|
if(shift) {
|
||||||
selected = char_to_uppercase(selected);
|
selected = char_to_uppercase(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selected == ENTER_KEY) {
|
if(selected == ENTER_KEY) {
|
||||||
if(model->validator_callback && (!model->validator_callback(
|
if(model->validator_callback &&
|
||||||
model->text_buffer,
|
(!model->validator_callback(
|
||||||
model->validator_text,
|
model->text_buffer, model->validator_text, model->validator_callback_context))) {
|
||||||
model->validator_callback_context))) {
|
model->valadator_message_visible = true;
|
||||||
model->valadator_message_visible = true;
|
osTimerStart(text_input->timer, osKernelGetTickFreq() * 4);
|
||||||
osTimerStart(text_input->timer, osKernelGetTickFreq() * 4);
|
} else if(model->callback != 0 && text_length > 0) {
|
||||||
} else if(model->callback != 0 && text_length > 0) {
|
model->callback(model->callback_context);
|
||||||
model->callback(model->callback_context);
|
}
|
||||||
}
|
} else if(selected == BACKSPACE_KEY) {
|
||||||
} else if(selected == BACKSPACE_KEY) {
|
text_input_backspace_cb(model);
|
||||||
text_input_backspace_cb(model);
|
} else if(text_length < (model->text_buffer_size - 1)) {
|
||||||
} else if(text_length < (model->text_buffer_size - 1)) {
|
if(model->clear_default_text) {
|
||||||
if(model->clear_default_text) {
|
text_length = 0;
|
||||||
text_length = 0;
|
}
|
||||||
}
|
if(text_length == 0 && char_is_lowercase(selected)) {
|
||||||
if(text_length == 0 && char_is_lowercase(selected)) {
|
selected = char_to_uppercase(selected);
|
||||||
selected = char_to_uppercase(selected);
|
}
|
||||||
}
|
model->text_buffer[text_length] = selected;
|
||||||
model->text_buffer[text_length] = selected;
|
model->text_buffer[text_length + 1] = 0;
|
||||||
model->text_buffer[text_length + 1] = 0;
|
}
|
||||||
}
|
model->clear_default_text = false;
|
||||||
model->clear_default_text = false;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool text_input_view_input_callback(InputEvent* event, void* context) {
|
static bool text_input_view_input_callback(InputEvent* event, void* context) {
|
||||||
TextInput* text_input = context;
|
TextInput* text_input = context;
|
||||||
furi_assert(text_input);
|
furi_assert(text_input);
|
||||||
|
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
|
|
||||||
if(event->type == InputTypeShort) {
|
// Acquire model
|
||||||
with_view_model(
|
TextInputModel* model = view_get_model(text_input->view);
|
||||||
text_input->view, (TextInputModel * model) {
|
|
||||||
if(model->valadator_message_visible) {
|
if((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
|
||||||
if(event->key == InputKeyBack) {
|
model->valadator_message_visible) {
|
||||||
consumed = true;
|
model->valadator_message_visible = false;
|
||||||
}
|
consumed = true;
|
||||||
}
|
} else if(event->type == InputTypeShort) {
|
||||||
model->valadator_message_visible = false;
|
consumed = true;
|
||||||
return false;
|
|
||||||
});
|
|
||||||
switch(event->key) {
|
switch(event->key) {
|
||||||
case InputKeyUp:
|
case InputKeyUp:
|
||||||
text_input_handle_up(text_input);
|
text_input_handle_up(text_input, model);
|
||||||
consumed = true;
|
|
||||||
break;
|
break;
|
||||||
case InputKeyDown:
|
case InputKeyDown:
|
||||||
text_input_handle_down(text_input);
|
text_input_handle_down(text_input, model);
|
||||||
consumed = true;
|
|
||||||
break;
|
break;
|
||||||
case InputKeyLeft:
|
case InputKeyLeft:
|
||||||
text_input_handle_left(text_input);
|
text_input_handle_left(text_input, model);
|
||||||
consumed = true;
|
|
||||||
break;
|
break;
|
||||||
case InputKeyRight:
|
case InputKeyRight:
|
||||||
text_input_handle_right(text_input);
|
text_input_handle_right(text_input, model);
|
||||||
consumed = true;
|
|
||||||
break;
|
break;
|
||||||
case InputKeyOk:
|
case InputKeyOk:
|
||||||
text_input_handle_ok(text_input, false);
|
text_input_handle_ok(text_input, model, false);
|
||||||
consumed = true;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
consumed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if(event->type == InputTypeLong) {
|
||||||
|
|
||||||
if((event->type == InputTypeLong || event->type == InputTypeRepeat) &&
|
|
||||||
event->key == InputKeyBack) {
|
|
||||||
with_view_model(
|
|
||||||
text_input->view, (TextInputModel * model) {
|
|
||||||
if(model->valadator_message_visible) {
|
|
||||||
model->valadator_message_visible = false;
|
|
||||||
} else {
|
|
||||||
text_input_backspace_cb(model);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
|
||||||
|
|
||||||
// Allow shift key on long press
|
|
||||||
if(event->type == InputTypeLong && event->key == InputKeyOk) {
|
|
||||||
with_view_model(
|
|
||||||
text_input->view, (TextInputModel * model) {
|
|
||||||
if(model->valadator_message_visible) {
|
|
||||||
if(event->key == InputKeyBack) {
|
|
||||||
consumed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
model->valadator_message_visible = false;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
switch(event->key) {
|
switch(event->key) {
|
||||||
|
case InputKeyUp:
|
||||||
|
text_input_handle_up(text_input, model);
|
||||||
|
break;
|
||||||
|
case InputKeyDown:
|
||||||
|
text_input_handle_down(text_input, model);
|
||||||
|
break;
|
||||||
|
case InputKeyLeft:
|
||||||
|
text_input_handle_left(text_input, model);
|
||||||
|
break;
|
||||||
|
case InputKeyRight:
|
||||||
|
text_input_handle_right(text_input, model);
|
||||||
|
break;
|
||||||
case InputKeyOk:
|
case InputKeyOk:
|
||||||
text_input_handle_ok(text_input, true);
|
text_input_handle_ok(text_input, model, true);
|
||||||
consumed = true;
|
break;
|
||||||
|
case InputKeyBack:
|
||||||
|
text_input_backspace_cb(model);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
consumed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if(event->type == InputTypeRepeat) {
|
||||||
|
consumed = true;
|
||||||
|
switch(event->key) {
|
||||||
|
case InputKeyUp:
|
||||||
|
text_input_handle_up(text_input, model);
|
||||||
|
break;
|
||||||
|
case InputKeyDown:
|
||||||
|
text_input_handle_down(text_input, model);
|
||||||
|
break;
|
||||||
|
case InputKeyLeft:
|
||||||
|
text_input_handle_left(text_input, model);
|
||||||
|
break;
|
||||||
|
case InputKeyRight:
|
||||||
|
text_input_handle_right(text_input, model);
|
||||||
|
break;
|
||||||
|
case InputKeyBack:
|
||||||
|
text_input_backspace_cb(model);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
consumed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Commit model
|
||||||
|
view_commit_model(text_input->view, consumed);
|
||||||
|
|
||||||
return consumed;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ upload: $(OBJ_DIR)/upload
|
|||||||
|
|
||||||
.PHONY: debug
|
.PHONY: debug
|
||||||
debug: flash
|
debug: flash
|
||||||
arm-none-eabi-gdb-py \
|
$(GDB) \
|
||||||
-ex 'target extended-remote | openocd -c "gdb_port pipe" $(OPENOCD_OPTS)' \
|
-ex 'target extended-remote | openocd -c "gdb_port pipe" $(OPENOCD_OPTS)' \
|
||||||
-ex "set confirm off" \
|
-ex "set confirm off" \
|
||||||
-ex "source ../debug/FreeRTOS/FreeRTOS.py" \
|
-ex "source ../debug/FreeRTOS/FreeRTOS.py" \
|
||||||
@ -105,7 +105,7 @@ debug: flash
|
|||||||
|
|
||||||
.PHONY: debug_other
|
.PHONY: debug_other
|
||||||
debug_other:
|
debug_other:
|
||||||
arm-none-eabi-gdb-py \
|
$(GDB) \
|
||||||
-ex 'target extended-remote | openocd -c "gdb_port pipe" $(OPENOCD_OPTS)' \
|
-ex 'target extended-remote | openocd -c "gdb_port pipe" $(OPENOCD_OPTS)' \
|
||||||
-ex "set confirm off" \
|
-ex "set confirm off" \
|
||||||
-ex "source ../debug/PyCortexMDebug/PyCortexMDebug.py" \
|
-ex "source ../debug/PyCortexMDebug/PyCortexMDebug.py" \
|
||||||
@ -113,7 +113,7 @@ debug_other:
|
|||||||
|
|
||||||
.PHONY: blackmagic
|
.PHONY: blackmagic
|
||||||
blackmagic:
|
blackmagic:
|
||||||
arm-none-eabi-gdb-py \
|
$(GDB) \
|
||||||
-ex 'target extended-remote $(BLACKMAGIC)' \
|
-ex 'target extended-remote $(BLACKMAGIC)' \
|
||||||
-ex 'monitor swdp_scan' \
|
-ex 'monitor swdp_scan' \
|
||||||
-ex 'monitor debug_bmp enable' \
|
-ex 'monitor debug_bmp enable' \
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
OS := $(shell uname -s)
|
||||||
|
|
||||||
# Compiller
|
# Compiller
|
||||||
ifeq ($(TOOLCHAIN), arm)
|
ifeq ($(TOOLCHAIN), arm)
|
||||||
PREFIX = arm-none-eabi-
|
PREFIX = arm-none-eabi-
|
||||||
@ -15,6 +17,12 @@ SZ = $(PREFIX)size
|
|||||||
HEX = $(CP) -O ihex
|
HEX = $(CP) -O ihex
|
||||||
BIN = $(CP) -O binary -S
|
BIN = $(CP) -O binary -S
|
||||||
|
|
||||||
|
ifeq ($(OS), Darwin)
|
||||||
|
GDB = gdb
|
||||||
|
else
|
||||||
|
GDB = $(PREFIX)gdb-py
|
||||||
|
endif
|
||||||
|
|
||||||
DEBUG ?= 1
|
DEBUG ?= 1
|
||||||
COMPACT ?= 0
|
COMPACT ?= 0
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
@ -27,4 +35,4 @@ endif
|
|||||||
|
|
||||||
CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)"
|
CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)"
|
||||||
CPPFLAGS += -fno-threadsafe-statics -fno-use-cxa-atexit -fno-exceptions -fno-rtti
|
CPPFLAGS += -fno-threadsafe-statics -fno-use-cxa-atexit -fno-exceptions -fno-rtti
|
||||||
LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -n
|
LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -n
|
||||||
|
Loading…
Reference in New Issue
Block a user