bool UIPanel::checkbox(const char * str, bool checked, bool enabled) { _state.widgetId++; uint32_t id = _state.widgetId; float x = _state.widgetX; float y = _state.widgetY; // + BUTTON_HEIGHT; float w = _state.widgetW; float h = BUTTON_HEIGHT; _state.widgetY += BUTTON_HEIGHT + DEFAULT_SPACING; bool over = enabled && inRect(_state, x, y, w, h); bool result = buttonLogic(_state, id, over); const float cx = x + BUTTON_HEIGHT * 0.5f - CHECK_SIZE * 0.5f; const float cy = y + BUTTON_HEIGHT * 0.5f - CHECK_SIZE * 0.5f; addRoundedRectangle(_faceMesh->geometry, Vector2(cx - 3.0f, cy - 3.0f), Vector2(CHECK_SIZE + 6.0f, CHECK_SIZE + 6.0f), 4.0f, Color(0.5, 0.5, 0.5, isActive(_state, id) ? 0.75 : 0.35)); if (checked) { if (enabled) addRoundedRectangle(_faceMesh->geometry, Vector2(cx, cy), Vector2(CHECK_SIZE, CHECK_SIZE), CHECK_SIZE * 0.5f - 1.0f, Color(1, 1, 1, isActive(_state, id) ? 1 : 0.8)); else addRoundedRectangle(_faceMesh->geometry, Vector2(cx, cy), Vector2(CHECK_SIZE, CHECK_SIZE), CHECK_SIZE * 0.5f - 1.0f, Color(0.5, 0.5, 0.5, 0.8)); } if (enabled) font->buildTextGeometry(str, Vector2(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT * 0.5f + TEXT_HEIGHT * 0.5f), _fontMesh->geometry, isHot(_state, id) ? Color(1, 0.75, 0, 1) : Color(1, 1, 1, 0.8)); else font->buildTextGeometry(str, Vector2(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT * 0.5f + TEXT_HEIGHT * 0.5f), _fontMesh->geometry, Color(0.5, 0.5, 0.5, 0.8)); return result; }
void UIPanel::end() { _state.widgetY -= SCROLL_AREA_PADDING; float height = size.y - SCROLL_AREA_PADDING * 2; float diff = _state.widgetY + _state.scroll - height; float factor = height / (_state.widgetY + _state.scroll); if (factor < 1.0f) { float x = size.x - SCROLL_AREA_PADDING - SCROLL_BAR_WIDTH * 0.5f; float h = factor * height; float y = SCROLL_AREA_PADDING + (height - h) * (_state.scroll / diff); addRoundedRectangle(_faceMesh->geometry, Vector2(x, y), Vector2(SCROLL_BAR_WIDTH, h), SCROLL_BAR_WIDTH * 0.5f, Color(1, 1, 1, 0.25)); // Update scroll if (_state.insidePanel) { _state.scroll -= _state.mouseScroll * 20.0f; _state.scroll = max(0.0f, min(diff, _state.scroll)); } } clearInput(_state); }
bool UIPanel::button(const char * str, bool enabled) { _state.widgetId++; uint32_t id = _state.widgetId; const float x = _state.widgetX; const float y = _state.widgetY; const float w = _state.widgetW; const float h = BUTTON_HEIGHT; _state.widgetY += BUTTON_HEIGHT + DEFAULT_SPACING; bool over = enabled && inRect(_state, x, y, w, h); bool result = buttonLogic(_state, id, over); addRoundedRectangle(_faceMesh->geometry, Vector2(x, y), Vector2(w, h), BUTTON_HEIGHT * 0.5f - 1.0f, Color(0.5, 0.5, 0.5, isActive(_state, id) ? 0.75 : 0.35)); const float textLength = font->textLength(str); const float textX = x + BUTTON_HEIGHT * 0.5f + (w - BUTTON_HEIGHT) * 0.5f - textLength * 0.5f; if (enabled) font->buildTextGeometry(str, Vector2(textX, y + BUTTON_HEIGHT * 0.5f + TEXT_HEIGHT * 0.5f), _fontMesh->geometry, isHot(_state, id) ? Color(1, 0.75, 0, 1) : Color(1, 1, 1, 0.8)); else font->buildTextGeometry(str, Vector2(textX, y + BUTTON_HEIGHT * 0.5f + TEXT_HEIGHT * 0.5f), _fontMesh->geometry, isHot(_state, id) ? Color(1, 0.75, 0, 1) : Color(0.5, 0.5, 0.5, 0.8)); return result; }
bool UIPanel::begin(Vector2 const& mousePos, bool mouseDown, float mouseScroll) { _faceMesh->geometry->clear(); _fontMesh->geometry->clear(); // Update input with panel normalized mouse coords updateInput(_state, mousePos - Vector2(position.x, position.y), mouseDown, mouseScroll); _state.hot = _state.toBeHot; _state.toBeHot = 0; _state.wentActive = false; _state.isActive = false; _state.isHot = false; _state.insidePanel = inRect(_state, position.x, position.y, size.x, size.y, false); _state.widgetX = SCROLL_AREA_PADDING; _state.widgetY = SCROLL_AREA_PADDING - _state.scroll; _state.widgetW = size.x - SCROLL_AREA_PADDING * 3; _state.widgetId = 1; addRoundedRectangle(_faceMesh->geometry, Vector2(0, 0), size, 8.0f, Color(0, 0, 0, 0.75)); return _state.insidePanel; }
void BluetoothDeviceListItem::paintButton(Graphics &g, bool isMouseOverButton, bool isButtonDown) { auto bounds = getLocalBounds(); auto inset = bounds.reduced(6, 4); auto w = bounds.getWidth(), h = bounds.getHeight(); auto iconBounds = Rectangle<float>(w - h, h/5.0, h*0.6, h*0.6); auto listOutline = Path(); listOutline.addRoundedRectangle(inset.toFloat(), 10.0f); g.setColour(findColour(ListBox::ColourIds::backgroundColourId)); g.fillPath(listOutline); if (device->connected) { icons->checkIcon->setSize(h, h); icons->checkIcon->drawWithin(g, iconBounds, RectanglePlacement::fillDestination, 1.0f); } // icons->arrowIcon->setSize(h, h); // icons->arrowIcon->drawWithin(g, Rectangle<float>(w - (h/8), contentHeight + 8, contentHeight, contentHeight), // RectanglePlacement::fillDestination, 1.0f); g.setFont(Font(getLookAndFeel().getTypefaceForFont(Font()))); g.setFont(h * 0.5); g.setColour(findColour(ListBox::ColourIds::textColourId)); g.drawText(getName(), inset.reduced(h * 0.2, 0), Justification::centredLeft, true); }
bool UIPanel::slider(const char * text, float * value, float valueMin, float valueMax, float valueInc, bool enabled) { _state.widgetId++; uint32_t id = _state.widgetId; const float x = _state.widgetX; const float y = _state.widgetY; const float w = _state.widgetW; const float h = SLIDER_HEIGHT; _state.widgetY += SLIDER_HEIGHT + DEFAULT_SPACING; addRoundedRectangle(_faceMesh->geometry, Vector2(x, y), Vector2(w, h), 4.0f, Color(0, 0, 0, 0.5)); const float range = w - SLIDER_MARKER_WIDTH; float u = (*value - valueMin) / (valueMax - valueMin); if (u < 0.0f) u = 0.0f; if (u > 1.0f) u = 1.0f; float m = u * range; bool over = enabled && inRect(_state, x + m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT); bool result = buttonLogic(_state, id, over); bool valueChanged = false; if (isActive(_state, id)) { if (_state.wentActive) { _state.mouseDrag.x = _state.mousePos.x; _state.dragOrigin = u; } if (_state.mouseDrag.x != _state.mousePos.x) { u = _state.dragOrigin + (float)(_state.mousePos.x - _state.mouseDrag.x) / (float)range; if (u < 0) u = 0; if (u > 1) u = 1; *value = valueMin + u * (valueMax - valueMin); *value = std::floor(*value / valueInc + 0.5f) * valueInc; m = u * range; valueChanged = true; } } if (isActive(_state, id)) addRoundedRectangle(_faceMesh->geometry, Vector2(x + m, y), Vector2(SLIDER_MARKER_WIDTH, SLIDER_HEIGHT), 4.0f, Color(1, 1, 1, 1)); else addRoundedRectangle(_faceMesh->geometry, Vector2(x + m, y), Vector2(SLIDER_MARKER_WIDTH, SLIDER_HEIGHT), 4.0f, isHot(_state, id) ? Color(1, 0.75, 0, 1) : Color(1, 1, 1, 0.25)); char valueStr[16]; sprintf(valueStr, "%d%%", (int)std::ceil((*value - valueMin) / (valueMax - valueMin) * 100.0)); const float valueLength = font->textLength(valueStr); Color fontColor = isHot(_state, id) ? Color(1, 0.75, 0, 1) : Color(1, 1, 1, 0.8); if (!enabled) fontColor = Color(0.5, 0.5, 0.5, 0.8); font->buildTextGeometry(text, Vector2(x + SLIDER_HEIGHT * 0.5f, y + SLIDER_HEIGHT * 0.5f + TEXT_HEIGHT * 0.5f), _fontMesh->geometry, fontColor); font->buildTextGeometry(valueStr, Vector2(x + w - valueLength - SLIDER_HEIGHT * 0.5f, y + SLIDER_HEIGHT * 0.5f + TEXT_HEIGHT * 0.5f), _fontMesh->geometry, fontColor); return result || valueChanged; }
void Path::addRoundedRectangle (float x, float y, float w, float h, float cs) { addRoundedRectangle (x, y, w, h, cs, cs); }
void Path::addRoundedRectangle (float x, float y, float w, float h, float csx, float csy) { addRoundedRectangle (x, y, w, h, csx, csy, true, true, true, true); }
void Path::addRoundedRectangle (const float x, const float y, const float w, const float h, float cs) { addRoundedRectangle (x, y, w, h, cs, cs); }