You've already forked M5Cardputer
mirror of
https://github.com/m5stack/M5Cardputer.git
synced 2026-05-20 11:02:53 -07:00
168 lines
3.9 KiB
C++
168 lines
3.9 KiB
C++
/*
|
|
* SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
#include "ReplView.h"
|
|
|
|
void ReplView::init(LGFX_Sprite* canvas)
|
|
{
|
|
_canvas = canvas;
|
|
render_interface();
|
|
}
|
|
|
|
void ReplView::update()
|
|
{
|
|
update_keyboard_input();
|
|
update_cursor();
|
|
}
|
|
|
|
void ReplView::clearScreen()
|
|
{
|
|
_canvas->fillScreen(TFT_BLACK);
|
|
_canvas->setCursor(0, 0);
|
|
_canvas->pushSprite(0, 0);
|
|
}
|
|
|
|
void ReplView::showMessage(const std::string& message, uint16_t color)
|
|
{
|
|
_canvas->setTextColor(color, TFT_BLACK);
|
|
_canvas->println(message.c_str());
|
|
_canvas->setTextColor(TFT_WHITE, TFT_BLACK);
|
|
_canvas->pushSprite(0, 0);
|
|
}
|
|
|
|
void ReplView::showPrompt(const std::string& prompt_text)
|
|
{
|
|
_prompt_text = prompt_text;
|
|
render_prompt();
|
|
}
|
|
|
|
void ReplView::setPromptText(const std::string& prompt)
|
|
{
|
|
_prompt_text = prompt;
|
|
}
|
|
|
|
void ReplView::setInputBuffer(const std::string& text)
|
|
{
|
|
_input_buffer = text;
|
|
render_prompt();
|
|
}
|
|
|
|
void ReplView::clearInputBuffer()
|
|
{
|
|
_input_buffer.clear();
|
|
render_prompt();
|
|
}
|
|
|
|
void ReplView::render_interface()
|
|
{
|
|
_canvas->fillScreen(TFT_BLACK);
|
|
_canvas->setFont(&fonts::efontCN_16);
|
|
_canvas->setTextScroll(true);
|
|
_canvas->setCursor(0, 0);
|
|
_canvas->setTextSize(1);
|
|
_canvas->setBaseColor(TFT_BLACK);
|
|
_canvas->setTextColor(TFT_WHITE, TFT_BLACK);
|
|
|
|
if (onRenderTips) {
|
|
onRenderTips();
|
|
}
|
|
|
|
render_prompt();
|
|
}
|
|
|
|
void ReplView::render_prompt()
|
|
{
|
|
// 显示输入和光标
|
|
std::string display_text = _prompt_text + _input_buffer;
|
|
if (_cursor_state) {
|
|
display_text += "_";
|
|
} else {
|
|
display_text += " ";
|
|
}
|
|
|
|
// 获取当前光标位置
|
|
int cursor_y = _canvas->getCursorY();
|
|
|
|
// 清除当前行,确保光标被完全移除
|
|
_canvas->fillRect(0, cursor_y, _canvas->width(), 15, TFT_BLACK);
|
|
|
|
// 打印提示符和输入
|
|
_canvas->setCursor(0, cursor_y);
|
|
_canvas->setTextColor(TFT_WHITE, TFT_BLACK);
|
|
_canvas->print(display_text.c_str());
|
|
|
|
_canvas->pushSprite(0, 0);
|
|
}
|
|
|
|
void ReplView::handle_enter_key()
|
|
{
|
|
// 清除当前输入行并重新绘制不带光标的版本
|
|
int cursor_y = _canvas->getCursorY();
|
|
_canvas->fillRect(0, cursor_y, _canvas->width(), 15, TFT_BLACK);
|
|
_canvas->setCursor(0, cursor_y);
|
|
_canvas->setTextColor(TFT_WHITE, TFT_BLACK);
|
|
_canvas->print(_prompt_text.c_str());
|
|
_canvas->print(_input_buffer.c_str());
|
|
_canvas->println(); // 移动到下一行
|
|
|
|
// 通过回调执行命令
|
|
if (onCommand && !_input_buffer.empty()) {
|
|
onCommand(_input_buffer);
|
|
}
|
|
|
|
// 重置输入缓冲区并显示新提示符
|
|
if (autoClearPrompt) {
|
|
_input_buffer.clear();
|
|
}
|
|
render_prompt();
|
|
}
|
|
|
|
void ReplView::handle_backspace()
|
|
{
|
|
if (!_input_buffer.empty()) {
|
|
_input_buffer.pop_back();
|
|
|
|
// 清除更大区域确保旧光标被完全移除
|
|
int cursor_y = _canvas->getCursorY();
|
|
_canvas->fillRect(0, cursor_y, _canvas->width(), 15, TFT_BLACK);
|
|
|
|
// 重新绘制提示行
|
|
render_prompt();
|
|
}
|
|
}
|
|
|
|
void ReplView::update_cursor()
|
|
{
|
|
if (millis() - _cursor_update_time > CURSOR_BLINK_PERIOD) {
|
|
_cursor_state = !_cursor_state;
|
|
_cursor_update_time = millis();
|
|
render_prompt();
|
|
}
|
|
}
|
|
|
|
void ReplView::update_keyboard_input()
|
|
{
|
|
if (M5Cardputer.Keyboard.isChange()) {
|
|
if (M5Cardputer.Keyboard.isPressed()) {
|
|
auto& status = M5Cardputer.Keyboard.keysState();
|
|
|
|
if (status.enter) {
|
|
handle_enter_key();
|
|
return;
|
|
}
|
|
|
|
if (status.del) {
|
|
handle_backspace();
|
|
return;
|
|
}
|
|
|
|
for (auto& c : status.word) {
|
|
_input_buffer += c;
|
|
}
|
|
render_prompt();
|
|
}
|
|
}
|
|
}
|