1 /********************************************************************** 2 3 Audacity: A Digital Audio Editor 4 5 CellularPanel.h 6 7 Paul Licameli 8 9 **********************************************************************/ 10 11 #ifndef __AUDACITY_CELLULAR_PANEL__ 12 #define __AUDACITY_CELLULAR_PANEL__ 13 14 #include "widgets/OverlayPanel.h" // to inherit 15 16 class ViewInfo; 17 class AudacityProject; 18 19 class TrackPanelCell; 20 struct TrackPanelDrawingContext; 21 class TrackPanelGroup; 22 class TrackPanelNode; 23 struct TrackPanelMouseEvent; 24 struct TrackPanelMouseState; 25 class TranslatableString; 26 27 class UIHandle; 28 using UIHandlePtr = std::shared_ptr<UIHandle>; 29 30 // This class manages a panel divided into a number of sub-rectangles called 31 // cells, that each implement hit tests returning click-drag-release handler 32 // objects, and other services. 33 // It has no dependency on the Track class. 34 class AUDACITY_DLL_API CellularPanel : public OverlayPanel { 35 public: 36 CellularPanel(wxWindow * parent, wxWindowID id, 37 const wxPoint & pos, 38 const wxSize & size, 39 ViewInfo *viewInfo, 40 // default as for wxPanel: 41 long style = wxTAB_TRAVERSAL | wxNO_BORDER); 42 ~CellularPanel() override; 43 44 // Overridables: 45 46 virtual AudacityProject *GetProject() const = 0; 47 48 // Get the root object defining a recursive subdivision of the panel's 49 // area into cells 50 virtual std::shared_ptr<TrackPanelNode> Root() = 0; 51 52 virtual TrackPanelCell *GetFocusedCell() = 0; 53 virtual void SetFocusedCell() = 0; 54 55 virtual void ProcessUIHandleResult 56 (TrackPanelCell *pClickedCell, TrackPanelCell *pLatestCell, 57 unsigned refreshResult) = 0; 58 59 virtual void UpdateStatusMessage( const TranslatableString & ) = 0; 60 61 public: 62 // Structure and functions for generalized visitation of the subdivision 63 struct Visitor { 64 virtual ~Visitor(); 65 virtual void VisitCell( const wxRect &rect, TrackPanelCell &cell ); 66 virtual void BeginGroup( const wxRect &rect, TrackPanelGroup &group ); 67 virtual void EndGroup( const wxRect &rect, TrackPanelGroup &group ); 68 }; 69 70 // Most general visit 71 void Visit( Visitor &visitor ); 72 73 // Easier visit when you care only about cells 74 using SimpleCellVisitor = 75 std::function< void( const wxRect &rect, TrackPanelCell &cell ) >; 76 void VisitCells( const SimpleCellVisitor &visitor ); 77 78 // Easier visits when you want to visit each node once only 79 using SimpleNodeVisitor = 80 std::function< void( const wxRect &rect, TrackPanelNode &node ) >; 81 void VisitPreorder( const SimpleNodeVisitor &visitor ); 82 void VisitPostorder( const SimpleNodeVisitor &visitor ); 83 84 // Find cell by coordinate 85 struct FoundCell { 86 std::shared_ptr< TrackPanelCell > pCell; 87 wxRect rect; 88 }; 89 90 FoundCell FindCell(int mouseX, int mouseY); 91 92 // Search the tree of subdivisions of the panel area for the given cell. 93 // If more than one sub-area is associated with the same cell object, it 94 // is not specified which rectangle is returned. 95 wxRect FindRect(const TrackPanelCell &cell); 96 97 // Search the tree of subdivisions of the panel area for a node (group or 98 // cell) satisfying the predicate. If more than one sub-area is associated 99 // with some node satisfying the predicate, it is not specified which 100 // rectangle is returned. 101 wxRect FindRect(const std::function< bool( TrackPanelNode& ) > &pred); 102 103 UIHandlePtr Target(); 104 105 std::shared_ptr<TrackPanelCell> LastCell() const; 106 107 bool IsMouseCaptured(); 108 109 wxCoord MostRecentXCoord() const; 110 111 void HandleCursorForPresentMouseState(bool doHit = true); 112 113 // Visit the Draw functions of all cells that intersect the panel area, 114 // and of handles associated with such cells, 115 // and of all groups of cells, 116 // repeatedly with a pass count from 0 to nPasses - 1 117 void Draw( TrackPanelDrawingContext &context, unsigned nPasses ); 118 119 protected: 120 bool HasEscape(); 121 bool CancelDragging( bool escaping ); 122 void DoContextMenu( TrackPanelCell *pCell = nullptr ); 123 void ClearTargets(); 124 125 private: 126 void Visit( 127 const wxRect &rect, const std::shared_ptr<TrackPanelNode> &node, 128 Visitor &visitor ); 129 130 bool HasRotation(); 131 bool ChangeTarget(bool forward, bool cycle); 132 133 void OnMouseEvent(wxMouseEvent & event); 134 void OnCaptureLost(wxMouseCaptureLostEvent & event); 135 void OnCaptureKey(wxCommandEvent & event); 136 void OnKeyDown(wxKeyEvent & event); 137 void OnChar(wxKeyEvent & event); 138 void OnKeyUp(wxKeyEvent & event); 139 140 void OnSetFocus(wxFocusEvent & event); 141 void OnKillFocus(wxFocusEvent & event); 142 void DoKillFocus(); 143 144 void OnContextMenu(wxContextMenuEvent & event); 145 146 void HandleInterruptedDrag(); 147 void Uncapture( bool escaping, wxMouseState *pState = nullptr ); 148 bool HandleEscapeKey(bool down); 149 void UpdateMouseState(const wxMouseState &state); 150 void HandleModifierKey(); 151 152 void HandleClick( const TrackPanelMouseEvent &tpmEvent ); 153 void HandleWheelRotation( TrackPanelMouseEvent &tpmEvent ); 154 155 void HandleMotion( wxMouseState &state, bool doHit = true ); 156 void HandleMotion 157 ( const TrackPanelMouseState &tpmState, bool doHit = true ); 158 void Leave(); 159 160 161 protected: 162 ViewInfo *mViewInfo; 163 164 // To do: make a drawing method and make this private 165 wxMouseState mLastMouseState; 166 167 private: 168 struct State; 169 std::unique_ptr<State> mState; 170 171 struct Filter; 172 173 DECLARE_EVENT_TABLE() 174 }; 175 176 #endif 177