mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[code] Navigation in the console history.
The user can copy previous commands or results, into the clipboard or in the console prompt. Change-Id: I280fff2d4937f4d17ab6c8907d6e5c359a322372
This commit is contained in:
@@ -34,16 +34,16 @@ void HistoryViewCell::layoutSubviews() {
|
||||
KDCoordinate width = bounds().width();
|
||||
KDCoordinate height = bounds().height();
|
||||
KDSize inputSize = m_inputView.minimalSizeForOptimalDisplay();
|
||||
if (inputSize.width() + k_digitHorizontalMargin > width) {
|
||||
m_inputView.setFrame(KDRect(k_digitHorizontalMargin, k_digitVerticalMargin, width - k_digitHorizontalMargin, inputSize.height()));
|
||||
if (inputSize.width() + Metric::HistoryHorizontalMargin > width) {
|
||||
m_inputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, k_digitVerticalMargin, width - Metric::HistoryHorizontalMargin, inputSize.height()));
|
||||
} else {
|
||||
m_inputView.setFrame(KDRect(k_digitHorizontalMargin, k_digitVerticalMargin, inputSize.width(), inputSize.height()));
|
||||
m_inputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, k_digitVerticalMargin, inputSize.width(), inputSize.height()));
|
||||
}
|
||||
KDSize outputSize = m_outputView.minimalSizeForOptimalDisplay();
|
||||
if (outputSize.width() + k_digitHorizontalMargin > width) {
|
||||
m_outputView.setFrame(KDRect(k_digitHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, width - k_digitHorizontalMargin, height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
if (outputSize.width() + Metric::HistoryHorizontalMargin > width) {
|
||||
m_outputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, width - Metric::HistoryHorizontalMargin, height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
} else {
|
||||
m_outputView.setFrame(KDRect(width - outputSize.width() - k_digitHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, outputSize.width(), height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
m_outputView.setFrame(KDRect(width - outputSize.width() - Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, outputSize.width(), height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ public:
|
||||
void layoutSubviews() override;
|
||||
void didBecomeFirstResponder() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
constexpr static KDCoordinate k_digitHorizontalMargin = 10;
|
||||
constexpr static KDCoordinate k_digitVerticalMargin = 5;
|
||||
SubviewType selectedSubviewType();
|
||||
void setSelectedSubviewType(HistoryViewCell::SubviewType subviewType);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "console_controller.h"
|
||||
#include "script.h"
|
||||
#include <apps/i18n.h>
|
||||
#include "app.h"
|
||||
#include <apps/i18n.h>
|
||||
#include <assert.h>
|
||||
|
||||
extern "C" {
|
||||
@@ -12,9 +12,10 @@ namespace Code {
|
||||
|
||||
ConsoleController::ConsoleController(Responder * parentResponder, ScriptStore * scriptStore) :
|
||||
ViewController(parentResponder),
|
||||
SelectableTableViewDataSource(),
|
||||
TextFieldDelegate(),
|
||||
m_rowHeight(KDText::charSize(k_fontSize).height()),
|
||||
m_tableView(this, this, 0, 0),
|
||||
m_selectableTableView(this, this, 0, 1, 0, Metric::CommonRightMargin, 3, Metric::HistoryHorizontalMargin, this, this, true, true, KDColorWhite),
|
||||
m_editCell(this, this),
|
||||
m_pythonHeap(nullptr),
|
||||
m_scriptStore(scriptStore)
|
||||
@@ -67,7 +68,7 @@ void ConsoleController::runAndPrintForCommand(const char * command) {
|
||||
runCode(command);
|
||||
flushOutputAccumulationBufferToStore();
|
||||
m_consoleStore.deleteLastLineIfEmpty();
|
||||
m_tableView.reloadData();
|
||||
m_selectableTableView.reloadData();
|
||||
m_editCell.setEditing(true);
|
||||
}
|
||||
|
||||
@@ -83,8 +84,8 @@ void ConsoleController::removeExtensionIfAny(char * name) {
|
||||
|
||||
void ConsoleController::viewWillAppear() {
|
||||
assert(pythonEnvironmentIsLoaded());
|
||||
m_tableView.reloadData();
|
||||
m_tableView.scrollToCell(0, m_consoleStore.numberOfLines());
|
||||
m_selectableTableView.reloadData();
|
||||
m_selectableTableView.selectCellAtLocation(0, m_consoleStore.numberOfLines());
|
||||
m_editCell.setEditing(true);
|
||||
}
|
||||
|
||||
@@ -92,6 +93,34 @@ void ConsoleController::didBecomeFirstResponder() {
|
||||
app()->setFirstResponder(&m_editCell);
|
||||
}
|
||||
|
||||
bool ConsoleController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::Up) {
|
||||
if (m_consoleStore.numberOfLines() > 0 && m_selectableTableView.selectedRow() > 0) {
|
||||
m_editCell.setEditing(false);
|
||||
m_editCell.setText("");
|
||||
m_selectableTableView.selectCellAtLocation(0, m_consoleStore.numberOfLines()-1);
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
return true;
|
||||
}
|
||||
} else if (event == Ion::Events::OK || event == Ion::Events::EXE) {
|
||||
if (m_consoleStore.numberOfLines() > 0) {
|
||||
const char * text = m_consoleStore.lineAtIndex(m_selectableTableView.selectedRow()).text();
|
||||
m_editCell.setEditing(true);
|
||||
m_selectableTableView.selectCellAtLocation(0, m_consoleStore.numberOfLines());
|
||||
app()->setFirstResponder(&m_editCell);
|
||||
m_editCell.setText(text);
|
||||
return true;
|
||||
}
|
||||
} else if (event == Ion::Events::Copy) {
|
||||
int row = m_selectableTableView.selectedRow();
|
||||
if (row < m_consoleStore.numberOfLines()) {
|
||||
Clipboard::sharedClipboard()->store(m_consoleStore.lineAtIndex(row).text());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ConsoleController::numberOfRows() {
|
||||
return m_consoleStore.numberOfLines()+1;
|
||||
}
|
||||
@@ -146,6 +175,13 @@ void ConsoleController::willDisplayCellAtLocation(HighlightCell * cell, int i, i
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
|
||||
if (t->selectedRow() == m_consoleStore.numberOfLines()) {
|
||||
m_editCell.setEditing(true);
|
||||
app()->setFirstResponder(&m_editCell);
|
||||
}
|
||||
}
|
||||
|
||||
bool ConsoleController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) {
|
||||
return event == Ion::Events::OK || event == Ion::Events::EXE;
|
||||
}
|
||||
@@ -157,7 +193,7 @@ bool ConsoleController::textFieldDidReceiveEvent(TextField * textField, Ion::Eve
|
||||
bool ConsoleController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
|
||||
runAndPrintForCommand(text);
|
||||
textField->setText("");
|
||||
m_tableView.scrollToCell(0, m_consoleStore.numberOfLines());
|
||||
m_selectableTableView.selectCellAtLocation(0, m_consoleStore.numberOfLines());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Code {
|
||||
|
||||
class ConsoleController : public ViewController, public ListViewDataSource, public ScrollViewDataSource, public TextFieldDelegate, public MicroPython::ExecutionEnvironment {
|
||||
class ConsoleController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource, public SelectableTableViewDelegate, public TextFieldDelegate, public MicroPython::ExecutionEnvironment {
|
||||
public:
|
||||
static constexpr KDText::FontSize k_fontSize = KDText::FontSize::Large;
|
||||
|
||||
@@ -31,9 +31,10 @@ public:
|
||||
void removeExtensionIfAny(char * name);
|
||||
|
||||
// ViewController
|
||||
View * view() override { return &m_tableView; }
|
||||
View * view() override { return &m_selectableTableView; }
|
||||
void viewWillAppear() override;
|
||||
void didBecomeFirstResponder() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
|
||||
// ListViewDataSource
|
||||
int numberOfRows() override;
|
||||
@@ -45,6 +46,9 @@ public:
|
||||
int typeAtLocation(int i, int j) override;
|
||||
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override;
|
||||
|
||||
// SelectableTableViewDelegate
|
||||
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
|
||||
|
||||
// TextFieldDelegate
|
||||
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
|
||||
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
@@ -68,7 +72,7 @@ private:
|
||||
int firstNewLineCharIndex(const char * text, size_t length);
|
||||
int m_rowHeight;
|
||||
ConsoleStore m_consoleStore;
|
||||
TableView m_tableView;
|
||||
SelectableTableView m_selectableTableView;
|
||||
ConsoleLineCell m_cells[k_numberOfLineCells];
|
||||
ConsoleEditCell m_editCell;
|
||||
char * m_pythonHeap;
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace Code {
|
||||
ConsoleEditCell::ConsoleEditCell(Responder * parentResponder, TextFieldDelegate * delegate) :
|
||||
HighlightCell(),
|
||||
Responder(parentResponder),
|
||||
m_textBuffer{0},
|
||||
m_draftTextBuffer{0},
|
||||
m_promptView(ConsoleController::k_fontSize, I18n::Message::ConsolePrompt, 0, 0.5),
|
||||
m_textField(this, m_textBuffer, m_draftTextBuffer, TextField::maxBufferSize(), delegate, true, ConsoleController::k_fontSize)
|
||||
{
|
||||
@@ -41,4 +43,8 @@ void ConsoleEditCell::setEditing(bool isEditing) {
|
||||
m_textField.setEditing(isEditing);
|
||||
}
|
||||
|
||||
void ConsoleEditCell::setText(const char * text) {
|
||||
m_textField.setText(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
|
||||
// Edit cell
|
||||
void setEditing(bool isEditing);
|
||||
void setText(const char * text);
|
||||
|
||||
private:
|
||||
char m_textBuffer[TextField::maxBufferSize()];
|
||||
|
||||
@@ -13,13 +13,14 @@ ConsoleLineCell::ConsoleLineCell() :
|
||||
}
|
||||
|
||||
void ConsoleLineCell::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
KDColor textBackgroundColor = isHighlighted() ? Palette::Select : KDColorWhite;
|
||||
ctx->fillRect(bounds(), KDColorWhite);
|
||||
if (m_line.type() == ConsoleLine::Type::Command) {
|
||||
ctx->drawString(I18n::translate(I18n::Message::ConsolePrompt), KDPointZero, ConsoleController::k_fontSize);
|
||||
KDCoordinate chevronsWidth = KDText::stringSize(I18n::translate(I18n::Message::ConsolePrompt), ConsoleController::k_fontSize).width();
|
||||
ctx->drawString(m_line.text(), KDPoint(chevronsWidth, KDCoordinate(0)), ConsoleController::k_fontSize);
|
||||
ctx->drawString(m_line.text(), KDPoint(chevronsWidth, KDCoordinate(0)), ConsoleController::k_fontSize, KDColorBlack, textBackgroundColor);
|
||||
} else {
|
||||
ctx->drawString(m_line.text(), KDPointZero, ConsoleController::k_fontSize);
|
||||
ctx->drawString(m_line.text(), KDPointZero, ConsoleController::k_fontSize, KDColorBlack, textBackgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ bool ScriptParameterController::handleEvent(Ion::Events::Event event) {
|
||||
m_autoImport = !m_autoImport;
|
||||
m_selectableTableView.reloadData();
|
||||
m_menuController->reloadConsole();
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
return true;
|
||||
case 3:
|
||||
dismissScriptParameterController();
|
||||
|
||||
Reference in New Issue
Block a user