|
- #include <app/ModuleLightWidget.hpp>
- #include <app/Scene.hpp>
- #include <context.hpp>
- #include <settings.hpp>
-
-
- namespace rack {
- namespace app {
-
-
- struct ModuleLightWidget::Internal {
- ui::Tooltip* tooltip = NULL;
- };
-
-
- struct LightTooltip : ui::Tooltip {
- ModuleLightWidget* lightWidget;
-
- void step() override {
- if (lightWidget->module) {
- engine::LightInfo* lightInfo = lightWidget->getLightInfo();
- if (!lightInfo)
- return;
- // Label
- std::string name = lightInfo->getName();
- text = string::f(string::translate("ModuleLightWidget.light"), name);
- // Description
- std::string description = lightInfo->getDescription();
- if (description != "") {
- text += "\n";
- text += description;
- }
- // Brightness for each color
- text += "\n";
- int numColors = lightWidget->getNumColors();
- for (int colorId = 0; colorId < numColors; colorId++) {
- if (colorId > 1)
- text += " ";
- engine::Light* light = lightWidget->getLight(colorId);
- float brightness = math::clamp(light->getBrightness(), 0.f, 1.f);
- text += string::f("% 3.0f%%", brightness * 100.f);
- }
- }
- Tooltip::step();
- // Position at bottom-right of parameter
- box.pos = lightWidget->getAbsoluteOffset(lightWidget->box.size).round();
- // Fit inside parent (copied from Tooltip.cpp)
- assert(parent);
- box = box.nudge(parent->box.zeroPos());
- }
- };
-
-
- ModuleLightWidget::ModuleLightWidget() {
- internal = new Internal;
- }
-
-
- ModuleLightWidget::~ModuleLightWidget() {
- destroyTooltip();
- delete internal;
- }
-
-
- engine::Light* ModuleLightWidget::getLight(int colorId) {
- if (!module)
- return NULL;
- if (firstLightId < 0)
- return NULL;
- return &module->lights[firstLightId + colorId];
- }
-
-
- engine::LightInfo* ModuleLightWidget::getLightInfo() {
- if (!module)
- return NULL;
- if (firstLightId < 0)
- return NULL;
- return module->lightInfos[firstLightId];
- }
-
-
- void ModuleLightWidget::createTooltip() {
- if (!settings::tooltips)
- return;
- if (internal->tooltip)
- return;
- // If the LightInfo is null, don't show a tooltip
- if (!getLightInfo())
- return;
- LightTooltip* tooltip = new LightTooltip;
- tooltip->lightWidget = this;
- APP->scene->addChild(tooltip);
- internal->tooltip = tooltip;
- }
-
-
- void ModuleLightWidget::destroyTooltip() {
- if (!internal->tooltip)
- return;
- APP->scene->removeChild(internal->tooltip);
- delete internal->tooltip;
- internal->tooltip = NULL;
- }
-
-
- void ModuleLightWidget::step() {
- std::vector<float> brightnesses(baseColors.size());
-
- int lastLightId = firstLightId + (int) baseColors.size();
- if (module) {
- if (module->isBypassed()) {
- // Leave lights off
- }
- else if (0 <= firstLightId && lastLightId <= (int) module->lights.size()) {
- for (size_t i = 0; i < baseColors.size(); i++) {
- float b = module->lights[firstLightId + i].getBrightness();
- if (!std::isfinite(b))
- b = 0.f;
- b = math::clamp(b, 0.f, 1.f);
- // Because LEDs are nonlinear, this seems to look more natural.
- b = std::sqrt(b);
- brightnesses[i] = b;
- }
- }
- }
- else {
- // Turn all lights on
- for (size_t i = 0; i < baseColors.size(); i++) {
- brightnesses[i] = 1.f;
- }
- }
-
- setBrightnesses(brightnesses);
-
- MultiLightWidget::step();
- }
-
-
- void ModuleLightWidget::onHover(const HoverEvent& e) {
- // Adapted from OpaqueWidget::onHover()
- Widget::onHover(e);
-
- // If the LightInfo is null, don't consume Hover event
- if (!getLightInfo())
- return;
-
- e.stopPropagating();
- // Consume if not consumed by child
- if (!e.isConsumed())
- e.consume(this);
- }
-
-
- void ModuleLightWidget::onEnter(const EnterEvent& e) {
- createTooltip();
- }
-
-
- void ModuleLightWidget::onLeave(const LeaveEvent& e) {
- destroyTooltip();
- }
-
-
- } // namespace app
- } // namespace rack
|