From f448f18ae4a1b92e2a0476afdc0c7ba665aac541 Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Wed, 3 Dec 2014 04:33:34 +0100 Subject: [PATCH 1/4] Removed code duplication by merging drawRect() and drawRoundedRect(). --- examples/common/imgui/imgui.cpp | 232 +++++++++++--------------------- 1 file changed, 76 insertions(+), 156 deletions(-) diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index b675b3f5..a70549cf 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -969,70 +969,34 @@ struct Imgui } // BG - if (0 == _r) - { - drawRect( (float)xx - , (float)yy - , (float)width - , (float)height - , imguiRGBA(0, 0, 0, 196) - ); - } - else - { - drawRoundedRect( (float)xx - , (float)yy - , (float)width - , (float)height - , (float)_r - , imguiRGBA(0, 0, 0, 196) - ); - } + drawRoundedRect( (float)xx + , (float)yy + , (float)width + , (float)height + , (float)_r + , imguiRGBA(0, 0, 0, 196) + ); // Bar if (isActive(hid) ) { - if (0 == _r) - { - drawRect( (float)hx - , (float)hy - , (float)hw - , (float)hh - , imguiRGBA(255, 196, 0, 196) - ); - } - else - { - drawRoundedRect( (float)hx - , (float)hy - , (float)hw - , (float)hh - , (float)_r - , imguiRGBA(255, 196, 0, 196) - ); - } + drawRoundedRect( (float)hx + , (float)hy + , (float)hw + , (float)hh + , (float)_r + , imguiRGBA(255, 196, 0, 196) + ); } else { - if (0 == _r) - { - drawRect( (float)hx - , (float)hy - , (float)hw - , (float)hh - , isHot(hid) ? imguiRGBA(255, 196, 0, 96) : imguiRGBA(255, 255, 255, 64) - ); - } - else - { - drawRoundedRect( (float)hx - , (float)hy - , (float)hw - , (float)hh - , (float)_r - , isHot(hid) ? imguiRGBA(255, 196, 0, 96) : imguiRGBA(255, 255, 255, 64) - ); - } + drawRoundedRect( (float)hx + , (float)hy + , (float)hw + , (float)hh + , (float)_r + , isHot(hid) ? imguiRGBA(255, 196, 0, 96) : imguiRGBA(255, 255, 255, 64) + ); } } else @@ -1174,25 +1138,13 @@ struct Imgui const uint32_t rgb0 = _rgb0&0x00ffffff; - if (0 == _r) - { - drawRect( (float)xx - , (float)yy - , (float)width - , (float)height - , rgb0 | imguiRGBA(0, 0, 0, isActive(id) ? 196 : 96) - ); - } - else - { - drawRoundedRect( (float)xx - , (float)yy - , (float)width - , (float)height - , (float)_r - , rgb0 | imguiRGBA(0, 0, 0, isActive(id) ? 196 : 96) - ); - } + drawRoundedRect( (float)xx + , (float)yy + , (float)width + , (float)height + , (float)_r + , rgb0 | imguiRGBA(0, 0, 0, isActive(id) ? 196 : 96) + ); if (enabled) { @@ -1409,25 +1361,13 @@ struct Imgui const bool over = enabled && inRect(xx, yy, width, height); inputLogic(id, over); - if (0 == _r) - { - drawRect( (float)xx - , (float)yy - , (float)width - , (float)height - , isActiveInputField(id)?imguiRGBA(255,196,0,255):imguiRGBA(128,128,128,96) - ); - } - else - { - drawRoundedRect( (float)xx - , (float)yy - , (float)width - , (float)height - , (float)_r - , isActiveInputField(id)?imguiRGBA(255,196,0,255):imguiRGBA(128,128,128,96) - ); - } + drawRoundedRect( (float)xx + , (float)yy + , (float)width + , (float)height + , (float)_r + , isActiveInputField(id)?imguiRGBA(255,196,0,255):imguiRGBA(128,128,128,96) + ); if (isActiveInputField(id) ) { @@ -1519,25 +1459,13 @@ struct Imgui const int32_t tabWidthHalf = width / (tabCount*2); const int32_t textY = yy + _height/2 + int32_t(m_fonts[m_currentFontIdx].m_size)/2 - 2; - if (0 == _r) - { - drawRect( (float)xx - , (float)yy - , (float)width - , (float)_height - , _enabled?imguiRGBA(128,128,128,96):imguiRGBA(128,128,128,64) - ); - } - else - { - drawRoundedRect( (float)xx - , (float)yy - , (float)width - , (float)_height - , (float)_r - , _enabled?imguiRGBA(128,128,128,96):imguiRGBA(128,128,128,64) - ); - } + drawRoundedRect( (float)xx + , (float)yy + , (float)width + , (float)_height + , (float)_r + , _enabled?imguiRGBA(128,128,128,96):imguiRGBA(128,128,128,64) + ); for (uint8_t ii = 0; ii < tabCount; ++ii) { @@ -1560,25 +1488,13 @@ struct Imgui { textColor = enabled?imguiRGBA(0,0,0,255):imguiRGBA(255,255,255,100); - if (0 == _r) - { - drawRect( (float)buttonX - , (float)yy - , (float)tabWidth - , (float)_height - , enabled?imguiRGBA(255,196,0,200):imguiRGBA(128,128,128,32) - ); - } - else - { - drawRoundedRect( (float)buttonX - , (float)yy - , (float)tabWidth - , (float)_height - , (float)_r - , enabled?imguiRGBA(255,196,0,200):imguiRGBA(128,128,128,32) - ); - } + drawRoundedRect( (float)buttonX + , (float)yy + , (float)tabWidth + , (float)_height + , (float)_r + , enabled?imguiRGBA(255,196,0,200):imguiRGBA(128,128,128,32) + ); } else { @@ -1984,13 +1900,12 @@ struct Imgui const bool over = _enabled && inRect(xx, yy, width, height, false); const bool res = buttonLogic(id, over); - drawRoundedRect( (float)xx - , (float)yy - , (float)width - , (float)height - , 0.0f - , isActive(id) ? imguiRGBA(23, 23, 23, 192) : imguiRGBA(0, 0, 0, 222) - ); + drawRect( (float)xx + , (float)yy + , (float)width + , (float)height + , isActive(id) ? imguiRGBA(23, 23, 23, 192) : imguiRGBA(0, 0, 0, 222) + ); drawTriangle( triX , triY @@ -2322,21 +2237,26 @@ struct Imgui } } - void drawRect(float _x, float _y, float w, float h, uint32_t _argb, float _fth = 1.0f) + void drawRect(float _x, float _y, float _w, float _h, uint32_t _argb, float _fth = 1.0f) { float verts[4 * 2] = { - _x + 0.5f, _y + 0.5f, - _x + w - 0.5f, _y + 0.5f, - _x + w - 0.5f, _y + h - 0.5f, - _x + 0.5f, _y + h - 0.5f, + _x + 0.5f, _y + 0.5f, + _x + _w - 0.5f, _y + 0.5f, + _x + _w - 0.5f, _y + _h - 0.5f, + _x + 0.5f, _y + _h - 0.5f, }; drawPolygon(verts, 4, _fth, _argb); } - void drawRoundedRect(float _x, float _y, float w, float h, float r, uint32_t _argb, float _fth = 1.0f) + void drawRoundedRect(float _x, float _y, float _w, float _h, float _r, uint32_t _argb, float _fth = 1.0f) { + if (0.0f == _r) + { + return drawRect(_x, _y, _w, _h, _argb, _fth); + } + const uint32_t num = NUM_CIRCLE_VERTS / 4; const float* cverts = m_circleVerts; float verts[(num + 1) * 4 * 2]; @@ -2344,30 +2264,30 @@ struct Imgui for (uint32_t ii = 0; ii <= num; ++ii) { - *vv++ = _x + w - r + cverts[ii * 2] * r; - *vv++ = _y + h - r + cverts[ii * 2 + 1] * r; + *vv++ = _x + _w - _r + cverts[ii * 2] * _r; + *vv++ = _y + _h - _r + cverts[ii * 2 + 1] * _r; } for (uint32_t ii = num; ii <= num * 2; ++ii) { - *vv++ = _x + r + cverts[ii * 2] * r; - *vv++ = _y + h - r + cverts[ii * 2 + 1] * r; + *vv++ = _x + _r + cverts[ii * 2] * _r; + *vv++ = _y + _h - _r + cverts[ii * 2 + 1] * _r; } for (uint32_t ii = num * 2; ii <= num * 3; ++ii) { - *vv++ = _x + r + cverts[ii * 2] * r; - *vv++ = _y + r + cverts[ii * 2 + 1] * r; + *vv++ = _x + _r + cverts[ii * 2] * _r; + *vv++ = _y + _r + cverts[ii * 2 + 1] * _r; } for (uint32_t ii = num * 3; ii < num * 4; ++ii) { - *vv++ = _x + w - r + cverts[ii * 2] * r; - *vv++ = _y + r + cverts[ii * 2 + 1] * r; + *vv++ = _x + _w - _r + cverts[ii * 2] * _r; + *vv++ = _y + _r + cverts[ii * 2 + 1] * _r; } - *vv++ = _x + w - r + cverts[0] * r; - *vv++ = _y + r + cverts[1] * r; + *vv++ = _x + _w - _r + cverts[0] * _r; + *vv++ = _y + _r + cverts[1] * _r; drawPolygon(verts, (num + 1) * 4, _fth, _argb); } From 815312466ca757e23d0d6036bba21f795a223cb1 Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Wed, 3 Dec 2014 22:23:00 +0100 Subject: [PATCH 2/4] Draging scroll bars with mouse now behaves more properly. --- examples/common/imgui/imgui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index a70549cf..f10ec503 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -959,7 +959,10 @@ struct Imgui { const int32_t diff = height - sh; - const int32_t val = *area.m_scrollVal - (m_my - m_dragY); + const int32_t drag = m_my - m_dragY; + const float dragFactor = float(sh)/float(height); + + const int32_t val = *area.m_scrollVal - int32_t(drag*dragFactor); const int32_t min = (diff < 0) ? diff : *area.m_scrollVal; const int32_t max = 0; *area.m_scrollVal = IMGUI_CLAMP(val, min, max); From a9a28951326920ac8728a06c9d9aeb437ab57903 Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Sun, 14 Dec 2014 00:05:35 +0100 Subject: [PATCH 3/4] Added 1px to scissor area. --- examples/common/imgui/imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index f10ec503..99560808 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -864,7 +864,7 @@ struct Imgui area.m_scissorX = area.m_contentX; area.m_scissorWidth = area.m_contentWidth; - area.m_scissorY = top; + area.m_scissorY = top - 1; area.m_scissorHeight = bottom - top; area.m_scissorEnabled = true; From 6ad5c8eb2ca71803459faaa17d8f7f7863e3f6d5 Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Sun, 14 Dec 2014 02:16:06 +0100 Subject: [PATCH 4/4] Preventing mouse scroll multiple areas at once and scroll bar scissor problem fixed. --- examples/common/imgui/imgui.cpp | 46 +++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index 99560808..20b847dc 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -879,6 +879,7 @@ struct Imgui , area.m_scissorHeight , false ); + area.m_didScroll = false; parentArea.m_widgetY += (_height + DEFAULT_SPACING); @@ -915,8 +916,12 @@ struct Imgui const int32_t stop = area.m_contentY + (*area.m_scrollVal); const int32_t sh = IMGUI_MAX(1, sbot - stop); // The scrollable area height. + const uint32_t hid = area.m_scrollId; + const float barHeight = (float)height / (float)sh; + const bool hasScrollBar = (barHeight < 1.0f); + // Handle mouse scrolling. - if (area.m_inside && !anyActive() ) + if (area.m_inside && !area.m_didScroll && !anyActive() ) { if (m_scroll) { @@ -925,17 +930,32 @@ struct Imgui const int32_t val = *area.m_scrollVal + 20*m_scroll; const int32_t min = (diff < 0) ? diff : *area.m_scrollVal; const int32_t max = 0; - *area.m_scrollVal = IMGUI_CLAMP(val, min, max); + const int32_t newVal = IMGUI_CLAMP(val, min, max); + *area.m_scrollVal = newVal; + + if (hasScrollBar) + { + area.m_didScroll = true; + } } } - const uint32_t hid = area.m_scrollId; - const float barHeight = (float)height / (float)sh; + area.m_inside = false; + + int32_t* scroll = area.m_scrollVal; + + // This must be called here before drawing scroll bars + // so that scissor of parrent area applies. + m_areaId.pop(); + + // Propagate 'didScroll' to parrent area to avoid scrolling multiple areas at once. + Area& parentArea = getCurrentArea(); + parentArea.m_didScroll = (parentArea.m_didScroll || area.m_didScroll); // Draw and handle scroll click. - if (barHeight < 1.0f) + if (hasScrollBar) { - const float barY = bx::fsaturate( (float)(-(*area.m_scrollVal) ) / (float)sh); + const float barY = bx::fsaturate( (float)(-(*scroll) ) / (float)sh); // Handle scroll bar logic. const int32_t hx = xx; @@ -962,10 +982,10 @@ struct Imgui const int32_t drag = m_my - m_dragY; const float dragFactor = float(sh)/float(height); - const int32_t val = *area.m_scrollVal - int32_t(drag*dragFactor); - const int32_t min = (diff < 0) ? diff : *area.m_scrollVal; + const int32_t val = *scroll - int32_t(drag*dragFactor); + const int32_t min = (diff < 0) ? diff : *scroll; const int32_t max = 0; - *area.m_scrollVal = IMGUI_CLAMP(val, min, max); + *scroll = IMGUI_CLAMP(val, min, max); m_dragY = m_my; } @@ -1012,10 +1032,6 @@ struct Imgui } nvgResetScissor(m_nvg); - - area.m_inside = false; - - m_areaId.previous(); } bool beginArea(const char* _name, int32_t _x, int32_t _y, int32_t _width, int32_t _height, bool _enabled, int32_t _r) @@ -1051,6 +1067,7 @@ struct Imgui area.m_scrollVal = &s_zeroScroll; area.m_scrollId = scrollId; area.m_inside = inRect(area.m_scissorX, area.m_scissorY, area.m_scissorWidth, area.m_scissorHeight, false); + area.m_didScroll = false; if (_enabled) { @@ -2870,6 +2887,7 @@ struct Imgui int32_t* m_scrollVal; uint32_t m_scrollId; bool m_inside; + bool m_didScroll; bool m_scissorEnabled; }; @@ -2917,7 +2935,7 @@ struct Imgui m_ids[++m_current] = ++m_idGen; } - void previous() + void pop() { m_current = m_current > 0 ? m_current-1 : 0; }