mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps/code] Display source and description in var box
This commit is contained in:
@@ -8,25 +8,27 @@ namespace Code {
|
||||
|
||||
class ScriptNode {
|
||||
public:
|
||||
constexpr static uint16_t CurrentScriptIndex = -1;
|
||||
enum class Type : bool {
|
||||
Function,
|
||||
Variable
|
||||
};
|
||||
ScriptNode(Type type = Type::Variable, const char * name = nullptr, int nameLength = 0, uint16_t scriptIndex = 0) :
|
||||
ScriptNode(Type type = Type::Variable, const char * name = nullptr, int nameLength = -1, const char * nodeSourceName = nullptr, const char * description = nullptr) :
|
||||
m_type(type),
|
||||
m_name(name),
|
||||
m_scriptIndex(-1),
|
||||
m_nodeSourceName(nodeSourceName),
|
||||
m_description(description),
|
||||
m_nameLength(nameLength)
|
||||
{}
|
||||
Type type() const { return m_type; }
|
||||
const char * name() const { return m_name; }
|
||||
int nameLength() const { return m_nameLength; }
|
||||
uint16_t scriptIndex() const { return m_scriptIndex; }
|
||||
const char * nodeSourceName() const { return m_nodeSourceName; }
|
||||
const char * description() const { return m_description; }
|
||||
private:
|
||||
Type m_type;
|
||||
const char * m_name;
|
||||
uint16_t m_scriptIndex; // TODO LEA smaller type ?
|
||||
const char * m_nodeSourceName;
|
||||
const char * m_description;
|
||||
int m_nameLength; // TODO LEA smaller type ?
|
||||
};
|
||||
|
||||
|
||||
@@ -7,22 +7,38 @@ namespace Code {
|
||||
constexpr char ScriptNodeCell::k_parentheses[];
|
||||
constexpr char ScriptNodeCell::k_parenthesesWithEmpty[];
|
||||
|
||||
// TODO LEA remove static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; }
|
||||
|
||||
void ScriptNodeCell::ScriptNodeView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
const KDColor backgroundColor = isHighlighted()? Palette::Select : KDColorWhite;
|
||||
|
||||
/* If it exists, draw the description name. If it did not fit, we would have
|
||||
* put nullptr at the node creation. */
|
||||
const char * descriptionName = m_scriptNode->description();
|
||||
bool drawDescription = descriptionName != nullptr;
|
||||
KDCoordinate rectHeightPerLine = rect.height();
|
||||
if (drawDescription) {
|
||||
rectHeightPerLine = rect.height() / 2;
|
||||
ctx->drawString(descriptionName, KDPoint(0, rectHeightPerLine + k_verticalMargin / 2), k_font, Palette::GreyDark, backgroundColor);
|
||||
}
|
||||
|
||||
// Draw the node name
|
||||
const char * nodeName = m_scriptNode->name();
|
||||
const int nodeNameLength = m_scriptNode->nameLength();
|
||||
const KDSize nameSize = k_font->stringSize(nodeName, nodeNameLength);
|
||||
const KDCoordinate nodeNameY = (rect.height() - nameSize.height()) / 2;
|
||||
KDSize nameSize = k_font->stringSize(nodeName, nodeNameLength);
|
||||
const KDCoordinate nodeNameY = rectHeightPerLine - k_verticalMargin / 2 - nameSize.height() ;
|
||||
ctx->drawString(nodeName, KDPoint(0, nodeNameY), k_font, KDColorBlack, backgroundColor, nodeNameLength);
|
||||
|
||||
// If it is a function, draw the parentheses
|
||||
if (m_scriptNode->type() == ScriptNode::Type::Function) {
|
||||
ctx->drawString(ScriptNodeCell::k_parentheses, KDPoint(nameSize.width(), nodeNameY), k_font, KDColorBlack, backgroundColor);
|
||||
}
|
||||
if (m_scriptNode->scriptIndex() != ScriptNode::CurrentScriptIndex) {
|
||||
ctx->drawString(m_scriptStore->scriptAtIndex(m_scriptNode->scriptIndex()).fullName(), KDPoint(0, Metric::TableCellVerticalMargin + nameSize.height() + k_verticalMargin), k_font, Palette::GreyDark, backgroundColor);
|
||||
|
||||
/* If it exists, draw the source name. If it did not fit, we would have put
|
||||
* nullptr at the node creation. */
|
||||
const char * sourceName = m_scriptNode->nodeSourceName();
|
||||
if (sourceName != nullptr) {
|
||||
KDSize sourceNameSize = k_font->stringSize(sourceName);
|
||||
ctx->drawString(sourceName, KDPoint(rect.width() - sourceNameSize.width(), nodeNameY), k_font, Palette::GreyDark, backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +46,25 @@ KDSize ScriptNodeCell::ScriptNodeView::minimalSizeForOptimalDisplay() const {
|
||||
if (m_scriptNode->name() == nullptr) {
|
||||
return KDSizeZero;
|
||||
}
|
||||
KDSize size1 = k_font->stringSize(m_scriptNode->name(), m_scriptNode->nameLength());
|
||||
KDSize size2 = m_scriptNode->scriptIndex() == ScriptNode::CurrentScriptIndex ? KDSizeZero : k_font->stringSize(m_scriptStore->scriptAtIndex(m_scriptNode->scriptIndex()).fullName());
|
||||
KDSize size3 = KDSizeZero;
|
||||
return KDSize(300 /*TODO LEA*/, 2*k_topBottomMargin + m_scriptNode->description() == nullptr ? k_font->glyphSize().height() : k_font->glyphSize().height() * 2 + k_verticalMargin);
|
||||
#if 0
|
||||
KDSize nameLineSize = k_font->stringSize(m_scriptNode->name(), m_scriptNode->nameLength());
|
||||
if (m_scriptNode->type() == ScriptNode::Type::Function) {
|
||||
size3 = k_font->stringSize(ScriptNodeCell::k_parentheses);
|
||||
nameLineSize = KDSize(nameLineSize.width() + k_font->stringSize(k_parentheses).width(), nameLineSize.height());
|
||||
}
|
||||
return KDSize(size1.width() + size3.width() > size2.width() ? size1.width() + size3.width() : size2.width(), Metric::TableCellVerticalMargin + size1.width() + k_verticalMargin + size2.width());
|
||||
const char * sourceName = m_scriptNode->nodeSourceName();
|
||||
if (sourceName != nullptr) {
|
||||
KDSize sourceNameSize = k_font->stringSize(sourceName, nodeNameLength);
|
||||
nameLineSize = KDSize(nameLineSize.width() + sourceNameSize.width() + k_font->glyphSize().width(), nameLineSize.height());
|
||||
}
|
||||
|
||||
const char * descriptionName = m_scriptNode->description();
|
||||
if (descriptionName == nullptr) {
|
||||
return nameLineSize;
|
||||
}
|
||||
const KDSize descriptionNameSize = k_font->stringSize(descriptionName);
|
||||
return KDSize(maxCoordinate(nameLineSize.width(), descriptionNameSize.width()),2*Metric::TableCellVerticalMargin + nameLineSize.width() + k_verticalMargin + descriptionNameSize.height());
|
||||
#endif
|
||||
}
|
||||
|
||||
void ScriptNodeCell::setScriptNode(ScriptNode * scriptNode) {
|
||||
|
||||
@@ -15,7 +15,6 @@ public:
|
||||
m_scriptNodeView()
|
||||
{}
|
||||
void setScriptNode(ScriptNode * node);
|
||||
void setScriptStore(ScriptStore * scriptStore) { m_scriptNodeView.setScriptStore(scriptStore); }
|
||||
|
||||
/* TableCell */
|
||||
View * labelView() const override { return const_cast<View *>(static_cast<const View *>(&m_scriptNodeView)); }
|
||||
@@ -34,21 +33,19 @@ protected:
|
||||
public:
|
||||
ScriptNodeView() :
|
||||
HighlightCell(),
|
||||
m_scriptNode(nullptr),
|
||||
m_scriptStore(nullptr)
|
||||
m_scriptNode(nullptr)
|
||||
{}
|
||||
void setScriptNode(ScriptNode * node) { m_scriptNode = node; }
|
||||
void setScriptStore(ScriptStore * scriptStore) { m_scriptStore = scriptStore; }
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
virtual KDSize minimalSizeForOptimalDisplay() const override;
|
||||
const char * text() const override {
|
||||
return m_scriptStore->scriptAtIndex(m_scriptNode->scriptIndex()).fullName();
|
||||
return m_scriptNode->description();
|
||||
}
|
||||
private:
|
||||
constexpr static const KDFont * k_font = KDFont::SmallFont;
|
||||
constexpr static KDCoordinate k_topBottomMargin = Metric::TableCellVerticalMargin;
|
||||
constexpr static KDCoordinate k_verticalMargin = 7;
|
||||
ScriptNode * m_scriptNode;
|
||||
ScriptStore * m_scriptStore;
|
||||
};
|
||||
ScriptNodeView m_scriptNodeView;
|
||||
};
|
||||
|
||||
@@ -53,9 +53,6 @@ VariableBoxController::VariableBoxController(ScriptStore * scriptStore) :
|
||||
m_builtinNodesCount(0),
|
||||
m_importedNodesCount(0)
|
||||
{
|
||||
for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) {
|
||||
m_itemCells[i].setScriptStore(scriptStore);
|
||||
}
|
||||
for (int i = 0; i < k_scriptOriginsCount; i++) {
|
||||
m_subtitleCells[i].setBackgroundColor(Palette::WallScreen);
|
||||
m_subtitleCells[i].setTextColor(Palette::BlueishGrey);
|
||||
@@ -447,7 +444,7 @@ void VariableBoxController::loadBuiltinNodes(const char * textToAutocomplete, in
|
||||
};
|
||||
assert(sizeof(builtinNames) / sizeof(builtinNames[0]) == k_totalBuiltinNodesCount);
|
||||
for (int i = 0; i < k_totalBuiltinNodesCount; i++) {
|
||||
ScriptNode node = ScriptNode(builtinNames[i].type, builtinNames[i].name, -1, 0);
|
||||
ScriptNode node = ScriptNode(builtinNames[i].type, builtinNames[i].name);
|
||||
int startsWith = textToAutocomplete == nullptr ? 0 : NodeNameStartsWith(&node, textToAutocomplete, textToAutocompleteLength);
|
||||
if (startsWith == 0) {
|
||||
m_builtinNodes[m_builtinNodesCount++] = node;
|
||||
@@ -548,7 +545,7 @@ void VariableBoxController::loadCurrentVariablesInScript(const char * scriptCont
|
||||
}
|
||||
}
|
||||
assert(strncmp(tokenInText, name, nameLength) == 0);
|
||||
addNode(defToken ? ScriptNode::Type::Function : ScriptNode::Type::Variable, NodeOrigin::CurrentScript, tokenInText, nameLength, ScriptNode::CurrentScriptIndex);
|
||||
addNode(defToken ? ScriptNode::Type::Function : ScriptNode::Type::Variable, NodeOrigin::CurrentScript, tokenInText, nameLength);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,7 +566,7 @@ void VariableBoxController::loadCurrentVariablesInScript(const char * scriptCont
|
||||
}
|
||||
}
|
||||
|
||||
void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength) {
|
||||
void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(const char * scriptName, const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
|
||||
@@ -582,7 +579,7 @@ void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(con
|
||||
uint structKind = (uint)MP_PARSE_NODE_STRUCT_KIND(pns);
|
||||
if (structKind == PN_funcdef || structKind == PN_expr_stmt) {
|
||||
// The script is only a single function or variable definition
|
||||
addImportStruct(pns, structKind, textToAutocomplete, textToAutocompleteLength);
|
||||
addImportStruct(pns, structKind, scriptName, textToAutocomplete, textToAutocompleteLength);
|
||||
} else if (addNodesFromImportMaybe(pns, textToAutocomplete, textToAutocompleteLength)) {
|
||||
// The script is is only an import, handled in addNodesFromImportMaybe
|
||||
} else if (structKind == PN_file_input_2) {
|
||||
@@ -597,7 +594,7 @@ void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(con
|
||||
mp_parse_node_struct_t *child_pns = (mp_parse_node_struct_t*)(child);
|
||||
structKind = (uint)MP_PARSE_NODE_STRUCT_KIND(child_pns);
|
||||
if (structKind == PN_funcdef || structKind == PN_expr_stmt) {
|
||||
addImportStruct(child_pns, structKind, textToAutocomplete, textToAutocompleteLength);
|
||||
addImportStruct(child_pns, structKind, scriptName, textToAutocomplete, textToAutocompleteLength);
|
||||
} else {
|
||||
addNodesFromImportMaybe(child_pns, textToAutocomplete, textToAutocompleteLength);
|
||||
}
|
||||
@@ -634,7 +631,7 @@ bool VariableBoxController::addNodesFromImportMaybe(mp_parse_node_struct_t * par
|
||||
if (MP_PARSE_NODE_IS_LEAF(child) && MP_PARSE_NODE_LEAF_KIND(child) == MP_PARSE_NODE_ID) {
|
||||
// Parsing something like "import math"
|
||||
const char * id = qstr_str(MP_PARSE_NODE_LEAF_ARG(child));
|
||||
checkAndAddNode(textToAutocomplete, textToAutocompleteLength, ScriptNode::Type::Variable, NodeOrigin::Importation, id, -1, 1/*TODO LEA*/);
|
||||
checkAndAddNode(textToAutocomplete, textToAutocompleteLength, ScriptNode::Type::Variable, NodeOrigin::Importation, id, -1, "math", "desc" /*TODO LEA*/);
|
||||
} else if (MP_PARSE_NODE_IS_STRUCT(child)) {
|
||||
// Parsing something like "from math import sin"
|
||||
addNodesFromImportMaybe((mp_parse_node_struct_t *)child, textToAutocomplete, textToAutocompleteLength);
|
||||
@@ -695,7 +692,7 @@ bool VariableBoxController::addNodesFromImportMaybe(mp_parse_node_struct_t * par
|
||||
assert(numberOfChildren > numberOfNodesToSkip);
|
||||
for (int i = 3; i < numberOfChildren; i++) {
|
||||
const char * name = I18n::translate((moduleChildren + i)->label());
|
||||
checkAndAddNode(textToAutocomplete, textToAutocompleteLength, ScriptNode::Type::Variable, NodeOrigin::Importation, name, -1, 1/*TODO LEA*/);
|
||||
checkAndAddNode(textToAutocomplete, textToAutocompleteLength, ScriptNode::Type::Variable, NodeOrigin::Importation, name, -1, importationSourceName, I18n::translate((moduleChildren + i)->text()) /*TODO LEA text or label?*/);
|
||||
}
|
||||
} else {
|
||||
// Try fetching the nodes from a script
|
||||
@@ -703,7 +700,7 @@ bool VariableBoxController::addNodesFromImportMaybe(mp_parse_node_struct_t * par
|
||||
if (!importedScript.isNull()) {
|
||||
const char * scriptContent = importedScript.scriptContent();
|
||||
assert(scriptContent != nullptr);
|
||||
loadGlobalAndImportedVariablesInScriptAsImported(scriptContent, textToAutocomplete, textToAutocompleteLength);
|
||||
loadGlobalAndImportedVariablesInScriptAsImported(importationSourceName, scriptContent, textToAutocomplete, textToAutocompleteLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -726,23 +723,23 @@ const char * structName(mp_parse_node_struct_t * structNode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VariableBoxController::addImportStruct(mp_parse_node_struct_t * pns, uint structKind, const char * textToAutocomplete, int textToAutocompleteLength) {
|
||||
void VariableBoxController::addImportStruct(mp_parse_node_struct_t * pns, uint structKind, const char * scriptName, const char * textToAutocomplete, int textToAutocompleteLength) {
|
||||
assert(structKind == PN_funcdef || structKind == PN_expr_stmt);
|
||||
// Find the id child node, which stores the struct's name
|
||||
const char * name = structName(pns);
|
||||
if (name == nullptr) {
|
||||
return;
|
||||
}
|
||||
checkAndAddNode(textToAutocomplete, textToAutocompleteLength, structKind == PN_funcdef ? ScriptNode::Type::Function : ScriptNode::Type::Variable, NodeOrigin::Importation, name, -1, 1/*TODO LEA*/);
|
||||
checkAndAddNode(textToAutocomplete, textToAutocompleteLength, structKind == PN_funcdef ? ScriptNode::Type::Function : ScriptNode::Type::Variable, NodeOrigin::Importation, name, -1, scriptName);
|
||||
}
|
||||
|
||||
void VariableBoxController::checkAndAddNode(const char * textToAutocomplete, int textToAutocompleteLength, ScriptNode::Type type, NodeOrigin origin, const char * nodeName, int nodeNameLength, int scriptIndex) {
|
||||
void VariableBoxController::checkAndAddNode(const char * textToAutocomplete, int textToAutocompleteLength, ScriptNode::Type type, NodeOrigin origin, const char * nodeName, int nodeNameLength, const char * nodeSourceName, const char * description) {
|
||||
if (nodeNameLength < 0) {
|
||||
nodeNameLength = strlen(nodeName);
|
||||
}
|
||||
if (shouldAddNode(textToAutocomplete, textToAutocompleteLength, nodeName, nodeNameLength)) {
|
||||
// Add the node in alphabetical order
|
||||
addNode(type, origin, nodeName, nodeNameLength, scriptIndex);
|
||||
addNode(type, origin, nodeName, nodeNameLength, nodeSourceName, description);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,7 +793,7 @@ bool VariableBoxController::contains(const char * name, int nameLength) {
|
||||
return alreadyInVarBox;
|
||||
}
|
||||
|
||||
void VariableBoxController::addNode(ScriptNode::Type type, NodeOrigin origin, const char * name, int nameLength, int scriptIndex) {
|
||||
void VariableBoxController::addNode(ScriptNode::Type type, NodeOrigin origin, const char * name, int nameLength, const char * nodeSourceName, const char * description) {
|
||||
assert(origin == NodeOrigin::CurrentScript || origin == NodeOrigin::Importation);
|
||||
int * currentNodeCount = nodesCountPointerForOrigin(origin);
|
||||
if (*currentNodeCount >= MaxNodesCountForOrigin(origin)) {
|
||||
@@ -822,7 +819,7 @@ void VariableBoxController::addNode(ScriptNode::Type type, NodeOrigin origin, co
|
||||
nodes[i+1] = nodes[i];
|
||||
}
|
||||
// Add the node
|
||||
nodes[insertionIndex] = ScriptNode(type, name, nameLength, scriptIndex);
|
||||
nodes[insertionIndex] = ScriptNode(type, name, nameLength, nodeSourceName, description);
|
||||
// Increase the node count
|
||||
*currentNodeCount = *currentNodeCount + 1;
|
||||
}
|
||||
|
||||
@@ -85,17 +85,16 @@ private:
|
||||
void loadBuiltinNodes(const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
void loadImportedVariablesInScript(const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
void loadCurrentVariablesInScript(const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
void loadGlobalAndImportedVariablesInScriptAsImported(const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
void loadGlobalAndImportedVariablesInScriptAsImported(const char * scriptName, const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
// Returns true if this was an import structure
|
||||
bool addNodesFromImportMaybe(mp_parse_node_struct_t * parseNode, const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
void addImportStruct(mp_parse_node_struct_t * pns, uint structKind, const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
void addImportStruct(mp_parse_node_struct_t * pns, uint structKind, const char * scriptName, const char * textToAutocomplete, int textToAutocompleteLength);
|
||||
/* Add a node if it completes the text to autocomplete and if it is not
|
||||
* already contained in the variable box. */
|
||||
void checkAndAddNode(const char * textToAutocomplete, int textToAutocompleteLength, ScriptNode::Type type, NodeOrigin origin, const char * name, int nameLength, int scriptIndex = 0);
|
||||
void checkAndAddNode(const char * textToAutocomplete, int textToAutocompleteLength, ScriptNode::Type type, NodeOrigin origin, const char * name, int nameLength, const char * nodeSourceName = nullptr, const char * description = nullptr);
|
||||
bool shouldAddNode(const char * textToAutocomplete, int textToAutocompleteLength, const char * name, int nameLength);
|
||||
bool contains(const char * name, int nameLength);
|
||||
void addNode(ScriptNode::Type type, NodeOrigin origin, const char * name, int nameLength, int scriptIndex = 0);
|
||||
|
||||
void addNode(ScriptNode::Type type, NodeOrigin origin, const char * name, int nameLength, const char * nodeSourceName = nullptr, const char * description = nullptr);
|
||||
ScriptNode m_currentScriptNodes[k_maxScriptNodesCount];
|
||||
ScriptNode m_builtinNodes[k_totalBuiltinNodesCount];
|
||||
ScriptNode m_importedNodes[k_maxScriptNodesCount];
|
||||
|
||||
Reference in New Issue
Block a user