1 /**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 CommonTrackPanelCell.cpp
6
7 Paul Licameli split from TrackPanel.cpp
8
9 **********************************************************************/
10
11 #include "CommonTrackPanelCell.h"
12
13 #include <wx/cursor.h>
14 #include <wx/event.h>
15 #include <wx/menu.h>
16
17 #include "../../widgets/BasicMenu.h"
18 #include "BasicUI.h"
19 #include "../../commands/CommandContext.h"
20 #include "../../commands/CommandManager.h"
21 #include "../../HitTestResult.h"
22 #include "../../RefreshCode.h"
23 #include "../../TrackPanelMouseEvent.h"
24 #include "ViewInfo.h"
25 #include "../../widgets/wxWidgetsWindowPlacement.h"
26
27 namespace {
GetHook()28 CommonTrackPanelCell::Hook &GetHook()
29 {
30 static CommonTrackPanelCell::Hook theHook;
31 return theHook;
32 }
33 }
34
InstallMouseWheelHook(const Hook & hook)35 auto CommonTrackPanelCell::InstallMouseWheelHook( const Hook &hook )
36 -> Hook
37 {
38 auto &theHook = GetHook();
39 auto result = theHook;
40 theHook = hook;
41 return result;
42 }
43
~CommonTrackPanelCell()44 CommonTrackPanelCell::~CommonTrackPanelCell()
45 {
46 }
47
DefaultPreview(const TrackPanelMouseState &,const AudacityProject *)48 HitTestPreview CommonTrackPanelCell::DefaultPreview
49 (const TrackPanelMouseState &, const AudacityProject *)
50 {
51 static wxCursor defaultCursor{ wxCURSOR_ARROW };
52 return { {}, &defaultCursor, {} };
53 }
54
GetMenuItems(const wxRect &,const wxPoint *,AudacityProject *)55 auto CommonTrackPanelCell::GetMenuItems(
56 const wxRect&, const wxPoint *, AudacityProject * )
57 -> std::vector<MenuItem>
58 {
59 return {};
60 }
61
DoContextMenu(const wxRect & rect,wxWindow * pParent,const wxPoint * pPoint,AudacityProject * pProject)62 unsigned CommonTrackPanelCell::DoContextMenu( const wxRect &rect,
63 wxWindow *pParent, const wxPoint *pPoint, AudacityProject *pProject)
64 {
65 const auto items = GetMenuItems( rect, pPoint, pProject );
66 if (items.empty())
67 return RefreshCode::RefreshNone;
68
69 // Set up command context with extras
70 CommandContext context{ *pProject };
71 SelectedRegion region;
72 if (pPoint) {
73 auto time = ViewInfo::Get(*pProject).PositionToTime(pPoint->x, rect.x);
74 region = { time, time };
75 context.temporarySelection.pSelectedRegion = ®ion;
76 }
77 context.temporarySelection.pTrack = FindTrack().get();
78
79 auto &commandManager = CommandManager::Get(*pProject);
80 auto flags = MenuManager::Get( *pProject ).GetUpdateFlags();
81
82 // Common dispatcher for the menu items
83 auto dispatcher = [&]( wxCommandEvent &evt ){
84 auto idx = evt.GetId() - 1;
85 if (idx >= 0 && idx < items.size()) {
86 if (auto &action = items[idx].action)
87 action( context );
88 else
89 commandManager.HandleTextualCommand(
90 items[idx].symbol.Internal(), context, flags, false);
91 }
92 };
93
94 wxMenu menu;
95 int ii = 1;
96 for (const auto &item: items) {
97 if ( const auto &commandID = item.symbol.Internal();
98 commandID.empty() )
99 menu.AppendSeparator();
100 else {
101 // Generate a menu item with the same shortcut key as in the toolbar
102 // menu, and as determined by keyboard preferences
103 auto label =
104 commandManager.FormatLabelForMenu( commandID, &item.symbol.Msgid() );
105 menu.Append( ii, label );
106 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, dispatcher );
107 bool enabled = item.enabled &&
108 (item.action || commandManager.GetEnabled( commandID ));
109 menu.Enable( ii, enabled );
110 }
111 ++ii;
112 }
113
114 BasicUI::Point point;
115 if (pPoint)
116 point = { pPoint->x, pPoint->y };
117 BasicMenu::Handle{ &menu }.Popup(
118 wxWidgetsWindowPlacement{ pParent },
119 point
120 );
121
122 return RefreshCode::RefreshNone;
123 }
124
HandleWheelRotation(const TrackPanelMouseEvent & evt,AudacityProject * pProject)125 unsigned CommonTrackPanelCell::HandleWheelRotation
126 (const TrackPanelMouseEvent &evt, AudacityProject *pProject)
127 {
128 auto hook = GetHook();
129 return hook ? hook( evt, pProject ) : RefreshCode::Cancelled;
130 }
131
CommonTrackCell(const std::shared_ptr<Track> & parent)132 CommonTrackCell::CommonTrackCell( const std::shared_ptr< Track > &parent )
133 : mwTrack { parent }
134 {}
135
136 CommonTrackCell::~CommonTrackCell() = default;
137
CopyTo(Track &) const138 void CommonTrackCell::CopyTo( Track& ) const
139 {
140 }
141
Reparent(const std::shared_ptr<Track> & parent)142 void CommonTrackCell::Reparent( const std::shared_ptr<Track> &parent )
143 {
144 mwTrack = parent;
145 }
146
DoFindTrack()147 std::shared_ptr<Track> CommonTrackCell::DoFindTrack()
148 {
149 return mwTrack.lock();
150 }
151
WriteXMLAttributes(XMLWriter &) const152 void CommonTrackCell::WriteXMLAttributes( XMLWriter & ) const
153 {
154 }
155
HandleXMLAttribute(const std::string_view & attr,const XMLAttributeValueView & valueView)156 bool CommonTrackCell::HandleXMLAttribute(
157 const std::string_view& attr, const XMLAttributeValueView& valueView)
158 {
159 return false;
160 }
161