diff --git a/src/AdornedRulerPanel.cpp b/src/AdornedRulerPanel.cpp index cd6f0eb63..f3f5aa31a 100644 --- a/src/AdornedRulerPanel.cpp +++ b/src/AdornedRulerPanel.cpp @@ -2141,19 +2141,6 @@ std::shared_ptr AdornedRulerPanel::Root() return std::make_shared< MainGroup >( *this ); } -auto AdornedRulerPanel::FindCell(int mouseX, int mouseY) -> FoundCell -{ - bool mayScrub = mProject->GetScrubber().CanScrub() && - mShowScrubbing; - if (mayScrub && mScrubZone.Contains(mouseX, mouseY)) - return { mScrubbingCell, mScrubZone }; - - if (mInner.Contains(mouseX, mouseY)) - return { mQPCell, mInner }; - - return {}; -} - wxRect AdornedRulerPanel::FindRect(const TrackPanelCell &cell) { if (&cell == mScrubbingCell.get()) diff --git a/src/AdornedRulerPanel.h b/src/AdornedRulerPanel.h index 9c4c81bff..057035a38 100644 --- a/src/AdornedRulerPanel.h +++ b/src/AdornedRulerPanel.h @@ -177,7 +177,6 @@ private: // area into cells std::shared_ptr Root() override; - FoundCell FindCell(int mouseX, int mouseY) override; wxRect FindRect(const TrackPanelCell &cell) override; public: AudacityProject * GetProject() const override; diff --git a/src/CellularPanel.cpp b/src/CellularPanel.cpp index 3614dc021..c569a2699 100644 --- a/src/CellularPanel.cpp +++ b/src/CellularPanel.cpp @@ -937,7 +937,6 @@ namespace { const auto end = children.end(); const auto nextCoord = ((next == end) ? upperBound : next->first - 1); - // Some defense against bad overrides of TrackPanelGroup::Children auto lesser = std::max(lowerBound, std::min(upperBound, iter->first)); auto greater = std::max(lesser, std::min(upperBound, nextCoord)); @@ -976,6 +975,45 @@ void CellularPanel::Visit( return; } +auto CellularPanel::FindCell(int mouseX, int mouseY) -> FoundCell +{ + auto rect = this->GetClientRect(); + auto node = Root(); + while (node) { + if ( auto pCell = std::dynamic_pointer_cast< TrackPanelCell >( node ) ) + // Found the bottom of the hierarchy + return { pCell, rect }; + else if ( auto pGroup = dynamic_cast< TrackPanelGroup* >( node.get() ) ) { + // Ask node for its subdivision + const auto results = pGroup->Children( rect ); + const bool divideX = results.first == TrackPanelGroup::Axis::X; + const auto &children = results.second; + + // Find the correct child + const auto begin = children.begin(), end = children.end(); + auto iter = std::upper_bound( begin, end, + (divideX ? mouseX : mouseY), + [&]( wxCoord coord, const TrackPanelGroup::Child &child ) { + return coord < child.first; + } + ); + if (iter == begin) + break; + --iter; + + // Descend the hierarchy of nodes + rect = Subdivide(rect, divideX, children, iter); + node = iter->second; + } + else + // Nulls in the array of children are allowed, to define a void with + // no cell + break; + } + + return { {}, {} }; +} + UIHandlePtr CellularPanel::Target() { auto &state = *mState; diff --git a/src/CellularPanel.h b/src/CellularPanel.h index f5c7595dc..90bc2e629 100644 --- a/src/CellularPanel.h +++ b/src/CellularPanel.h @@ -44,17 +44,10 @@ public: virtual AudacityProject *GetProject() const = 0; - // Find track info by coordinate - struct FoundCell { - std::shared_ptr pCell; - wxRect rect; - }; - // Get the root object defining a recursive subdivision of the panel's // area into cells virtual std::shared_ptr Root() = 0; - virtual FoundCell FindCell(int mouseX, int mouseY) = 0; virtual wxRect FindRect(const TrackPanelCell &cell) = 0; // Structure and functions for generalized visitation of the subdivision @@ -93,6 +86,14 @@ public: virtual bool TakesFocus() const = 0; public: + // Find cell by coordinate + struct FoundCell { + std::shared_ptr< TrackPanelCell > pCell; + wxRect rect; + }; + + FoundCell FindCell(int mouseX, int mouseY); + UIHandlePtr Target(); std::shared_ptr LastCell() const; diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index dfb43eb8e..bb1d22b5e 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -126,13 +126,13 @@ time, but that width may be adjusted when tracks change their vertical scales. GetLabelWidth() counts columns up to and including the VRuler. GetLeftOffset() is yet one more -- it counts the "one pixel" column. -FindCell() for label returns a rectangle that OMITS left, top, and bottom +Cell for label has a rectangle that OMITS left, top, and bottom margins -FindCell() for vruler returns a rectangle right of the label, +Cell for vruler has a rectangle right of the label, up to and including the One Pixel column, and OMITS top and bottom margins -FindCell() for track returns a rectangle with x == GetLeftOffset(), and OMITS +Cell() for track returns a rectangle with x == GetLeftOffset(), and OMITS right, top, and bottom margins +--------------- ... ------ ... --------------------- ... ... -------------+ @@ -2088,27 +2088,6 @@ std::shared_ptr TrackPanel::Root() return std::make_shared< MainGroup >( *this ); } -/// Determines which cell is under the mouse -/// @param mouseX - mouse X position. -/// @param mouseY - mouse Y position. -auto TrackPanel::FindCell(int mouseX, int mouseY) -> FoundCell -{ - auto range = Cells(); - auto &iter = range.first, &end = range.second; - while - ( iter != end && - !(*iter).second.Contains( mouseX, mouseY ) ) - ++iter; - if (iter == end) - return {}; - - auto found = *iter; - return { - found.first, - found.second - }; -} - wxRect TrackPanel::FindRect( const TrackPanelCell &cell ) { auto range = Cells(); diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 1d7bce695..25a720aa9 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -341,9 +341,6 @@ protected: // area into cells std::shared_ptr Root() override; - // Find track info by coordinate - FoundCell FindCell(int mouseX, int mouseY) override; - // Find rectangle of the given cell wxRect FindRect(const TrackPanelCell &cell) override;