mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
Merge branch 'master' into f7
This commit is contained in:
@@ -361,9 +361,10 @@ bool PythonToolbox::selectLeaf(int selectedRow) {
|
||||
m_selectableTableView.deselectTable();
|
||||
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->children(selectedRow);
|
||||
const char * editedText = I18n::translate(node->insertedText());
|
||||
// strippedEditedText array needs to be in the same scope as editedText
|
||||
char strippedEditedText[k_maxMessageSize];
|
||||
if (node->stripInsertedText()) {
|
||||
int strippedEditedTextMaxLength = strlen(editedText)+1;
|
||||
char strippedEditedText[k_maxMessageSize];
|
||||
assert(strippedEditedTextMaxLength <= k_maxMessageSize);
|
||||
Shared::ToolboxHelpers::TextToInsertForCommandMessage(node->insertedText(), strippedEditedText, strippedEditedTextMaxLength, true);
|
||||
editedText = strippedEditedText;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "graph_controller.h"
|
||||
#include "../shared/poincare_helpers.h"
|
||||
#include "../shared/text_helpers.h"
|
||||
#include "../apps_container.h"
|
||||
#include <cmath>
|
||||
|
||||
@@ -110,16 +111,15 @@ void GraphController::reloadBannerView() {
|
||||
numberOfChar += strlcpy(buffer, legend, bufferSize);
|
||||
if (*m_selectedDotIndex == m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) {
|
||||
legend = I18n::translate(I18n::Message::MeanDot);
|
||||
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize - numberOfChar);
|
||||
numberOfChar += strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
|
||||
} else if (*m_selectedDotIndex < 0) {
|
||||
legend = I18n::translate(I18n::Message::Reg);
|
||||
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize - numberOfChar);
|
||||
numberOfChar += strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
|
||||
} else {
|
||||
numberOfChar += PrintFloat::convertFloatToText<float>(std::round((float)*m_selectedDotIndex+1.0f), buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits), Constant::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||
numberOfChar += PrintFloat::convertFloatToText<float>(std::round((float)*m_selectedDotIndex+1.0f), buffer + numberOfChar, bufferSize - numberOfChar, Constant::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||
}
|
||||
legend = ") ";
|
||||
strlcpy(buffer+numberOfChar, legend, bufferSize - numberOfChar);
|
||||
buffer[k_maxLegendLength] = 0;
|
||||
strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
|
||||
m_bannerView.dotNameView()->setText(buffer);
|
||||
|
||||
// Set "x=..." or "xmean=..."
|
||||
@@ -133,12 +133,9 @@ void GraphController::reloadBannerView() {
|
||||
}
|
||||
m_bannerView.abscissaSymbol()->setText(legend);
|
||||
|
||||
numberOfChar = PoincareHelpers::ConvertFloatToText<double>(x, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits);
|
||||
assert(UTF8Decoder::CharSizeOfCodePoint(' ') == 1);
|
||||
for (int i = numberOfChar; i < k_maxLegendLength; i++) {
|
||||
buffer[numberOfChar++] = ' ';
|
||||
}
|
||||
buffer[k_maxLegendLength] = 0;
|
||||
numberOfChar = PoincareHelpers::ConvertFloatToText<double>(x, buffer, bufferSize, Constant::MediumNumberOfSignificantDigits);
|
||||
// Padding
|
||||
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
|
||||
m_bannerView.abscissaValue()->setText(buffer);
|
||||
|
||||
// Set "y=..." or "ymean=..."
|
||||
@@ -151,11 +148,9 @@ void GraphController::reloadBannerView() {
|
||||
y = m_store->meanOfColumn(*m_selectedSeriesIndex, 1);
|
||||
}
|
||||
numberOfChar += strlcpy(buffer, legend, bufferSize);
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(y, buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits);
|
||||
for (int i = numberOfChar; i < k_maxLegendLength; i++) {
|
||||
buffer[numberOfChar++] = ' ';
|
||||
}
|
||||
buffer[k_maxLegendLength] = 0;
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(y, buffer + numberOfChar, bufferSize - numberOfChar, Constant::MediumNumberOfSignificantDigits);
|
||||
// Padding
|
||||
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
|
||||
m_bannerView.ordinateView()->setText(buffer);
|
||||
|
||||
// Set formula
|
||||
@@ -176,10 +171,8 @@ void GraphController::reloadBannerView() {
|
||||
// Force the "Data not suitable" message to be on the next line
|
||||
int numberOfCharToCompleteLine = maxInt(Ion::Display::Width / BannerView::Font()->glyphSize().width() - strlen(I18n::translate(formula)), 0);
|
||||
numberOfChar = 0;
|
||||
for (int i = 0; i < numberOfCharToCompleteLine-1; i++) {
|
||||
buffer[numberOfChar++] = ' ';
|
||||
}
|
||||
buffer[numberOfChar] = 0;
|
||||
// Padding
|
||||
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, numberOfCharToCompleteLine - 1);
|
||||
m_bannerView.subTextAtIndex(0)->setText(buffer);
|
||||
|
||||
const char * dataNotSuitableMessage = I18n::translate(I18n::Message::DataNotSuitableForRegression);
|
||||
@@ -195,8 +188,7 @@ void GraphController::reloadBannerView() {
|
||||
char leg[] = {' ', coefficientName, '=', 0};
|
||||
legend = leg;
|
||||
numberOfChar += strlcpy(buffer, legend, bufferSize);
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(coefficients[i], buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
buffer[k_maxLegendLength] = 0;
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(coefficients[i], buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
|
||||
m_bannerView.subTextAtIndex(i)->setText(buffer);
|
||||
coefficientName++;
|
||||
}
|
||||
@@ -207,8 +199,7 @@ void GraphController::reloadBannerView() {
|
||||
legend = " r=";
|
||||
double r = m_store->correlationCoefficient(*m_selectedSeriesIndex);
|
||||
numberOfChar += strlcpy(buffer, legend, bufferSize);
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r, buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
buffer[k_maxLegendLength+10] = 0;
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r, buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
|
||||
m_bannerView.subTextAtIndex(2)->setText(buffer);
|
||||
|
||||
// Set "r2=..."
|
||||
@@ -216,8 +207,7 @@ void GraphController::reloadBannerView() {
|
||||
legend = " r2=";
|
||||
double r2 = m_store->squaredCorrelationCoefficient(*m_selectedSeriesIndex);
|
||||
numberOfChar += strlcpy(buffer, legend, bufferSize);
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r2, buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
buffer[k_maxLegendLength] = 0;
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r2, buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
|
||||
m_bannerView.subTextAtIndex(3)->setText(buffer);
|
||||
|
||||
// Clean the last subview
|
||||
|
||||
@@ -65,6 +65,7 @@ app_src += $(addprefix apps/shared/,\
|
||||
text_field_delegate.cpp \
|
||||
text_field_delegate_app.cpp \
|
||||
text_field_with_extension.cpp \
|
||||
text_helpers.cpp \
|
||||
toolbox_helpers.cpp \
|
||||
values_controller.cpp \
|
||||
values_function_parameter_controller.cpp \
|
||||
|
||||
25
apps/shared/text_helpers.cpp
Normal file
25
apps/shared/text_helpers.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "text_helpers.h"
|
||||
#include <ion/unicode/utf8_decoder.h>
|
||||
#include <ion/unicode/utf8_helper.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Shared {
|
||||
namespace TextHelpers {
|
||||
|
||||
void PadWithSpaces(char * buffer, int bufferSize, int * currentNumberOfChar, int maxGlyphLengthWithPadding) {
|
||||
assert(*currentNumberOfChar <= bufferSize);
|
||||
size_t currentGlyphLength = UTF8Helper::StringGlyphLength(buffer, *currentNumberOfChar);
|
||||
bool addedPadding = false;
|
||||
assert(UTF8Decoder::CharSizeOfCodePoint(' ') == 1);
|
||||
while (currentGlyphLength < maxGlyphLengthWithPadding && *currentNumberOfChar < bufferSize) {
|
||||
*currentNumberOfChar = *currentNumberOfChar + UTF8Decoder::CodePointToChars(' ', buffer + *currentNumberOfChar, bufferSize - *currentNumberOfChar);
|
||||
addedPadding = true;
|
||||
currentGlyphLength++;
|
||||
}
|
||||
if (addedPadding) {
|
||||
buffer[*currentNumberOfChar-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
12
apps/shared/text_helpers.h
Normal file
12
apps/shared/text_helpers.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef SHARED_TEXT_HELPERS_H
|
||||
#define SHARED_TEXT_HELPERS_H
|
||||
|
||||
namespace Shared {
|
||||
namespace TextHelpers {
|
||||
|
||||
void PadWithSpaces(char * buffer, int bufferSize, int * currentNumberOfChar, int maxGlyphLengthWithPadding);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "histogram_controller.h"
|
||||
#include "../apps_container.h"
|
||||
#include "../shared/poincare_helpers.h"
|
||||
#include "../shared/text_helpers.h"
|
||||
#include "app.h"
|
||||
#include <cmath>
|
||||
#include <assert.h>
|
||||
@@ -90,20 +91,6 @@ Responder * HistogramController::tabController() const {
|
||||
return (parentResponder()->parentResponder()->parentResponder()->parentResponder());
|
||||
}
|
||||
|
||||
void pad(char * buffer, int bufferSize, int * currentNumberOfChar, int maxGlyphLengthWithPadding) {
|
||||
assert(*currentNumberOfChar <= bufferSize);
|
||||
size_t currentGlyphLength = UTF8Helper::StringGlyphLength(buffer, *currentNumberOfChar);
|
||||
bool addedPadding = false;
|
||||
while (currentGlyphLength < maxGlyphLengthWithPadding && *currentNumberOfChar < bufferSize) {
|
||||
*currentNumberOfChar = *currentNumberOfChar + UTF8Decoder::CodePointToChars(' ', buffer + *currentNumberOfChar, bufferSize - *currentNumberOfChar);
|
||||
addedPadding = true;
|
||||
currentGlyphLength++;
|
||||
}
|
||||
if (addedPadding) {
|
||||
buffer[*currentNumberOfChar-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramController::reloadBannerView() {
|
||||
if (selectedSeriesIndex() < 0) {
|
||||
return;
|
||||
@@ -134,7 +121,7 @@ void HistogramController::reloadBannerView() {
|
||||
numberOfChar+= UTF8Decoder::CodePointToChars('[', buffer + numberOfChar, bufferSize - numberOfChar);
|
||||
|
||||
// Padding
|
||||
pad(buffer, bufferSize, &numberOfChar, k_maxIntervalLegendLength);
|
||||
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxIntervalLegendLength);
|
||||
m_view.bannerView()->intervalView()->setText(buffer);
|
||||
|
||||
// Add Size Data
|
||||
@@ -149,7 +136,7 @@ void HistogramController::reloadBannerView() {
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(size, buffer+numberOfChar, bufferSize-numberOfChar, Constant::LargeNumberOfSignificantDigits);
|
||||
}
|
||||
// Padding
|
||||
pad(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
|
||||
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
|
||||
m_view.bannerView()->sizeView()->setText(buffer);
|
||||
|
||||
// Add Frequency Data
|
||||
@@ -163,7 +150,7 @@ void HistogramController::reloadBannerView() {
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(frequency, buffer+numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
|
||||
}
|
||||
// Padding
|
||||
pad(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
|
||||
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
|
||||
m_view.bannerView()->frequencyView()->setText(buffer);
|
||||
|
||||
m_view.bannerView()->reload();
|
||||
|
||||
@@ -287,25 +287,37 @@ void LayoutField::insertLayoutAtCursor(Layout layoutR, Poincare::Expression corr
|
||||
cursor->showEmptyLayoutIfNeeded();
|
||||
|
||||
bool layoutWillBeMerged = layoutR.type() == LayoutNode::Type::HorizontalLayout;
|
||||
Layout lastMergedLayoutChild = layoutWillBeMerged ? layoutR.childAtIndex(layoutR.numberOfChildren()-1) : Layout();
|
||||
|
||||
// Find the layout where the cursor will point
|
||||
assert(!correspondingExpression.isUninitialized());
|
||||
Layout cursorLayout = forceCursorRightOfLayout ? layoutR : layoutR.layoutToPointWhenInserting(&correspondingExpression);
|
||||
assert(!cursorLayout.isUninitialized());
|
||||
Layout lastMergedLayoutChild = (layoutWillBeMerged && layoutR.numberOfChildren() > 0) ? layoutR.childAtIndex(layoutR.numberOfChildren()-1) : Layout();
|
||||
|
||||
// Add the layout. This puts the cursor at the right of the added layout
|
||||
cursor->addLayoutAndMoveCursor(layoutR);
|
||||
|
||||
/* Move the cursor if needed.
|
||||
* If the layout to point to has been merged, it means that only its children
|
||||
* have been inserted in the layout, so we must not move the cursor to the
|
||||
* parent. In this case, addLayoutAndMoveCursor made the cursor point to the
|
||||
* last merged child, which is what is wanted.
|
||||
* For other cases, move the cursor to the computed layout. */
|
||||
if (!(layoutWillBeMerged && cursorLayout == layoutR)) {
|
||||
cursor->setLayout(cursorLayout);
|
||||
cursor->setPosition(LayoutCursor::Position::Right);
|
||||
*
|
||||
* If forceCursorRightOfLayout is true, there is no need to move the cursor
|
||||
* because it already points to the right of the added layout.
|
||||
*
|
||||
* If the layout to point to has been merged, only its children have been
|
||||
* inserted in the layout, so we must not move the cursor to the parent.
|
||||
* addLayoutAndMoveCursor made the cursor point to the last merged child,
|
||||
* which is what is wanted.
|
||||
*
|
||||
* For other cases, move the cursor to the layout indicated by
|
||||
* layoutToPointWhenInserting. This pointed layout cannot be computed before
|
||||
* adding layoutR, because addLayoutAndMoveCursor might have changed layoutR's
|
||||
* children.
|
||||
* For instance, if we add an absolute value with an empty child left of a 0,
|
||||
* the empty child is deleted and the 0 is collapsed into the absolute value.
|
||||
* Sketch of the situation, ' being the cursor:
|
||||
* Initial layout: '0
|
||||
* "abs(x)" pressed in the toolbox => |•| is added, • being an empty layout
|
||||
* Final layout: |0'|
|
||||
* */
|
||||
|
||||
if (!forceCursorRightOfLayout && !layoutWillBeMerged) {
|
||||
assert(!correspondingExpression.isUninitialized());
|
||||
m_contentView.cursor()->setLayout(layoutR.layoutToPointWhenInserting(&correspondingExpression));
|
||||
m_contentView.cursor()->setPosition(LayoutCursor::Position::Right);
|
||||
}
|
||||
|
||||
// Handle matrices
|
||||
|
||||
@@ -340,13 +340,16 @@ size_t StringGlyphLength(const char * s, int maxSize) {
|
||||
return 0;
|
||||
}
|
||||
UTF8Decoder decoder(s);
|
||||
CodePoint codePoint = decoder.nextCodePoint();
|
||||
CodePoint codePoint = 0;
|
||||
size_t glyphIndex = 0;
|
||||
while (codePoint != UCodePointNull && (maxSize < 0 || ((decoder.stringPosition() - s) <= maxSize))) {
|
||||
while (maxSize < 0 || ((decoder.stringPosition() - s) < maxSize)) {
|
||||
codePoint = decoder.nextCodePoint();
|
||||
if (codePoint == UCodePointNull) {
|
||||
break;
|
||||
}
|
||||
if (!codePoint.isCombining()) {
|
||||
glyphIndex++;
|
||||
}
|
||||
codePoint = decoder.nextCodePoint();
|
||||
}
|
||||
return glyphIndex;
|
||||
}
|
||||
|
||||
@@ -10,5 +10,6 @@ QUIZ_CASE(ion_utf8_helper_glyph_length) {
|
||||
assert_string_glyph_length_is("1ᴇ3", -1, 3);
|
||||
assert_string_glyph_length_is("∑∫𝐢", -1, 3);
|
||||
assert_string_glyph_length_is("123", 2, 2);
|
||||
assert_string_glyph_length_is("1ᴇ3", 2, 1);
|
||||
uint8_t testString[] = {'a', 'b', 'c', 0b11111111, 0b11111111, 0}; // Malformed utf-8 string
|
||||
assert_string_glyph_length_is((const char *)testString, 3, 3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user