diff --git a/src-ui/app/SCXTEditor.h b/src-ui/app/SCXTEditor.h index 1056c31c..b08bfa2f 100644 --- a/src-ui/app/SCXTEditor.h +++ b/src-ui/app/SCXTEditor.h @@ -277,6 +277,9 @@ struct SCXTEditor : sst::jucegui::components::WindowPanel, juce::DragAndDropCont } void showTooltip(const juce::Component &relativeTo); + void showTooltip(const juce::Component &relativeTo, const juce::Point &internalPosition); + void repositionTooltip(const juce::Component &relativeTo, + const juce::Point &internalPosition); void hideTooltip(); void setTooltipContents(const std::string &title, const std::vector &rows); diff --git a/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.cpp b/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.cpp index 0ce46ef5..c4064651 100644 --- a/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.cpp +++ b/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.cpp @@ -69,12 +69,14 @@ void ZoneLayoutDisplay::mouseDown(const juce::MouseEvent &e) if (!keyboardHotZones.empty() && keyboardHotZones[0].contains(e.position)) { + updateTooltipContents(true, e.position.toInt()); mouseState = DRAG_KEY; dragFrom[0] = FROM_START; return; } if (!keyboardHotZones.empty() && keyboardHotZones[1].contains(e.position)) { + updateTooltipContents(true, e.position.toInt()); mouseState = DRAG_KEY; dragFrom[0] = FROM_END; return; @@ -82,12 +84,14 @@ void ZoneLayoutDisplay::mouseDown(const juce::MouseEvent &e) if (!velocityHotZones.empty() && velocityHotZones[0].contains(e.position)) { + updateTooltipContents(true, e.position.toInt()); mouseState = DRAG_VELOCITY; dragFrom[1] = FROM_END; return; } if (!velocityHotZones.empty() && velocityHotZones[1].contains(e.position)) { + updateTooltipContents(true, e.position.toInt()); mouseState = DRAG_VELOCITY; dragFrom[1] = FROM_START; return; @@ -104,6 +108,8 @@ void ZoneLayoutDisplay::mouseDown(const juce::MouseEvent &e) dragFrom[0] = (idx == 1 || idx == 2) ? FROM_END : FROM_START; dragFrom[1] = (idx < 2) ? FROM_END : FROM_START; mouseState = DRAG_KEY_AND_VEL; + updateTooltipContents(true, e.position.toInt()); + return; } } @@ -115,6 +121,8 @@ void ZoneLayoutDisplay::mouseDown(const juce::MouseEvent &e) { lastMousePos = e.position; mouseState = DRAG_SELECTED_ZONE; + updateTooltipContents(true, e.position.toInt()); + return; } } @@ -172,6 +180,7 @@ void ZoneLayoutDisplay::mouseDown(const juce::MouseEvent &e) display->editor->doSelectionAction(nextZone, true, false, true); lastMousePos = e.position; mouseState = DRAG_SELECTED_ZONE; + updateTooltipContents(true, e.position.toInt()); } else { @@ -180,6 +189,7 @@ void ZoneLayoutDisplay::mouseDown(const juce::MouseEvent &e) display->editor->doSelectionAction(nextZone, true, true, true); lastMousePos = e.position; mouseState = DRAG_SELECTED_ZONE; + updateTooltipContents(true, e.position.toInt()); } } else @@ -189,12 +199,16 @@ void ZoneLayoutDisplay::mouseDown(const juce::MouseEvent &e) nextZone, true, !(e.mods.isCommandDown() || e.mods.isAltDown()), true); lastMousePos = e.position; mouseState = DRAG_SELECTED_ZONE; + updateTooltipContents(true, e.position.toInt()); } } else { if (e.mods.isCommandDown()) + { mouseState = CREATE_EMPTY_ZONE; + updateTooltipContents(true, e.position.toInt()); + } else mouseState = MULTI_SELECT; firstMousePos = e.position.toFloat(); @@ -448,11 +462,21 @@ void ZoneLayoutDisplay::mouseDrag(const juce::MouseEvent &e) lastMousePos = e.position.toFloat(); repaint(); } + + if (tooltipActive) + { + updateTooltipContents(false, e.position.toInt()); + } } void ZoneLayoutDisplay::mouseUp(const juce::MouseEvent &e) { setMouseCursor(juce::MouseCursor::NormalCursor); + if (tooltipActive) + { + editor->hideTooltip(); + tooltipActive = false; + } if (mouseState == MULTI_SELECT) { auto rz = juce::Rectangle(firstMousePos, e.position); @@ -1101,4 +1125,38 @@ void ZoneLayoutDisplay::labelZoneRectangle(juce::Graphics &g, const juce::Rectan } } +void ZoneLayoutDisplay::updateTooltipContents(bool andShow, const juce::Point &pos) +{ + if (!cacheLastZone.has_value()) + return; + SCLOG_UNIMPL_ONCE("Update Tooltip in ZoneDisplaye currently bypassed"); + if (andShow) + { + juce::Timer::callAfterDelay(100, [pos, w = juce::Component::SafePointer(this)]() { + if (!w) + return; + if (w->tooltipActive) + w->editor->showTooltip(*w, pos); + }); + } + else + { + editor->repositionTooltip(*this, pos); + } + tooltipActive = true; + + sst::jucegui::components::ToolTip::Row velRow, keyRow; + + // TODO: Format these as midi notes not note numbers + keyRow.leftAlignText = std::to_string(cacheLastZone->kr.keyStart); + keyRow.rightAlignText = std::to_string(cacheLastZone->kr.keyEnd); + keyRow.centerAlignText = "key"; + + velRow.leftAlignText = std::to_string(cacheLastZone->vr.velStart); + velRow.rightAlignText = std::to_string(cacheLastZone->vr.velEnd); + velRow.centerAlignText = "vel"; + + editor->setTooltipContents(cacheLastZone->name, {keyRow, velRow}); +} + } // namespace scxt::ui::app::edit_screen \ No newline at end of file diff --git a/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.h b/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.h index 842991c7..e7ea83a1 100644 --- a/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.h +++ b/src-ui/app/edit-screen/components/mapping-pane/ZoneLayoutDisplay.h @@ -140,6 +140,7 @@ struct ZoneLayoutDisplay : juce::Component, HasEditor FROM_START, FROM_END } dragFrom[2]; // key and velocity + bool tooltipActive{false}; std::vector> velocityHotZones, keyboardHotZones, bothHotZones, lastSelectedZone; @@ -163,6 +164,7 @@ struct ZoneLayoutDisplay : juce::Component, HasEditor resetLeadZoneBounds(); repaint(); } + void updateTooltipContents(bool andShow, const juce::Point &pos); }; } // namespace scxt::ui::app::edit_screen diff --git a/src-ui/app/editor-impl/SCXTEditor.cpp b/src-ui/app/editor-impl/SCXTEditor.cpp index 972f8fef..a234f4a9 100644 --- a/src-ui/app/editor-impl/SCXTEditor.cpp +++ b/src-ui/app/editor-impl/SCXTEditor.cpp @@ -373,6 +373,24 @@ void SCXTEditor::showTooltip(const juce::Component &relativeTo) toolTip->getHeight()); } +void SCXTEditor::showTooltip(const juce::Component &relativeTo, const juce::Point &p) +{ + auto fb = getLocalArea(&relativeTo, relativeTo.getLocalBounds()); + toolTip->resetSizeFromData(); + toolTip->setVisible(true); + toolTip->toFront(false); + toolTip->setBounds(fb.getX() + p.getX(), fb.getY() + p.getY(), toolTip->getWidth(), + toolTip->getHeight()); +} + +void SCXTEditor::repositionTooltip(const juce::Component &relativeTo, const juce::Point &p) +{ + auto fb = getLocalArea(&relativeTo, relativeTo.getLocalBounds()); + toolTip->resetSizeFromData(); + toolTip->setBounds(fb.getX() + p.getX(), fb.getY() + p.getY(), toolTip->getWidth(), + toolTip->getHeight()); +} + void SCXTEditor::hideTooltip() { toolTip->setVisible(false); } void SCXTEditor::setTooltipContents(const std::string &title, const std::vector &data)