| 48 | Vector2i MultiGraph::preferred_size_impl(NVGcontext*) const { return Vector2i(180, 80); } |
| 49 | |
| 50 | void MultiGraph::draw(NVGcontext* ctx) { |
| 51 | Widget::draw(ctx); |
| 52 | |
| 53 | NVGpaint bg = nvgBoxGradient(ctx, m_pos.x() + 1, m_pos.y() + 1 + 1.0f, m_size.x() - 2, m_size.y() - 2, 3, 4, Color(120, 32), Color(32, 32)); |
| 54 | |
| 55 | nvgBeginPath(ctx); |
| 56 | nvgRoundedRect(ctx, m_pos.x() + 1, m_pos.y() + 1 + 1.0f, m_size.x() - 2, m_size.y() - 2, 3); |
| 57 | |
| 58 | nvgFillPaint(ctx, bg); |
| 59 | |
| 60 | nvgFill(ctx); |
| 61 | |
| 62 | if (mValues.size() >= 2) { |
| 63 | nvgSave(ctx); |
| 64 | |
| 65 | // Additive blending |
| 66 | nvgGlobalCompositeBlendFuncSeparate( |
| 67 | ctx, NVGblendFactor::NVG_SRC_ALPHA, NVGblendFactor::NVG_ONE, NVGblendFactor::NVG_ZERO, NVGblendFactor::NVG_ONE |
| 68 | ); |
| 69 | |
| 70 | size_t nBins = mValues.size() / mNChannels; |
| 71 | |
| 72 | for (size_t i = 0; i < (size_t)mNChannels; i++) { |
| 73 | nvgBeginPath(ctx); |
| 74 | nvgMoveTo(ctx, m_pos.x(), m_pos.y() + m_size.y()); |
| 75 | |
| 76 | for (size_t j = 0; j < (size_t)nBins; j++) { |
| 77 | float value = mValues[j + i * nBins]; |
| 78 | float vx = m_pos.x() + 2 + j * (m_size.x() - 4) / (float)(nBins - 1); |
| 79 | float vy = m_pos.y() + (1 - value) * m_size.y(); |
| 80 | nvgLineTo(ctx, vx, vy); |
| 81 | } |
| 82 | |
| 83 | auto color = i < mColors.size() ? mColors[i] : mForegroundColor; |
| 84 | nvgLineTo(ctx, m_pos.x() + m_size.x(), m_pos.y() + m_size.y()); |
| 85 | nvgFillColor(ctx, color); |
| 86 | nvgFill(ctx); |
| 87 | } |
| 88 | |
| 89 | nvgRestore(ctx); |
| 90 | |
| 91 | if (mZeroBin > 0) { |
| 92 | nvgBeginPath(ctx); |
| 93 | nvgRect(ctx, m_pos.x() + 1 + mZeroBin * (m_size.x() - 4) / (float)(nBins - 1), m_pos.y() + 15, 4, m_size.y() - 15); |
| 94 | nvgFillColor(ctx, Color(0, 128)); |
| 95 | nvgFill(ctx); |
| 96 | nvgBeginPath(ctx); |
| 97 | nvgRect(ctx, m_pos.x() + 2 + mZeroBin * (m_size.x() - 4) / (float)(nBins - 1), m_pos.y() + 15, 2, m_size.y() - 15); |
| 98 | nvgFillColor(ctx, Color(200, 255)); |
| 99 | nvgFill(ctx); |
| 100 | } |
| 101 | |
| 102 | nvgFontFace(ctx, "sans"); |
| 103 | |
| 104 | nvgFontSize(ctx, 15.0f); |
| 105 | nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); |
| 106 | nvgFillColor(ctx, mTextColor); |
| 107 | drawTextWithShadow(ctx, m_pos.x() + 3, m_pos.y() + 1, formatNumber(mMinimum)); |
nothing calls this directly
no test coverage detected