176 lines
5.4 KiB
C++
176 lines
5.4 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
CellularPanel.h
|
|
|
|
Paul Licameli
|
|
|
|
**********************************************************************/
|
|
|
|
#ifndef __AUDACITY_CELLULAR_PANEL__
|
|
#define __AUDACITY_CELLULAR_PANEL__
|
|
|
|
#include "widgets/OverlayPanel.h" // to inherit
|
|
|
|
class ViewInfo;
|
|
class AudacityProject;
|
|
|
|
class TrackPanelCell;
|
|
struct TrackPanelDrawingContext;
|
|
class TrackPanelGroup;
|
|
class TrackPanelNode;
|
|
struct TrackPanelMouseEvent;
|
|
struct TrackPanelMouseState;
|
|
class TranslatableString;
|
|
|
|
class UIHandle;
|
|
using UIHandlePtr = std::shared_ptr<UIHandle>;
|
|
|
|
// This class manages a panel divided into a number of sub-rectangles called
|
|
// cells, that each implement hit tests returning click-drag-release handler
|
|
// objects, and other services.
|
|
// It has no dependency on the Track class.
|
|
class AUDACITY_DLL_API CellularPanel : public OverlayPanel {
|
|
public:
|
|
CellularPanel(wxWindow * parent, wxWindowID id,
|
|
const wxPoint & pos,
|
|
const wxSize & size,
|
|
ViewInfo *viewInfo,
|
|
// default as for wxPanel:
|
|
long style = wxTAB_TRAVERSAL | wxNO_BORDER);
|
|
~CellularPanel() override;
|
|
|
|
// Overridables:
|
|
|
|
virtual AudacityProject *GetProject() const = 0;
|
|
|
|
// Get the root object defining a recursive subdivision of the panel's
|
|
// area into cells
|
|
virtual std::shared_ptr<TrackPanelNode> Root() = 0;
|
|
|
|
virtual TrackPanelCell *GetFocusedCell() = 0;
|
|
virtual void SetFocusedCell() = 0;
|
|
|
|
virtual void ProcessUIHandleResult
|
|
(TrackPanelCell *pClickedCell, TrackPanelCell *pLatestCell,
|
|
unsigned refreshResult) = 0;
|
|
|
|
virtual void UpdateStatusMessage( const TranslatableString & ) = 0;
|
|
|
|
public:
|
|
// Structure and functions for generalized visitation of the subdivision
|
|
struct Visitor {
|
|
virtual ~Visitor();
|
|
virtual void VisitCell( const wxRect &rect, TrackPanelCell &cell );
|
|
virtual void BeginGroup( const wxRect &rect, TrackPanelGroup &group );
|
|
virtual void EndGroup( const wxRect &rect, TrackPanelGroup &group );
|
|
};
|
|
|
|
// Most general visit
|
|
void Visit( Visitor &visitor );
|
|
|
|
// Easier visit when you care only about cells
|
|
using SimpleCellVisitor =
|
|
std::function< void( const wxRect &rect, TrackPanelCell &cell ) >;
|
|
void VisitCells( const SimpleCellVisitor &visitor );
|
|
|
|
// Easier visits when you want to visit each node once only
|
|
using SimpleNodeVisitor =
|
|
std::function< void( const wxRect &rect, TrackPanelNode &node ) >;
|
|
void VisitPreorder( const SimpleNodeVisitor &visitor );
|
|
void VisitPostorder( const SimpleNodeVisitor &visitor );
|
|
|
|
// Find cell by coordinate
|
|
struct FoundCell {
|
|
std::shared_ptr< TrackPanelCell > pCell;
|
|
wxRect rect;
|
|
};
|
|
|
|
FoundCell FindCell(int mouseX, int mouseY);
|
|
|
|
// Search the tree of subdivisions of the panel area for the given cell.
|
|
// If more than one sub-area is associated with the same cell object, it
|
|
// is not specified which rectangle is returned.
|
|
wxRect FindRect(const TrackPanelCell &cell);
|
|
|
|
// Search the tree of subdivisions of the panel area for a node (group or
|
|
// cell) satisfying the predicate. If more than one sub-area is associated
|
|
// with some node satisfying the predicate, it is not specified which
|
|
// rectangle is returned.
|
|
wxRect FindRect(const std::function< bool( TrackPanelNode& ) > &pred);
|
|
|
|
UIHandlePtr Target();
|
|
|
|
std::shared_ptr<TrackPanelCell> LastCell() const;
|
|
|
|
bool IsMouseCaptured();
|
|
|
|
wxCoord MostRecentXCoord() const;
|
|
|
|
void HandleCursorForPresentMouseState(bool doHit = true);
|
|
|
|
// Visit the Draw functions of all cells that intersect the panel area,
|
|
// and of handles associated with such cells,
|
|
// and of all groups of cells,
|
|
// repeatedly with a pass count from 0 to nPasses - 1
|
|
void Draw( TrackPanelDrawingContext &context, unsigned nPasses );
|
|
|
|
protected:
|
|
bool HasEscape();
|
|
bool CancelDragging( bool escaping );
|
|
void DoContextMenu( TrackPanelCell *pCell = nullptr );
|
|
void ClearTargets();
|
|
|
|
private:
|
|
void Visit(
|
|
const wxRect &rect, const std::shared_ptr<TrackPanelNode> &node,
|
|
Visitor &visitor );
|
|
|
|
bool HasRotation();
|
|
bool ChangeTarget(bool forward, bool cycle);
|
|
|
|
void OnMouseEvent(wxMouseEvent & event);
|
|
void OnCaptureLost(wxMouseCaptureLostEvent & event);
|
|
void OnCaptureKey(wxCommandEvent & event);
|
|
void OnKeyDown(wxKeyEvent & event);
|
|
void OnChar(wxKeyEvent & event);
|
|
void OnKeyUp(wxKeyEvent & event);
|
|
|
|
void OnSetFocus(wxFocusEvent & event);
|
|
void OnKillFocus(wxFocusEvent & event);
|
|
|
|
void OnContextMenu(wxContextMenuEvent & event);
|
|
|
|
void HandleInterruptedDrag();
|
|
void Uncapture( bool escaping, wxMouseState *pState = nullptr );
|
|
bool HandleEscapeKey(bool down);
|
|
void UpdateMouseState(const wxMouseState &state);
|
|
void HandleModifierKey();
|
|
|
|
void HandleClick( const TrackPanelMouseEvent &tpmEvent );
|
|
void HandleWheelRotation( TrackPanelMouseEvent &tpmEvent );
|
|
|
|
void HandleMotion( wxMouseState &state, bool doHit = true );
|
|
void HandleMotion
|
|
( const TrackPanelMouseState &tpmState, bool doHit = true );
|
|
void Leave();
|
|
|
|
|
|
protected:
|
|
ViewInfo *mViewInfo;
|
|
|
|
// To do: make a drawing method and make this private
|
|
wxMouseState mLastMouseState;
|
|
|
|
private:
|
|
struct State;
|
|
std::unique_ptr<State> mState;
|
|
|
|
struct Filter;
|
|
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
#endif
|