| @@ -72,14 +72,34 @@ public: | |||||
| */ | */ | ||||
| ~CairoImage() override; | ~CairoImage() override; | ||||
| /** | |||||
| Load image data from memory. | |||||
| @note @a rawData must remain valid for the lifetime of this Image. | |||||
| */ | |||||
| void loadFromMemory(const char* rawData, | |||||
| const Size<uint>& size, | |||||
| ImageFormat format = kImageFormatBGRA) noexcept override; | |||||
| /** | /** | ||||
| Draw this image at position @a pos using the graphics context @a context. | Draw this image at position @a pos using the graphics context @a context. | ||||
| */ | */ | ||||
| void drawAt(const GraphicsContext& context, const Point<int>& pos) override; | void drawAt(const GraphicsContext& context, const Point<int>& pos) override; | ||||
| /** | |||||
| TODO document this. | |||||
| */ | |||||
| CairoImage& operator=(const CairoImage& image) noexcept; | |||||
| // FIXME this should not be needed | // FIXME this should not be needed | ||||
| inline void loadFromMemory(const char* rawData, uint w, uint h, ImageFormat format) | |||||
| { loadFromMemory(rawData, Size<uint>(w, h), format); }; | |||||
| inline void drawAt(const GraphicsContext& context, int x, int y) | inline void drawAt(const GraphicsContext& context, int x, int y) | ||||
| { drawAt(context, Point<int>(x, y)); }; | { drawAt(context, Point<int>(x, y)); }; | ||||
| private: | |||||
| cairo_surface_t* surface; | |||||
| uchar* surfacedata; | |||||
| int* datarefcount; | |||||
| }; | }; | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -24,6 +24,7 @@ START_NAMESPACE_DGL | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| enum ImageFormat { | enum ImageFormat { | ||||
| kImageFormatNull, | |||||
| kImageFormatBGR, | kImageFormatBGR, | ||||
| kImageFormatBGRA, | kImageFormatBGRA, | ||||
| kImageFormatRGB, | kImageFormatRGB, | ||||
| @@ -61,6 +61,9 @@ public: | |||||
| { return Window::addIdleCallback(callback, timerFrequencyInMs); } | { return Window::addIdleCallback(callback, timerFrequencyInMs); } | ||||
| bool removeIdleCallback(IdleCallback* callback) { return Window::removeIdleCallback(callback); } | bool removeIdleCallback(IdleCallback* callback) { return Window::removeIdleCallback(callback); } | ||||
| const GraphicsContext& getGraphicsContext() const noexcept { return Window::getGraphicsContext(); } | const GraphicsContext& getGraphicsContext() const noexcept { return Window::getGraphicsContext(); } | ||||
| void setGeometryConstraints(uint minimumWidth, uint minimumHeight, | |||||
| bool keepAspectRatio = false, bool automaticallyScale = false) | |||||
| { Window::setGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, automaticallyScale); } | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(StandaloneWindow) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(StandaloneWindow) | ||||
| }; | }; | ||||
| @@ -92,20 +92,28 @@ static void drawCircle(cairo_t* const handle, | |||||
| const T origy = pos.getY(); | const T origy = pos.getY(); | ||||
| double t, x = size, y = 0.0; | double t, x = size, y = 0.0; | ||||
| // TODO use arc | |||||
| /* | /* | ||||
| glBegin(outline ? GL_LINE_LOOP : GL_POLYGON); | |||||
| cairo_arc(handle, origx, origy, size, sin, cos); | |||||
| */ | |||||
| cairo_move_to(handle, x + origx, y + origy); | |||||
| for (uint i=0; i<numSegments; ++i) | |||||
| for (uint i=1; i<numSegments; ++i) | |||||
| { | { | ||||
| glVertex2d(x + origx, y + origy); | |||||
| cairo_line_to(handle, x + origx, y + origy); | |||||
| t = x; | t = x; | ||||
| x = cos * x - sin * y; | x = cos * x - sin * y; | ||||
| y = sin * t + cos * y; | y = sin * t + cos * y; | ||||
| } | } | ||||
| glEnd(); | |||||
| */ | |||||
| cairo_line_to(handle, x + origx, y + origy); | |||||
| if (outline) | |||||
| cairo_stroke(handle); | |||||
| else | |||||
| cairo_fill(handle); | |||||
| } | } | ||||
| template<typename T> | template<typename T> | ||||
| @@ -158,7 +166,15 @@ static void drawTriangle(cairo_t* const handle, | |||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(pos1 != pos2 && pos1 != pos3,); | DISTRHO_SAFE_ASSERT_RETURN(pos1 != pos2 && pos1 != pos3,); | ||||
| // TODO | |||||
| cairo_move_to(handle, pos1.getX(), pos1.getY()); | |||||
| cairo_line_to(handle, pos2.getX(), pos2.getY()); | |||||
| cairo_line_to(handle, pos3.getX(), pos3.getY()); | |||||
| cairo_line_to(handle, pos1.getX(), pos1.getY()); | |||||
| if (outline) | |||||
| cairo_stroke(handle); | |||||
| else | |||||
| cairo_fill(handle); | |||||
| } | } | ||||
| template<typename T> | template<typename T> | ||||
| @@ -206,7 +222,12 @@ template class Triangle<ushort>; | |||||
| template<typename T> | template<typename T> | ||||
| static void drawRectangle(cairo_t* const handle, const Rectangle<T>& rect, const bool outline) | static void drawRectangle(cairo_t* const handle, const Rectangle<T>& rect, const bool outline) | ||||
| { | { | ||||
| // TODO | |||||
| cairo_rectangle(handle, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); | |||||
| if (outline) | |||||
| cairo_stroke(handle); | |||||
| else | |||||
| cairo_fill(handle); | |||||
| } | } | ||||
| template<typename T> | template<typename T> | ||||
| @@ -253,24 +274,152 @@ template class Rectangle<ushort>; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // CairoImage | // CairoImage | ||||
| static cairo_format_t asCairoImageFormat(const ImageFormat format) | |||||
| { | |||||
| switch (format) | |||||
| { | |||||
| case kImageFormatNull: | |||||
| break; | |||||
| case kImageFormatBGR: | |||||
| case kImageFormatRGB: | |||||
| return CAIRO_FORMAT_RGB24; | |||||
| case kImageFormatBGRA: | |||||
| case kImageFormatRGBA: | |||||
| return CAIRO_FORMAT_ARGB32; | |||||
| } | |||||
| return CAIRO_FORMAT_INVALID; | |||||
| } | |||||
| CairoImage::CairoImage() | CairoImage::CairoImage() | ||||
| : ImageBase() {} | |||||
| : ImageBase(), | |||||
| surface(nullptr), | |||||
| surfacedata(nullptr), | |||||
| datarefcount(nullptr) {} | |||||
| CairoImage::CairoImage(const char* const rawData, const uint width, const uint height, const ImageFormat format) | CairoImage::CairoImage(const char* const rawData, const uint width, const uint height, const ImageFormat format) | ||||
| : ImageBase(rawData, width, height, format) {} | |||||
| : ImageBase(rawData, width, height, format), | |||||
| surface(nullptr), | |||||
| surfacedata(nullptr), | |||||
| datarefcount(nullptr) | |||||
| { | |||||
| loadFromMemory(rawData, width, height, format); | |||||
| } | |||||
| CairoImage::CairoImage(const char* const rawData, const Size<uint>& size, const ImageFormat format) | CairoImage::CairoImage(const char* const rawData, const Size<uint>& size, const ImageFormat format) | ||||
| : ImageBase(rawData, size, format) {} | |||||
| : ImageBase(rawData, size, format), | |||||
| surface(nullptr), | |||||
| surfacedata(nullptr), | |||||
| datarefcount(nullptr) | |||||
| { | |||||
| loadFromMemory(rawData, size, format); | |||||
| } | |||||
| CairoImage::CairoImage(const CairoImage& image) | CairoImage::CairoImage(const CairoImage& image) | ||||
| : ImageBase(image.rawData, image.size, image.format) {} | |||||
| : ImageBase(image.rawData, image.size, image.format), | |||||
| surface(cairo_surface_reference(image.surface)), | |||||
| surfacedata(image.surfacedata), | |||||
| datarefcount(image.datarefcount) | |||||
| { | |||||
| if (datarefcount != nullptr) | |||||
| ++(*datarefcount); | |||||
| } | |||||
| CairoImage::~CairoImage() | CairoImage::~CairoImage() | ||||
| { | { | ||||
| cairo_surface_destroy(surface); | |||||
| if (datarefcount != nullptr && --(*datarefcount) == 0) | |||||
| { | |||||
| std::free(surfacedata); | |||||
| std::free(datarefcount); | |||||
| } | |||||
| } | } | ||||
| void CairoImage::drawAt(const GraphicsContext&, const Point<int>&) | |||||
| void CairoImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept | |||||
| { | { | ||||
| const cairo_format_t cairoformat = asCairoImageFormat(fmt); | |||||
| const uint width = s.getWidth(); | |||||
| const uint height = s.getHeight(); | |||||
| const int stride = cairo_format_stride_for_width(cairoformat, width); | |||||
| uchar* const newdata = (uchar*)std::malloc(width * height * stride * 4); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newdata != nullptr,); | |||||
| cairo_surface_t* const newsurface = cairo_image_surface_create_for_data(newdata, cairoformat, width, height, stride); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newsurface != nullptr,); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(s.getWidth() == cairo_image_surface_get_width(newsurface),); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(s.getHeight() == cairo_image_surface_get_height(newsurface),); | |||||
| cairo_surface_destroy(surface); | |||||
| if (datarefcount != nullptr && --(*datarefcount) == 0) | |||||
| std::free(surfacedata); | |||||
| else | |||||
| datarefcount = (int*)malloc(sizeof(*datarefcount)); | |||||
| surface = newsurface; | |||||
| surfacedata = newdata; | |||||
| *datarefcount = 1; | |||||
| switch (fmt) | |||||
| { | |||||
| case kImageFormatNull: | |||||
| break; | |||||
| case kImageFormatBGR: | |||||
| // BGR8 to CAIRO_FORMAT_RGB24 | |||||
| for (uint h = 0; h < height; ++h) | |||||
| { | |||||
| for (uint w = 0; w < width; ++w) | |||||
| { | |||||
| newdata[h*width*4+w*4+0] = rdata[h*width*3+w*3+0]; | |||||
| newdata[h*width*4+w*4+1] = rdata[h*width*3+w*3+1]; | |||||
| newdata[h*width*4+w*4+2] = rdata[h*width*3+w*3+2]; | |||||
| newdata[h*width*4+w*4+3] = 0; | |||||
| } | |||||
| } | |||||
| break; | |||||
| case kImageFormatBGRA: | |||||
| // RGB8 to CAIRO_FORMAT_ARGB32 | |||||
| // TODO | |||||
| break; | |||||
| case kImageFormatRGB: | |||||
| // RGB8 to CAIRO_FORMAT_RGB24 | |||||
| // TODO | |||||
| break; | |||||
| case kImageFormatRGBA: | |||||
| // RGBA8 to CAIRO_FORMAT_ARGB32 | |||||
| // TODO | |||||
| break; | |||||
| } | |||||
| ImageBase::loadFromMemory(rdata, s, fmt); | |||||
| } | |||||
| void CairoImage::drawAt(const GraphicsContext& context, const Point<int>& pos) | |||||
| { | |||||
| if (surface == nullptr) | |||||
| return; | |||||
| cairo_t* const handle = ((const CairoGraphicsContext&)context).handle; | |||||
| cairo_set_source_surface(handle, surface, pos.getX(), pos.getY()); | |||||
| cairo_paint(handle); | |||||
| } | |||||
| CairoImage& CairoImage::operator=(const CairoImage& image) noexcept | |||||
| { | |||||
| cairo_surface_t* newsurface = cairo_surface_reference(image.surface); | |||||
| cairo_surface_destroy(surface); | |||||
| surface = newsurface; | |||||
| rawData = image.rawData; | |||||
| size = image.size; | |||||
| format = image.format; | |||||
| surfacedata = image.surfacedata; | |||||
| datarefcount = image.datarefcount; | |||||
| if (datarefcount != nullptr) | |||||
| ++(*datarefcount); | |||||
| return *this; | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -318,21 +467,47 @@ template class ImageBaseAboutWindow<CairoImage>; | |||||
| void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) | void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) | ||||
| { | { | ||||
| /* | |||||
| if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible) | |||||
| return; | |||||
| */ | |||||
| cairo_t* const handle = static_cast<const CairoGraphicsContext&>(self->getGraphicsContext()).handle; | |||||
| bool needsResetClip = false; | |||||
| cairo_t* cr = static_cast<const CairoGraphicsContext&>(self->getGraphicsContext()).handle; | |||||
| cairo_matrix_t matrix; | cairo_matrix_t matrix; | ||||
| cairo_get_matrix(cr, &matrix); | |||||
| cairo_translate(cr, absolutePos.getX(), absolutePos.getY()); | |||||
| // TODO: autoScaling and cropping | |||||
| cairo_get_matrix(handle, &matrix); | |||||
| if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size<uint>(width, height))) | |||||
| { | |||||
| // full viewport size | |||||
| cairo_translate(handle, 0, 0); | |||||
| } | |||||
| else if (needsViewportScaling) | |||||
| { | |||||
| // limit viewport to widget bounds | |||||
| // NOTE only used for nanovg for now, which is not relevant here | |||||
| cairo_translate(handle, 0, 0); | |||||
| } | |||||
| else | |||||
| { | |||||
| // set viewport pos | |||||
| cairo_translate(handle, absolutePos.getX(), absolutePos.getY()); | |||||
| // then cut the outer bounds | |||||
| cairo_rectangle(handle, | |||||
| 0, | |||||
| 0, | |||||
| std::round(self->getWidth() * autoScaleFactor), | |||||
| std::round(self->getHeight() * autoScaleFactor)); | |||||
| cairo_clip(handle); | |||||
| needsResetClip = true; | |||||
| } | |||||
| // display widget | // display widget | ||||
| self->onDisplay(); | self->onDisplay(); | ||||
| cairo_set_matrix(cr, &matrix); | |||||
| if (needsResetClip) | |||||
| cairo_reset_clip(handle); | |||||
| cairo_set_matrix(handle, &matrix); | |||||
| selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | ||||
| } | } | ||||
| @@ -347,6 +522,7 @@ void TopLevelWidget::PrivateData::display() | |||||
| const double autoScaleFactor = window.pData->autoScaleFactor; | const double autoScaleFactor = window.pData->autoScaleFactor; | ||||
| // FIXME anything needed here? | |||||
| #if 0 | #if 0 | ||||
| // full viewport size | // full viewport size | ||||
| if (window.pData->autoScaling) | if (window.pData->autoScaling) | ||||
| @@ -24,7 +24,7 @@ START_NAMESPACE_DGL | |||||
| ImageBase::ImageBase() | ImageBase::ImageBase() | ||||
| : rawData(nullptr), | : rawData(nullptr), | ||||
| size(0, 0), | size(0, 0), | ||||
| format(kImageFormatBGRA) {} | |||||
| format(kImageFormatNull) {} | |||||
| ImageBase::ImageBase(const char* const rdata, const uint width, const uint height, const ImageFormat fmt) | ImageBase::ImageBase(const char* const rdata, const uint width, const uint height, const ImageFormat fmt) | ||||
| : rawData(rdata), | : rawData(rdata), | ||||
| @@ -264,11 +264,14 @@ template class Rectangle<short>; | |||||
| template class Rectangle<ushort>; | template class Rectangle<ushort>; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // OpenGLImage | |||||
| static GLenum asOpenGLImageFormat(const ImageFormat format) | static GLenum asOpenGLImageFormat(const ImageFormat format) | ||||
| { | { | ||||
| switch (format) | switch (format) | ||||
| { | { | ||||
| case kImageFormatNull: | |||||
| break; | |||||
| case kImageFormatBGR: | case kImageFormatBGR: | ||||
| return GL_BGR; | return GL_BGR; | ||||
| case kImageFormatBGRA: | case kImageFormatBGRA: | ||||
| @@ -279,7 +282,7 @@ static GLenum asOpenGLImageFormat(const ImageFormat format) | |||||
| return GL_RGBA; | return GL_RGBA; | ||||
| } | } | ||||
| return GL_BGRA; | |||||
| return 0x0; | |||||
| } | } | ||||
| static void setupOpenGLImage(const OpenGLImage& image, GLuint textureId) | static void setupOpenGLImage(const OpenGLImage& image, GLuint textureId) | ||||
| @@ -353,8 +356,8 @@ OpenGLImage::~OpenGLImage() | |||||
| void OpenGLImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept | void OpenGLImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept | ||||
| { | { | ||||
| ImageBase::loadFromMemory(rdata, s, fmt); | |||||
| setupCalled = false; | setupCalled = false; | ||||
| ImageBase::loadFromMemory(rdata, s, fmt); | |||||
| } | } | ||||
| void OpenGLImage::drawAt(const GraphicsContext&, const Point<int>& pos) | void OpenGLImage::drawAt(const GraphicsContext&, const Point<int>& pos) | ||||
| @@ -456,7 +459,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // only set viewport pos | |||||
| // set viewport pos | |||||
| glViewport(absolutePos.getX() * autoScaleFactor, | glViewport(absolutePos.getX() * autoScaleFactor, | ||||
| -std::round((height * autoScaleFactor - height) + (absolutePos.getY() * autoScaleFactor)), | -std::round((height * autoScaleFactor - height) + (absolutePos.getY() * autoScaleFactor)), | ||||
| std::round(width * autoScaleFactor), | std::round(width * autoScaleFactor), | ||||
| @@ -476,10 +479,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||||
| self->onDisplay(); | self->onDisplay(); | ||||
| if (needsDisableScissor) | if (needsDisableScissor) | ||||
| { | |||||
| glDisable(GL_SCISSOR_TEST); | glDisable(GL_SCISSOR_TEST); | ||||
| needsDisableScissor = false; | |||||
| } | |||||
| selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | ||||
| } | } | ||||
| @@ -26,6 +26,7 @@ SubWidget::PrivateData::PrivateData(SubWidget* const s, Widget* const pw) | |||||
| selfw((Widget*)s), | selfw((Widget*)s), | ||||
| parentWidget(pw), | parentWidget(pw), | ||||
| absolutePos(), | absolutePos(), | ||||
| needsFullViewportForDrawing(false), | |||||
| needsViewportScaling(false) | needsViewportScaling(false) | ||||
| { | { | ||||
| parentWidget->pData->subWidgets.push_back(self); | parentWidget->pData->subWidgets.push_back(self); | ||||
| @@ -67,17 +67,19 @@ public: | |||||
| curPage(0), | curPage(0), | ||||
| curHover(-1) | curHover(-1) | ||||
| { | { | ||||
| #ifdef DGL_OPENGL | |||||
| // for text | |||||
| nvg.loadSharedResources(); | |||||
| #endif | |||||
| using namespace DemoArtwork; | using namespace DemoArtwork; | ||||
| img1.loadFromMemory(ico1Data, ico1Width, ico1Height, kImageFormatBGR); | img1.loadFromMemory(ico1Data, ico1Width, ico1Height, kImageFormatBGR); | ||||
| img2.loadFromMemory(ico2Data, ico2Width, ico2Height, kImageFormatBGR); | img2.loadFromMemory(ico2Data, ico2Width, ico2Height, kImageFormatBGR); | ||||
| img3.loadFromMemory(ico3Data, ico3Width, ico2Height, kImageFormatBGR); | img3.loadFromMemory(ico3Data, ico3Width, ico2Height, kImageFormatBGR); | ||||
| img4.loadFromMemory(ico4Data, ico4Width, ico4Height, kImageFormatBGR); | img4.loadFromMemory(ico4Data, ico4Width, ico4Height, kImageFormatBGR); | ||||
| #ifdef DGL_OPENGL | |||||
| img5.loadFromMemory(ico5Data, ico5Width, ico5Height, kImageFormatBGR); | img5.loadFromMemory(ico5Data, ico5Width, ico5Height, kImageFormatBGR); | ||||
| // for text | |||||
| nvg.loadSharedResources(); | |||||
| #endif | |||||
| } | } | ||||
| protected: | protected: | ||||
| @@ -120,9 +122,10 @@ protected: | |||||
| img2.drawAt(context, pad, pad + 3 + iconSize); | img2.drawAt(context, pad, pad + 3 + iconSize); | ||||
| img3.drawAt(context, pad, pad + 6 + iconSize*2); | img3.drawAt(context, pad, pad + 6 + iconSize*2); | ||||
| img4.drawAt(context, pad, pad + 9 + iconSize*3); | img4.drawAt(context, pad, pad + 9 + iconSize*3); | ||||
| img5.drawAt(context, pad, pad + 12 + iconSize*4); | |||||
| #ifdef DGL_OPENGL | #ifdef DGL_OPENGL | ||||
| img5.drawAt(context, pad, pad + 12 + iconSize*4); | |||||
| // draw some text | // draw some text | ||||
| nvg.beginFrame(this); | nvg.beginFrame(this); | ||||
| @@ -267,10 +270,6 @@ public: | |||||
| #endif | #endif | ||||
| wLeft.setAbsolutePos(2, 2); | wLeft.setAbsolutePos(2, 2); | ||||
| setResizable(true); | |||||
| setSize(600, 500); | |||||
| setTitle("DGL Demo"); | |||||
| curPageChanged(0); | curPageChanged(0); | ||||
| } | } | ||||
| @@ -350,6 +349,7 @@ template <class ExampleWidgetStandaloneWindow> | |||||
| void createAndShowExampleWidgetStandaloneWindow(Application& app) | void createAndShowExampleWidgetStandaloneWindow(Application& app) | ||||
| { | { | ||||
| ExampleWidgetStandaloneWindow swin(app); | ExampleWidgetStandaloneWindow swin(app); | ||||
| swin.setResizable(true); | |||||
| swin.setSize(600, 500); | swin.setSize(600, 500); | ||||
| swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); | swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); | ||||
| swin.show(); | swin.show(); | ||||
| @@ -89,7 +89,7 @@ protected: | |||||
| else | else | ||||
| Color(0.3f, 0.5f, 0.8f).setFor(context); | Color(0.3f, 0.5f, 0.8f).setFor(context); | ||||
| r.draw(); | |||||
| r.draw(context); | |||||
| // 2nd | // 2nd | ||||
| r.setY(3 + height/3); | r.setY(3 + height/3); | ||||
| @@ -99,7 +99,7 @@ protected: | |||||
| else | else | ||||
| Color(0.3f, 0.5f, 0.8f).setFor(context); | Color(0.3f, 0.5f, 0.8f).setFor(context); | ||||
| r.draw(); | |||||
| r.draw(context); | |||||
| // 3rd | // 3rd | ||||
| r.setY(3 + height*2/3); | r.setY(3 + height*2/3); | ||||
| @@ -109,7 +109,7 @@ protected: | |||||
| else | else | ||||
| Color(0.3f, 0.5f, 0.8f).setFor(context); | Color(0.3f, 0.5f, 0.8f).setFor(context); | ||||
| r.draw(); | |||||
| r.draw(context); | |||||
| } | } | ||||
| } | } | ||||