2 #include "../constant.h" 15 m_bannerView(bannerView),
16 m_curveViewCursor(curveViewCursor),
17 m_curveViewRange(curveViewRange),
18 m_cursorView(cursorView),
20 m_mainViewSelected(
false),
21 m_drawnRangeVersion(0)
27 if (m_drawnRangeVersion != rangeVersion) {
29 m_drawnRangeVersion = rangeVersion;
43 return m_mainViewSelected;
47 if (m_mainViewSelected != mainViewSelected) {
48 m_mainViewSelected = mainViewSelected;
54 m_curveViewRange = curveViewRange;
66 m_cursorView = cursorView;
91 float CurveView::min(Axis axis)
const {
96 float CurveView::max(Axis axis)
const {
101 float CurveView::gridUnit(Axis axis)
const {
112 return min(axis) + pixels*((max(axis)-min(axis))/pixelLength(axis));
116 float fraction = (f-min(axis))/(max(axis)-min(axis));
125 fraction = fraction < -10.0f ? -10.0f : fraction;
126 fraction = fraction > 10.0f ? 10.0f : fraction;
127 return pixelLength(axis)*fraction;
132 float step = gridUnit(axis);
133 for (
int index = 0; index < numberOfLabels(axis); index++) {
134 float labelValue = 2.0f*step*(
std::ceil(min(axis)/(2.0f*step)))+index*2.0f*step;
135 if (labelValue < step && labelValue > -step) {
138 PrintFloat::convertFloatToText<float>(labelValue, buffer,
147 float step = gridUnit(axis);
149 float end = max(axis);
151 for (
float x =
start; x < end; x += 2.0f*step) {
154 if (x == x-step || x == x+step) {
164 if (-step < x && x < step && shiftOrigin) {
181 rect.
width(), thickness
219 {0xE1, 0x45, 0x0C, 0x45, 0xE1},
220 {0x45, 0x00, 0x00, 0x00, 0x45},
221 {0x00, 0x00, 0x00, 0x00, 0x00},
222 {0x45, 0x00, 0x00, 0x00, 0x45},
223 {0xE1, 0x45, 0x0C, 0x45, 0xE1},
228 {0xE1, 0x45, 0x0C, 0x00, 0x0C, 0x45, 0xE1},
229 {0x45, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x45},
230 {0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C},
231 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
232 {0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C},
233 {0x45, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x45},
234 {0xE1, 0x45, 0x0C, 0x00, 0x0C, 0x45, 0xE1},
263 float start = step*((int)(min(axis)/step));
265 for (
float x =
start; x < max(axis); x += step) {
268 if (x == x-step || x == x+step) {
271 if (rectMin <= x && x <= rectMax) {
272 drawLine(ctx, rect, otherAxis, x, color);
286 #define LINE_THICKNESS 2 288 #if LINE_THICKNESS == 1 298 #elif LINE_THICKNESS == 2 303 {0xFF, 0xE6, 0xE6, 0xFF},
304 {0xE6, 0x33, 0x33, 0xE6},
305 {0xE6, 0x33, 0x33, 0xE6},
306 {0xFF, 0xE6, 0xE6, 0xFF},
309 #elif LINE_THICKNESS == 3 314 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
315 {0xFF, 0x7A, 0x0C, 0x7A, 0xFF},
316 {0xFF, 0x0C, 0x00, 0x0C, 0xFF},
317 {0xFF, 0x7A, 0x0C, 0x7A, 0xFF},
318 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
321 #elif LINE_THICKNESS == 5 326 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
327 {0xFF, 0xE1, 0x45, 0x0C, 0x45, 0xE1, 0xFF},
328 {0xFF, 0x45, 0x00, 0x00, 0x00, 0x45, 0xFF},
329 {0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0xFF},
330 {0xFF, 0x45, 0x00, 0x00, 0x00, 0x45, 0xFF},
331 {0xFF, 0xE1, 0x45, 0x0C, 0x45, 0xE1, 0xFF},
332 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
337 constexpr
static int k_maxNumberOfIterations = 10;
349 for (
float x = rectMin; x < rectMax; x += xStep) {
352 if (x == x-xStep || x == x+xStep) {
355 float y = evaluation(x,
model, context);
361 if (colorUnderCurve && pxf > pixelColorLowerBound && pxf < pixelColorUpperBound) {
368 stampAtLocation(ctx, rect, pxf, pyf, color);
375 straightJoinDots(ctx, rect, puf, pvf, pxf, pyf, color);
377 jointDots(ctx, rect, evaluation,
model, context, x - xStep, evaluation(x-xStep,
model, context), x, y, color, k_maxNumberOfIterations);
383 bool fillBar,
KDColor defaultColor,
KDColor highlightColor,
float highlightLowerBound,
float highlightUpperBound)
const {
385 float rectMinBinNumber =
std::floor((rectMin - firstBarAbscissa)/barWidth);
386 float rectMinLowerBound = firstBarAbscissa + rectMinBinNumber*barWidth;
388 float rectMaxBinNumber =
std::floor((rectMax - firstBarAbscissa)/barWidth);
389 float rectMaxUpperBound = firstBarAbscissa + (rectMaxBinNumber+1)*barWidth + barWidth;
392 for (
float x = rectMinLowerBound; x < rectMaxUpperBound; x += barWidth) {
395 if (x == x-barWidth || x == x+barWidth) {
398 float centerX = fillBar ? x+barWidth/2.0f : x;
399 float y = evaluation(centerX,
model, context);
410 KDColor binColor = defaultColor;
411 bool shouldColorBin = fillBar ? centerX >= highlightLowerBound && centerX <= highlightUpperBound : pxf >=
floorf(pHighlightLowerBound) && pxf <=
floorf(pHighlightUpperBound);
412 if (shouldColorBin) {
413 binColor = highlightColor;
419 int CurveView::numberOfLabels(Axis axis)
const {
421 if (min(otherAxis) > 0.0f || max(otherAxis) < 0.0f) {
424 return std::ceil((max(axis) - min(axis))/(2*gridUnit(axis)));
427 void CurveView::jointDots(
KDContext * ctx,
KDRect rect, EvaluateModelWithParameter evaluation,
void *
model,
void * context,
float x,
float y,
float u,
float v,
KDColor color,
int maxNumberOfRecursion)
const {
449 float cx = (x + u)/2.0f;
450 float cy = evaluation(cx,
model, context);
451 if ((y <= cy && cy <= v) || (v <= cy && cy <= y)) {
459 straightJoinDots(ctx, rect, pxf, pyf, puf, pvf, color);
464 if (maxNumberOfRecursion > 0) {
465 stampAtLocation(ctx, rect, pcxf, pcyf, color);
466 jointDots(ctx, rect, evaluation,
model, context, x, y, cx, cy, color, maxNumberOfRecursion-1);
467 jointDots(ctx, rect, evaluation,
model, context, cx, cy, u, v, color, maxNumberOfRecursion-1);
471 void CurveView::straightJoinDots(
KDContext * ctx,
KDRect rect,
float pxf,
float pyf,
float puf,
float pvf,
KDColor color)
const {
473 for (
float pnf = pyf; pnf<pvf; pnf+= 1.0f) {
474 float pmf = pxf + (pnf - pyf)*(puf - pxf)/(pvf - pyf);
475 stampAtLocation(ctx, rect, pmf, pnf, color);
479 straightJoinDots(ctx, rect, puf, pvf, pxf, pyf, color);
482 void CurveView::stampAtLocation(
KDContext * ctx,
KDRect rect,
float pxf,
float pyf,
KDColor color)
const {
509 void CurveView::layoutSubviews() {
511 m_cursorView->
setFrame(cursorFrame());
516 if (m_okView !=
nullptr) {
521 KDRect CurveView::cursorFrame() {
527 cursorFrame =
KDRect(xCursorPixelPosition - (cursorSize.
width()-1)/2, yCursorPixelPosition - (cursorSize.
height()-1)/2, cursorSize.
width(), cursorSize.
height());
528 if (cursorSize.
height() == 0) {
536 KDRect CurveView::bannerFrame() {
540 bannerFrame =
KDRect(0,
bounds().height()- bannerHeight,
bounds().width(), bannerHeight);
545 KDRect CurveView::okFrame() {
547 if (m_okView && m_mainViewSelected) {
558 int CurveView::numberOfSubviews()
const {
559 return (
m_bannerView !=
nullptr) + (m_cursorView !=
nullptr) + (m_okView !=
nullptr);
562 View * CurveView::subviewAtIndex(
int index) {
563 assert(index >= 0 && index < 3);
568 if (m_okView !=
nullptr) {
576 if (index == 1 &&
m_bannerView !=
nullptr && m_okView !=
nullptr) {
constexpr KDCoordinate circleDiameter
bool isMainViewSelected() const
void setFrame(KDRect frame)
void drawGridLines(KDContext *ctx, KDRect rect, Axis axis, float step, KDColor color) const
const SettingsMessageTree model
KDColor s_dotWorkingBuffer[dotDiameter *dotDiameter]
constexpr KDCoordinate width() const
static KDSize stringSize(const char *text, FontSize size=FontSize::Large)
void setBannerView(View *bannerView)
virtual float yGridUnit()
void markRectAsDirty(KDRect rect)
void drawSegment(KDContext *ctx, KDRect rect, Axis axis, float coordinate, float lowerBound, float upperBound, KDColor color, KDCoordinate thickness=1) const
void blendRectWithMask(KDRect rect, KDColor color, const uint8_t *mask, KDColor *workingBuffer)
void drawGrid(KDContext *ctx, KDRect rect) const
void drawAxes(KDContext *ctx, KDRect rect, Axis axis) const
void setOkView(View *okView)
size_t strlcpy(char *dst, const char *src, size_t len)
void drawCurve(KDContext *ctx, KDRect rect, EvaluateModelWithParameter evaluation, void *model, void *context, KDColor color, bool colorUnderCurve=false, float colorLowerBound=0.0f, float colorUpperBound=0.0f, bool continuously=false) const
static constexpr KDCoordinate k_labelMargin
void drawLine(KDContext *ctx, KDRect rect, Axis axis, float coordinate, KDColor color, KDCoordinate thickness=1) const
virtual float xGridUnit()=0
static constexpr int ShortNumberOfSignificantDigits
KDPoint blendString(const char *text, KDPoint p, KDText::FontSize size, KDColor textColor=KDColorBlack)
CurveViewCursor * m_curveViewCursor
const uint8_t stampMask[stampSize+1][stampSize+1]
virtual float samplingRatio() const
KDCoordinate right() const
constexpr KDCoordinate stampSize
size_t strlen(const char *s)
void drawLabels(KDContext *ctx, KDRect rect, Axis axis, bool shiftOrigin) const
KDColor s_oversizeDotWorkingBuffer[oversizeDotDiameter *oversizeDotDiameter]
static constexpr KDCoordinate k_okMargin
static constexpr int k_externRectMargin
KDCoordinate left() const
constexpr KDColor KDColorBlack
void setCurveViewRange(CurveViewRange *curveViewRange)
virtual uint32_t rangeChecksum()
constexpr KDCoordinate dotDiameter
void drawHistogram(KDContext *ctx, KDRect rect, EvaluateModelWithParameter evaluation, void *model, void *context, float firstBarAbscissa, float barWidth, bool fillBar, KDColor defaultColor, KDColor highlightColor, float highlightLowerBound=INFINITY, float highlightUpperBound=-INFINITY) const
virtual KDSize minimalSizeForOptimalDisplay() const
constexpr KDRect KDRectZero
void fillRect(KDRect rect, KDColor color)
void setCursorView(View *cursorView)
float floatToPixel(Axis axis, float f) const
void computeLabels(Axis axis)
constexpr KDCoordinate oversizeDotDiameter
KDCoordinate width() const
void selectMainView(bool mainViewSelected)
const uint8_t oversizeDotMask[oversizeDotDiameter][oversizeDotDiameter]
void drawDot(KDContext *ctx, KDRect rect, float x, float y, KDColor color, bool oversize=false) const
const uint8_t dotMask[dotDiameter][dotDiameter]
KDCoordinate height() const
float pixelToFloat(Axis axis, KDCoordinate p) const
bool intersects(const KDRect &other) const
static constexpr KDColor GreyWhite
static constexpr KDCoordinate k_labelGraduationLength
KDCoordinate bottom() const
constexpr KDCoordinate height() const