mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[Update] Epsilon 14
This commit is contained in:
@@ -32,7 +32,7 @@ mp_obj_t modkandinsky_color(size_t n_args, const mp_obj_t *args) {
|
||||
assert(n_args == 3);
|
||||
color = mp_obj_new_tuple(n_args, args);
|
||||
}
|
||||
return TupleForKDColor(MicroPython::ColorParser::ParseColor(color));
|
||||
return TupleForKDColor(MicroPython::Color::Parse(color));
|
||||
}
|
||||
|
||||
/* Calling ExecutionEnvironment::displaySandbox() hides the console and switches
|
||||
@@ -49,7 +49,7 @@ mp_obj_t modkandinsky_get_pixel(mp_obj_t x, mp_obj_t y) {
|
||||
|
||||
mp_obj_t modkandinsky_set_pixel(mp_obj_t x, mp_obj_t y, mp_obj_t input) {
|
||||
KDPoint point(mp_obj_get_int(x), mp_obj_get_int(y));
|
||||
KDColor kdColor = MicroPython::ColorParser::ParseColor(input);
|
||||
KDColor kdColor = MicroPython::Color::Parse(input);
|
||||
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
|
||||
KDIonContext::sharedContext()->setPixel(point, kdColor);
|
||||
return mp_const_none;
|
||||
@@ -59,8 +59,8 @@ mp_obj_t modkandinsky_set_pixel(mp_obj_t x, mp_obj_t y, mp_obj_t input) {
|
||||
mp_obj_t modkandinsky_draw_string(size_t n_args, const mp_obj_t * args) {
|
||||
const char * text = mp_obj_str_get_str(args[0]);
|
||||
KDPoint point(mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
|
||||
KDColor textColor = (n_args >= 4) ? MicroPython::ColorParser::ParseColor(args[3]) : KDColorBlack;
|
||||
KDColor backgroundColor = (n_args >= 5) ? MicroPython::ColorParser::ParseColor(args[4]) : KDColorWhite;
|
||||
KDColor textColor = (n_args >= 4) ? MicroPython::Color::Parse(args[3]) : KDColorBlack;
|
||||
KDColor backgroundColor = (n_args >= 5) ? MicroPython::Color::Parse(args[4]) : KDColorWhite;
|
||||
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
|
||||
KDIonContext::sharedContext()->drawString(text, point, KDFont::LargeFont, textColor, backgroundColor);
|
||||
/* Before and after execution of "modkandinsky_draw_string",
|
||||
@@ -90,7 +90,7 @@ mp_obj_t modkandinsky_fill_rect(size_t n_args, const mp_obj_t * args) {
|
||||
y = y - height;
|
||||
}
|
||||
KDRect rect(x, y, width, height);
|
||||
KDColor color = MicroPython::ColorParser::ParseColor(args[4]);
|
||||
KDColor color = MicroPython::Color::Parse(args[4]);
|
||||
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
|
||||
KDIonContext::sharedContext()->fillRect(rect, color);
|
||||
// Cf comment on modkandinsky_draw_string
|
||||
|
||||
@@ -42,7 +42,7 @@ static size_t extractArgumentsAndCheckEqualSize(mp_obj_t x, mp_obj_t y, mp_obj_t
|
||||
* - of the required size
|
||||
*/
|
||||
|
||||
size_t extractArgumentAndValidateSize(mp_obj_t arg, size_t requiredlength, mp_obj_t ** items) {
|
||||
static size_t extractArgumentAndValidateSize(mp_obj_t arg, size_t requiredlength, mp_obj_t ** items) {
|
||||
size_t itemLength = extractArgument(arg, items);
|
||||
if (itemLength > 1 && requiredlength > 1 && itemLength != requiredlength) {
|
||||
mp_raise_ValueError("shape mismatch");
|
||||
@@ -50,6 +50,18 @@ size_t extractArgumentAndValidateSize(mp_obj_t arg, size_t requiredlength, mp_ob
|
||||
return itemLength;
|
||||
}
|
||||
|
||||
// Get color from keyword arguments if possible
|
||||
|
||||
bool colorFromKeywordArgument(mp_map_elem_t * elemColor, KDColor * color) {
|
||||
if (elemColor != nullptr) {
|
||||
*color = MicroPython::Color::Parse(elemColor->value);
|
||||
return true;
|
||||
} else {
|
||||
*color = Palette::nextDataColor(&paletteIndex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal functions
|
||||
|
||||
mp_obj_t modpyplot___init__() {
|
||||
@@ -79,16 +91,34 @@ void modpyplot_flush_used_heap() {
|
||||
}
|
||||
}
|
||||
|
||||
/* arrow(x,y,dx,dy)
|
||||
/* arrow(x,y,dx,dy, KW : head_width, color)
|
||||
* x, y, dx, dy scalars
|
||||
* */
|
||||
|
||||
mp_obj_t modpyplot_arrow(size_t n_args, const mp_obj_t *args) {
|
||||
assert(n_args == 4);
|
||||
mp_obj_t modpyplot_arrow(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args) {
|
||||
assert(sPlotStore != nullptr);
|
||||
sPlotStore->setShow(true);
|
||||
|
||||
KDColor color = Palette::nextDataColor(&paletteIndex);
|
||||
sPlotStore->addSegment(args[0], args[1], mp_obj_float_binary_op(MP_BINARY_OP_INPLACE_ADD, mp_obj_get_float(args[0]), args[2]), mp_obj_float_binary_op(MP_BINARY_OP_INPLACE_ADD, mp_obj_get_float(args[1]), args[3]), color, true);
|
||||
if (n_args > 4) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,"arrow() takes 4 positional arguments but %d were given",n_args));
|
||||
}
|
||||
|
||||
mp_map_elem_t * elem;
|
||||
// Setting arrow width
|
||||
elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_head_width), MP_MAP_LOOKUP);
|
||||
/* Default head_width is 0.0f because we want a default width in pixel
|
||||
* coordinates which is handled by CurveView::drawArrow. */
|
||||
mp_obj_t arrowWidth = (elem == nullptr) ? mp_obj_new_float(0.0f) : elem->value;
|
||||
|
||||
// Setting arrow color
|
||||
KDColor color;
|
||||
// color keyword
|
||||
elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||
colorFromKeywordArgument(elem, &color);
|
||||
|
||||
// Adding the object to the plot
|
||||
assert(n_args >= 4);
|
||||
sPlotStore->addSegment(args[0], args[1], mp_obj_new_float(mp_obj_get_float(args[0]) + mp_obj_get_float(args[2])), mp_obj_new_float(mp_obj_get_float(args[1]) + mp_obj_get_float(args[3])), color, arrowWidth);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@@ -100,7 +130,7 @@ mp_obj_t modpyplot_arrow(size_t n_args, const mp_obj_t *args) {
|
||||
|
||||
mp_obj_t modpyplot_axis(size_t n_args, const mp_obj_t *args) {
|
||||
assert(sPlotStore != nullptr);
|
||||
|
||||
sPlotStore->setShow(true);
|
||||
if (n_args == 1) {
|
||||
mp_obj_t arg = args[0];
|
||||
if (mp_obj_is_str(arg)) {
|
||||
@@ -143,23 +173,26 @@ mp_obj_t modpyplot_axis(size_t n_args, const mp_obj_t *args) {
|
||||
return mp_obj_new_tuple(4, coords);
|
||||
}
|
||||
|
||||
/* bar(x, height, width, bottom)
|
||||
/* bar(x, height, width, bottom, KW :color)
|
||||
* 'x', 'height', 'width' and 'bottom' can either be a scalar or an array/tuple of
|
||||
* scalar.
|
||||
* 'width' default value is 0.8
|
||||
* 'bottom' default value is None
|
||||
* */
|
||||
|
||||
// TODO: accept keyword args?
|
||||
|
||||
mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args) {
|
||||
assert(sPlotStore != nullptr);
|
||||
|
||||
if (n_args > 4) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,"bar() takes from 2 to 4 positional arguments but %d were given",n_args));
|
||||
}
|
||||
sPlotStore->setShow(true);
|
||||
mp_obj_t * xItems;
|
||||
mp_obj_t * hItems;
|
||||
mp_obj_t * wItems;
|
||||
mp_obj_t * bItems;
|
||||
|
||||
assert(n_args >= 2);
|
||||
|
||||
// x arg
|
||||
size_t xLength = extractArgument(args[0], &xItems);
|
||||
|
||||
@@ -184,7 +217,13 @@ mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args) {
|
||||
bItems[0] = mp_obj_new_float(0.0f);
|
||||
}
|
||||
|
||||
KDColor color = Palette::nextDataColor(&paletteIndex);
|
||||
// Setting bar color
|
||||
// color keyword
|
||||
KDColor color;
|
||||
// color keyword
|
||||
mp_map_elem_t * elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||
colorFromKeywordArgument(elem, &color);
|
||||
|
||||
for (size_t i=0; i<xLength; i++) {
|
||||
mp_obj_t iH = hItems[hLength > 1 ? i : 0];
|
||||
mp_obj_t iW = wItems[wLength > 1 ? i : 0];
|
||||
@@ -196,7 +235,7 @@ mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t rectLeft = mp_obj_new_float(iXf - iWf/2.0f);
|
||||
mp_obj_t rectRight = mp_obj_new_float(iXf + iWf/2.0f);
|
||||
mp_obj_t rectBottom = iB;
|
||||
mp_obj_t rectTop = mp_obj_float_binary_op(MP_BINARY_OP_INPLACE_ADD, mp_obj_get_float(iH), iB);
|
||||
mp_obj_t rectTop = mp_obj_new_float(mp_obj_get_float(iH) + mp_obj_get_float(iB));
|
||||
if (mp_obj_get_float(iH) < 0.0) {
|
||||
mp_obj_t temp = rectTop;
|
||||
rectTop = rectBottom;
|
||||
@@ -209,28 +248,33 @@ mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args) {
|
||||
|
||||
mp_obj_t modpyplot_grid(size_t n_args, const mp_obj_t *args) {
|
||||
assert(sPlotStore != nullptr);
|
||||
|
||||
sPlotStore->setShow(true);
|
||||
if (n_args == 0) {
|
||||
// Toggle the grid visibility
|
||||
sPlotStore->setGridRequested(!sPlotStore->gridRequested());
|
||||
} else {
|
||||
assert(n_args >= 1);
|
||||
sPlotStore->setGridRequested(mp_obj_is_true(args[0]));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/* hist(x, bins)
|
||||
/* hist(x, bins KW : color)
|
||||
* 'x' array
|
||||
* 'bins': (default value 10)
|
||||
* - int (number of bins)
|
||||
* - sequence of bins
|
||||
* */
|
||||
|
||||
mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args ) {
|
||||
if (n_args > 2) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,"hist() takes from 1 to 2 positional arguments but %d were given",n_args));
|
||||
}
|
||||
assert(sPlotStore != nullptr);
|
||||
|
||||
sPlotStore->setShow(true);
|
||||
// Sort data to easily get the minimal and maximal value and count bin sizes
|
||||
mp_obj_t * xItems;
|
||||
assert(n_args >= 1);
|
||||
size_t xLength = extractArgument(args[0], &xItems);
|
||||
if (xLength == 0) {
|
||||
return mp_const_none;
|
||||
@@ -298,25 +342,44 @@ mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args) {
|
||||
binIndex++;
|
||||
}
|
||||
|
||||
KDColor color = Palette::nextDataColor(&paletteIndex);
|
||||
// Setting hist color
|
||||
// color keyword
|
||||
KDColor color;
|
||||
// color keyword
|
||||
mp_map_elem_t * elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||
colorFromKeywordArgument(elem, &color);
|
||||
|
||||
for (size_t i=0; i<nBins; i++) {
|
||||
sPlotStore->addRect(edgeItems[i], edgeItems[i+1], binItems[i], mp_obj_new_float(0.0), color);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/* scatter(x, y)
|
||||
/* scatter(x, y, KW : color)
|
||||
* - x, y: list
|
||||
* - x, y: scalar
|
||||
* */
|
||||
|
||||
mp_obj_t modpyplot_scatter(mp_obj_t x, mp_obj_t y) {
|
||||
mp_obj_t modpyplot_scatter(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args) {
|
||||
assert(sPlotStore != nullptr);
|
||||
|
||||
if (n_args > 2) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,"scatter() takes 2 positional arguments but %d were given",n_args));
|
||||
}
|
||||
sPlotStore->setShow(true);
|
||||
mp_obj_t * xItems, * yItems;
|
||||
size_t length = extractArgumentsAndCheckEqualSize(x, y, &xItems, &yItems);
|
||||
assert(n_args >= 2);
|
||||
size_t length = extractArgumentsAndCheckEqualSize(args[0], args[1], &xItems, &yItems);
|
||||
|
||||
// Setting scatter color
|
||||
// color keyword
|
||||
KDColor color;
|
||||
// c keyword
|
||||
mp_map_elem_t * elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_c), MP_MAP_LOOKUP);
|
||||
colorFromKeywordArgument(elem, &color);
|
||||
// color keyword
|
||||
elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||
colorFromKeywordArgument(elem, &color);
|
||||
|
||||
KDColor color = Palette::nextDataColor(&paletteIndex);
|
||||
for (size_t i=0; i<length; i++) {
|
||||
sPlotStore->addDot(xItems[i], yItems[i], color);
|
||||
}
|
||||
@@ -324,13 +387,16 @@ mp_obj_t modpyplot_scatter(mp_obj_t x, mp_obj_t y) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/* plot(x, y) plots the curve (x, y)
|
||||
/* plot(x, y) plots the curve (x, y, KW : color)
|
||||
* plot(y) plots the curve x as index array ([0,1,2...],y)
|
||||
* */
|
||||
|
||||
mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args,mp_map_t* kw_args) {
|
||||
assert(sPlotStore != nullptr);
|
||||
|
||||
sPlotStore->setShow(true);
|
||||
if (n_args > 3) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,"plot() takes 3 positional arguments but %d were given",n_args));
|
||||
}
|
||||
mp_obj_t * xItems, * yItems;
|
||||
size_t length;
|
||||
if (n_args == 1) {
|
||||
@@ -342,13 +408,26 @@ mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args) {
|
||||
xItems[i] = mp_obj_new_float((float)i);
|
||||
}
|
||||
} else {
|
||||
assert(n_args == 2);
|
||||
assert(n_args >= 2);
|
||||
length = extractArgumentsAndCheckEqualSize(args[0], args[1], &xItems, &yItems);
|
||||
}
|
||||
|
||||
KDColor color = Palette::nextDataColor(&paletteIndex);
|
||||
// Setting plot color
|
||||
KDColor color;
|
||||
bool isUserSet = false;
|
||||
// c keyword
|
||||
mp_map_elem_t * elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_c), MP_MAP_LOOKUP);
|
||||
isUserSet = colorFromKeywordArgument(elem, &color);
|
||||
// color keyword
|
||||
elem = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||
isUserSet = isUserSet | colorFromKeywordArgument(elem, &color);
|
||||
// Eventual third positional argument
|
||||
if (!isUserSet && n_args >= 3) {
|
||||
color = MicroPython::Color::Parse(args[2]);
|
||||
}
|
||||
|
||||
for (int i=0; i<(int)length-1; i++) {
|
||||
sPlotStore->addSegment(xItems[i], yItems[i], xItems[i+1], yItems[i+1], color, false);
|
||||
sPlotStore->addSegment(xItems[i], yItems[i], xItems[i+1], yItems[i+1], color);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
@@ -356,7 +435,7 @@ mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args) {
|
||||
|
||||
mp_obj_t modpyplot_text(mp_obj_t x, mp_obj_t y, mp_obj_t s) {
|
||||
assert(sPlotStore != nullptr);
|
||||
|
||||
sPlotStore->setShow(true);
|
||||
// Input parameter validation
|
||||
mp_obj_get_float(x);
|
||||
mp_obj_get_float(y);
|
||||
@@ -368,10 +447,11 @@ mp_obj_t modpyplot_text(mp_obj_t x, mp_obj_t y, mp_obj_t s) {
|
||||
}
|
||||
|
||||
mp_obj_t modpyplot_show() {
|
||||
if (sPlotStore->isEmpty()) {
|
||||
if (!sPlotStore->show()) {
|
||||
return mp_const_none;
|
||||
}
|
||||
MicroPython::ExecutionEnvironment * env = MicroPython::ExecutionEnvironment::currentExecutionEnvironment();
|
||||
env->displayViewController(sPlotController);
|
||||
sPlotStore->setShow(false);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ mp_obj_t modpyplot___init__();
|
||||
void modpyplot_gc_collect();
|
||||
void modpyplot_flush_used_heap();
|
||||
|
||||
mp_obj_t modpyplot_arrow(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modpyplot_arrow(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args);
|
||||
mp_obj_t modpyplot_axis(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args);
|
||||
mp_obj_t modpyplot_grid(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modpyplot_scatter(mp_obj_t x, mp_obj_t y);
|
||||
mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args);
|
||||
mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args);
|
||||
mp_obj_t modpyplot_scatter(size_t n_args, const mp_obj_t *args, mp_map_t* kw_args);
|
||||
mp_obj_t modpyplot_text(mp_obj_t x, mp_obj_t y, mp_obj_t s);
|
||||
mp_obj_t modpyplot_show();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "modpyplot.h"
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modpyplot___init___obj, modpyplot___init__);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_arrow_obj, 4, 4, modpyplot_arrow);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(modpyplot_arrow_obj, 4, modpyplot_arrow);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_axis_obj, 0, 1, modpyplot_axis);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_bar_obj, 2, 4, modpyplot_bar);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(modpyplot_bar_obj, 2, modpyplot_bar);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_grid_obj, 0, 1, modpyplot_grid);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_hist_obj, 1, 2, modpyplot_hist);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_plot_obj, 1, 2, modpyplot_plot);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(modpyplot_scatter_obj, modpyplot_scatter);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(modpyplot_hist_obj, 1, modpyplot_hist);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(modpyplot_plot_obj, 1, modpyplot_plot);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(modpyplot_scatter_obj, 2, modpyplot_scatter);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modpyplot_show_obj, modpyplot_show);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(modpyplot_text_obj, modpyplot_text);
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
namespace Matplotlib {
|
||||
|
||||
PlotStore::PlotStore() : Shared::InteractiveCurveViewRange(),
|
||||
m_axesRequested(true),
|
||||
m_axesAuto(true),
|
||||
m_gridRequested(false)
|
||||
m_show(false)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
@@ -21,10 +19,6 @@ void PlotStore::flush() {
|
||||
m_gridRequested = false;
|
||||
}
|
||||
|
||||
bool PlotStore::isEmpty() {
|
||||
return MP_OBJ_SMALL_INT_VALUE(mp_obj_len(m_dots)) == 0 && MP_OBJ_SMALL_INT_VALUE(mp_obj_len(m_segments)) == 0 && MP_OBJ_SMALL_INT_VALUE(mp_obj_len(m_rects)) == 0 && MP_OBJ_SMALL_INT_VALUE(mp_obj_len(m_labels)) == 0;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
|
||||
template <class T>
|
||||
@@ -62,15 +56,6 @@ T PlotStore::ListIterator<T>::operator*() {
|
||||
return T(m_tuples[m_tupleIndex]);
|
||||
};
|
||||
|
||||
void checkFloatType(mp_obj_t * elements, size_t nbOfElements) {
|
||||
for (size_t i = 0; i < nbOfElements; i++) {
|
||||
// TODO: we don't take advantage of the fact that we extracted the value at the sametime... Maybe change the way things are done, build the c objects in addItem instead of allocating them on the python heap? Or use float array in python?
|
||||
mp_float_t value;
|
||||
if (!mp_obj_get_float_maybe(elements[i], &value)) {
|
||||
mp_raise_TypeError("argument should be a number");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dot
|
||||
|
||||
@@ -87,7 +72,6 @@ PlotStore::Dot::Dot(mp_obj_t tuple) {
|
||||
void PlotStore::addDot(mp_obj_t x, mp_obj_t y, KDColor c) {
|
||||
mp_obj_t color = mp_obj_new_int(c);
|
||||
mp_obj_t items[3] = {x, y, color};
|
||||
checkFloatType(items, 2);
|
||||
mp_obj_t tuple = mp_obj_new_tuple(3, items);
|
||||
mp_obj_list_append(m_dots, tuple);
|
||||
}
|
||||
@@ -103,14 +87,13 @@ PlotStore::Segment::Segment(mp_obj_t tuple) {
|
||||
m_yStart = mp_obj_get_float(elements[1]);
|
||||
m_xEnd = mp_obj_get_float(elements[2]);
|
||||
m_yEnd = mp_obj_get_float(elements[3]);
|
||||
m_color = KDColor::RGB16(mp_obj_get_int(elements[4]));
|
||||
m_arrow = elements[5] == mp_const_true;
|
||||
m_arrowWidth = mp_obj_get_float(elements[4]);
|
||||
m_color = KDColor::RGB16(mp_obj_get_int(elements[5]));
|
||||
}
|
||||
|
||||
void PlotStore::addSegment(mp_obj_t xStart, mp_obj_t yStart, mp_obj_t xEnd, mp_obj_t yEnd, KDColor c, bool arrowEdge) {
|
||||
void PlotStore::addSegment(mp_obj_t xStart, mp_obj_t yStart, mp_obj_t xEnd, mp_obj_t yEnd, KDColor c, mp_obj_t arrowWidth) {
|
||||
mp_obj_t color = mp_obj_new_int(c);
|
||||
mp_obj_t items[6] = {xStart, yStart, xEnd, yEnd, color, arrowEdge ? mp_const_true : mp_const_false};
|
||||
checkFloatType(items, 4);
|
||||
mp_obj_t items[6] = {xStart, yStart, xEnd, yEnd, arrowWidth, color};
|
||||
mp_obj_t tuple = mp_obj_new_tuple(6, items);
|
||||
mp_obj_list_append(m_segments, tuple);
|
||||
}
|
||||
@@ -132,7 +115,6 @@ PlotStore::Rect::Rect(mp_obj_t tuple) {
|
||||
void PlotStore::addRect(mp_obj_t left, mp_obj_t right, mp_obj_t top, mp_obj_t bottom, KDColor c) {
|
||||
mp_obj_t color = mp_obj_new_int(c);
|
||||
mp_obj_t items[5] = {left, right, top, bottom, color};
|
||||
checkFloatType(items, 4);
|
||||
mp_obj_t tuple = mp_obj_new_tuple(5, items);
|
||||
mp_obj_list_append(m_rects, tuple);
|
||||
}
|
||||
@@ -151,7 +133,6 @@ PlotStore::Label::Label(mp_obj_t tuple) {
|
||||
|
||||
void PlotStore::addLabel(mp_obj_t x, mp_obj_t y, mp_obj_t string) {
|
||||
mp_obj_t items[3] = {x, y, string};
|
||||
checkFloatType(items, 2);
|
||||
if (!mp_obj_is_str(string)) {
|
||||
mp_raise_TypeError("argument should be a string");
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ class PlotStore : public Shared::InteractiveCurveViewRange {
|
||||
public:
|
||||
PlotStore();
|
||||
void flush();
|
||||
bool isEmpty();
|
||||
|
||||
// Iterators
|
||||
|
||||
@@ -68,18 +67,18 @@ public:
|
||||
float yStart() const { return m_yStart; }
|
||||
float xEnd() const { return m_xEnd; }
|
||||
float yEnd() const { return m_yEnd; }
|
||||
bool isArrow() const { return m_arrow; }
|
||||
float arrowWidth() const { return m_arrowWidth; }
|
||||
KDColor color() const { return m_color; }
|
||||
private:
|
||||
float m_xStart;
|
||||
float m_yStart;
|
||||
float m_xEnd;
|
||||
float m_yEnd;
|
||||
bool m_arrow;
|
||||
float m_arrowWidth;
|
||||
KDColor m_color;
|
||||
};
|
||||
|
||||
void addSegment(mp_obj_t xStart, mp_obj_t yStart, mp_obj_t xEnd, mp_obj_t yEnd, KDColor c, bool arrowEdge);
|
||||
void addSegment(mp_obj_t xStart, mp_obj_t yStart, mp_obj_t xEnd, mp_obj_t yEnd, KDColor c, mp_obj_t arrowWidth = mp_obj_new_float(NAN));
|
||||
Iterable<ListIterator<Segment>> segments() { return Iterable<ListIterator<Segment>>(m_segments); }
|
||||
|
||||
// Rect
|
||||
@@ -123,6 +122,8 @@ public:
|
||||
void setAxesRequested(bool b) { m_axesRequested = b; }
|
||||
bool axesRequested() const { return m_axesRequested; }
|
||||
void setAxesAuto(bool b) { m_axesAuto = b; }
|
||||
void setShow(bool b) { m_show = b; }
|
||||
bool show() { return m_show; }
|
||||
void initRange();
|
||||
|
||||
void setGridRequested(bool b) { m_gridRequested = b; }
|
||||
@@ -135,6 +136,7 @@ private:
|
||||
bool m_axesRequested;
|
||||
bool m_axesAuto;
|
||||
bool m_gridRequested;
|
||||
bool m_show;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ void PlotView::traceSegment(KDContext * ctx, KDRect r, PlotStore::Segment segmen
|
||||
segment.xEnd(), segment.yEnd(),
|
||||
segment.color()
|
||||
);
|
||||
if (segment.isArrow()) {
|
||||
if (!std::isnan(segment.arrowWidth())) {
|
||||
float dx = segment.xEnd() - segment.xStart();
|
||||
float dy = segment.yEnd() - segment.yStart();
|
||||
drawArrow(ctx, r, segment.xEnd(), segment.yEnd(), dx, dy, segment.color());
|
||||
drawArrow(ctx, r, segment.xEnd(), segment.yEnd(), dx, dy, segment.color(), segment.arrowWidth());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ mp_obj_t modturtle_pencolor(size_t n_args, const mp_obj_t *args) {
|
||||
// pencolor()
|
||||
KDColor c = sTurtle.color();
|
||||
mp_obj_t mp_col[3];
|
||||
if(sTurtle.colorMode() == MicroPython::ColorParser::ColorMode::MaxIntensity255){
|
||||
if(sTurtle.colorMode() == MicroPython::Color::Mode::MaxIntensity255){
|
||||
mp_col[0] = mp_obj_new_int_from_uint(c.red());
|
||||
mp_col[1] = mp_obj_new_int_from_uint(c.green());
|
||||
mp_col[2] = mp_obj_new_int_from_uint(c.blue());
|
||||
@@ -161,21 +161,29 @@ mp_obj_t modturtle_pencolor(size_t n_args, const mp_obj_t *args) {
|
||||
assert(n_args == 3);
|
||||
color = mp_obj_new_tuple(n_args, args);
|
||||
}
|
||||
sTurtle.setColor(MicroPython::ColorParser::ParseColor(color, sTurtle.colorMode()));
|
||||
sTurtle.setColor(MicroPython::Color::Parse(color, sTurtle.colorMode()));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t modturtle_colormode(size_t n_args, const mp_obj_t *args) {
|
||||
if(n_args == 0){
|
||||
return mp_obj_new_int_from_uint(static_cast<int>(sTurtle.colorMode()));
|
||||
} else{
|
||||
int colorMode = mp_obj_get_int(args[0]);
|
||||
if (colorMode != static_cast<int>(MicroPython::ColorParser::ColorMode::MaxIntensity1) &&
|
||||
colorMode != static_cast<int>(MicroPython::ColorParser::ColorMode::MaxIntensity255)) {
|
||||
} else {
|
||||
// To accept both colormode(1) and colormode(1.0) we try to get args[0] as both int and float
|
||||
mp_float_t decimalOne = mp_obj_get_float(args[0]);
|
||||
int colorMode;
|
||||
// But only 1 is accepted as float, 255 must be int
|
||||
if (decimalOne == 1.0) {
|
||||
colorMode = static_cast<int>(MicroPython::Color::Mode::MaxIntensity1);
|
||||
} else {
|
||||
colorMode = mp_obj_get_int(args[0]);
|
||||
}
|
||||
if (colorMode != static_cast<int>(MicroPython::Color::Mode::MaxIntensity1) &&
|
||||
colorMode != static_cast<int>(MicroPython::Color::Mode::MaxIntensity255)) {
|
||||
mp_raise_ValueError("Colormode can be 1 or 255");
|
||||
return mp_const_none;
|
||||
}
|
||||
sTurtle.setColorMode(static_cast<MicroPython::ColorParser::ColorMode>(colorMode));
|
||||
sTurtle.setColorMode(static_cast<MicroPython::Color::Mode>(colorMode));
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
@@ -193,3 +201,9 @@ mp_obj_t modturtle_hideturtle() {
|
||||
mp_obj_t modturtle_isvisible() {
|
||||
return sTurtle.isVisible() ? mp_const_true : mp_const_false;
|
||||
}
|
||||
|
||||
mp_obj_t modturtle_write(mp_obj_t s) {
|
||||
const char * string = mp_obj_str_get_str(s);
|
||||
sTurtle.write(string);
|
||||
return mp_const_none;
|
||||
}
|
||||
@@ -23,6 +23,7 @@ mp_obj_t modturtle_penup();
|
||||
mp_obj_t modturtle_isdown();
|
||||
mp_obj_t modturtle_pensize(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modturtle_isvisible();
|
||||
mp_obj_t modturtle_write(mp_obj_t s);
|
||||
|
||||
mp_obj_t modturtle_pencolor(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modturtle_colormode(size_t n_args, const mp_obj_t *args);
|
||||
|
||||
@@ -25,6 +25,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(modturtle_reset_obj, modturtle_reset);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modturtle_showturtle_obj, modturtle_showturtle);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modturtle_hideturtle_obj, modturtle_hideturtle);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modturtle_isvisible_obj, modturtle_isvisible);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(modturtle_write_obj, modturtle_write);
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modturtle___init___obj, modturtle___init__);
|
||||
|
||||
@@ -74,6 +75,7 @@ STATIC const mp_rom_map_elem_t modturtle_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_hideturtle), (mp_obj_t)&modturtle_hideturtle_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ht), (mp_obj_t)&modturtle_hideturtle_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_isvisible), (mp_obj_t)&modturtle_isvisible_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), (mp_obj_t)&modturtle_write_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(modturtle_module_globals, modturtle_module_globals_table);
|
||||
|
||||
@@ -175,6 +175,21 @@ void Turtle::setVisible(bool visible) {
|
||||
}
|
||||
}
|
||||
|
||||
void Turtle::write(const char * string) {
|
||||
// We erase the turtle to redraw it on top of the text
|
||||
erase();
|
||||
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
static constexpr KDCoordinate headOffsetLength = 6;
|
||||
KDCoordinate headOffsetX = headOffsetLength * std::cos(m_heading * k_headingScale);
|
||||
KDCoordinate headOffsetY = k_invertedYAxisCoefficient * headOffsetLength * std::sin(m_heading * k_headingScale);
|
||||
KDPoint headOffset(headOffsetX, headOffsetY);
|
||||
KDPoint head(-k_iconHeadSize, -k_iconHeadSize);
|
||||
KDPoint stringOffset = KDPoint(0,-k_font->glyphSize().height());
|
||||
ctx->drawString(string, position().translatedBy(headOffset).translatedBy(head).translatedBy(stringOffset));
|
||||
draw(true);
|
||||
}
|
||||
|
||||
|
||||
void Turtle::viewDidDisappear() {
|
||||
m_drawn = false;
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
m_y(0),
|
||||
m_heading(0),
|
||||
m_color(k_defaultColor),
|
||||
m_colorMode(MicroPython::ColorParser::ColorMode::MaxIntensity255),
|
||||
m_colorMode(MicroPython::Color::Mode::MaxIntensity255),
|
||||
m_penDown(true),
|
||||
m_visible(true),
|
||||
m_speed(k_defaultSpeed),
|
||||
@@ -73,11 +73,13 @@ public:
|
||||
void setColor(uint8_t r, uint8_t g, uint8_t b) {
|
||||
m_color = KDColor::RGB888(r, g, b);
|
||||
}
|
||||
MicroPython::ColorParser::ColorMode colorMode() const {return m_colorMode; }
|
||||
void setColorMode(MicroPython::ColorParser::ColorMode colorMode){
|
||||
MicroPython::Color::Mode colorMode() const {return m_colorMode; }
|
||||
void setColorMode(MicroPython::Color::Mode colorMode){
|
||||
m_colorMode = colorMode;
|
||||
}
|
||||
|
||||
void write(const char * string);
|
||||
|
||||
void viewDidDisappear();
|
||||
|
||||
private:
|
||||
@@ -91,6 +93,7 @@ private:
|
||||
static constexpr uint8_t k_maxSpeed = 10;
|
||||
static constexpr KDColor k_defaultColor = KDColorBlack;
|
||||
static constexpr uint8_t k_defaultPenSize = 1;
|
||||
static constexpr const KDFont * k_font = KDFont::LargeFont;
|
||||
|
||||
enum class PawType : uint8_t {
|
||||
FrontRight = 0,
|
||||
@@ -141,7 +144,7 @@ private:
|
||||
mp_float_t m_heading;
|
||||
|
||||
KDColor m_color;
|
||||
MicroPython::ColorParser::ColorMode m_colorMode;
|
||||
MicroPython::Color::Mode m_colorMode;
|
||||
bool m_penDown;
|
||||
bool m_visible;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user