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:
あく 2022-03-22 11:03:26 +03:00 committed by GitHub
parent e7dd715289
commit 6470aa8ff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 127 additions and 132 deletions

View File

@ -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
View 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;
} }

View File

@ -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' \

View File

@ -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