Audacity  2.2.2
Grabber.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Grabber.cpp
6 
7  Leland Lucius
8 
9 *******************************************************************//*******************************************************************//**********************************************************************/
22 
23 #include "../Audacity.h"
24 
25 #include <wx/defs.h>
26 #include <wx/dcclient.h>
27 #include <wx/event.h>
28 #include <wx/intl.h>
29 #include <wx/window.h>
30 
31 #include "Grabber.h"
32 #include "../Experimental.h"
33 
34 #include "../AColor.h"
35 #include "../AllThemeResources.h"
36 #include "../Internat.h"
37 
41 
42 DEFINE_EVENT_TYPE(EVT_GRABBER_CLICKED)
43 
44 BEGIN_EVENT_TABLE(Grabber, wxWindow)
45  EVT_ENTER_WINDOW(Grabber::OnEnter)
46  EVT_LEAVE_WINDOW(Grabber::OnLeave)
47  EVT_LEFT_DOWN(Grabber::OnLeftDown)
48  EVT_ERASE_BACKGROUND( Grabber::OnErase )
49  EVT_PAINT(Grabber::OnPaint)
50  EVT_KEY_DOWN(Grabber::OnKeyDown)
52 
53 //
54 // Constructor
55 //
56 Grabber::Grabber(wxWindow * parent, wxWindowID id)
57 : wxWindow(parent,
58  id,
59  wxDefaultPosition,
60  wxSize(grabberWidth, 27),
61  wxFULL_REPAINT_ON_RESIZE)
62 {
63  mOver = false;
64  mPressed = false;
65  mAsSpacer = false;
66  SetBackgroundColour( theTheme.Colour( clrMedium ) );
67 
68  /* i18n-hint: A 'Grabber' is a region you can click and drag on
69  It's used to drag a track around (when in multi-tool mode) rather
70  than requiring that you use the drag tool. It's shown as a series
71  of horizontal bumps */
72 
73  SetLabel(_("Grabber"));
74  SetName(_("Grabber"));
75 }
76 
77 //
78 // Destructor
79 //
81 {
82 }
83 
84 //
85 // Queue a drag event
86 //
87 void Grabber::SendEvent(wxEventType type, const wxPoint & pos, bool escaping)
88 {
89  wxWindow *parent = GetParent();
90 
91  // Initialize event and convert mouse coordinates to screen space
92  GrabberEvent e(type, GetId(), parent->ClientToScreen(pos), escaping);
93 
94  // Set the object of our desire
95  e.SetEventObject(parent);
96 
97  // Queue the event
98  parent->GetEventHandler()->AddPendingEvent(e);
99 }
100 
101 void Grabber::SetAsSpacer( bool bIsSpacer ) {
102  if( mAsSpacer != bIsSpacer ){
103  // HACK: Use a wider rectangle to also cover one pixel of space just to the right.
104  wxSize siz = GetSize();
105  siz.IncBy( bIsSpacer ? 1:-1, 0 );
106  SetSize( siz );
107  }
108  mAsSpacer = bIsSpacer;
109 };
110 
111 
112 //
113 // Draw the grabber
114 //
115 void Grabber::DrawGrabber( wxDC & dc )
116 {
117  wxRect r = GetRect();
118  // PaintDC positions are relative to the grabber, not the parent window.
119  // So use 0,0 as origin for draw, so that the grabber draws right if
120  // positioned in its parent at some non zero position.
121  r.SetPosition( wxPoint(0,0) );
122  int y, left, right, top, bottom;
123 
124  AColor::Medium(&dc, mOver );
125  dc.DrawRectangle(r);
126 
127  // HACK: We used a wider rectangle to also cover one pixel of space just to the right.
128  if( mAsSpacer )
129  r.width -= 1;
130 
131 #ifndef __WXMAC__
132 
133  // Add a box
134  r.width -= 1;
135  r.height -= 1;
136  AColor::Bevel(dc, !mPressed, r);
137  r.width += 1;
138  r.height += 1;
139 
140 #endif
141 
142  // No bumps in a spacer grabber.
143  if( mAsSpacer )
144  return;
145  // Calculate the bump rectangle
146  r.Deflate(3, 3);
147  if ((r.GetHeight() % 4) < 2) {
148  r.Offset(0, 1);
149  }
150 
151  // Cache
152  left = r.GetLeft();
153  right = r.GetRight();
154  top = r.GetTop();
155  bottom = r.GetBottom();
156 
157  // Draw the raised bumps
158  if (mPressed) {
159  AColor::Dark(&dc, false);
160  }
161  else {
162  AColor::Light(&dc, false);
163  }
164 
165  for (y = top; y < bottom; y += 4) {
166  AColor::Line(dc, left, y, right, y);
167  }
168 
169  // Draw the pushed bumps
170  if (mPressed) {
171  AColor::Light(&dc, false);
172  }
173  else {
174  AColor::Dark(&dc, false);
175  }
176 
177  for (y = top + 1; y <= bottom; y += 4) {
178  AColor::Line(dc, left, y, right, y);
179  }
180 }
181 
182 //
183 // Change the button state
184 //
185 void Grabber::PushButton(bool state )
186 {
187  if( mAsSpacer )
188  return;
189  wxRect r = GetRect();
190  mOver = r.Contains(ScreenToClient(wxGetMousePosition()));
191 
192  // Redraw button
193  mPressed = state;
194  Refresh(false);
195 }
196 
197 //
198 // Handle left button down events
199 //
200 void Grabber::OnLeftDown(wxMouseEvent & event)
201 {
202  // Button should be drawn pushed
203  PushButton(true);
204 
205  // Notify parent
206  SendEvent(EVT_GRABBER_CLICKED, event.GetPosition(), false);
207 
208  event.Skip();
209 }
210 
211 //
212 // Handle mouse enter events
213 //
214 void Grabber::OnEnter(wxMouseEvent & WXUNUSED(event))
215 {
216  // Bug 1201: On Mac, unsetting and re-setting the tooltip may be needed
217  // to make it pop up when we want it.
218  const auto text = GetToolTipText();
219  UnsetToolTip();
220  SetToolTip(text);
221 
222  if( mAsSpacer )
223  return;
224 
225  // Redraw highlighted
226  mOver = true;
227  Refresh(false);
228 }
229 
230 //
231 // Handle mouse leave events
232 //
233 void Grabber::OnLeave(wxMouseEvent & WXUNUSED(event))
234 {
235  if (!GetCapture()) {
236  // Redraw plain
237  mOver = false;
238  Refresh(false);
239  }
240 }
241 
242 void Grabber::OnErase( wxEraseEvent & WXUNUSED(event) )
243 {
244  // Ignore it to prevent flashing
245 }
246 
247 //
248 // Handle the paint events
249 //
250 void Grabber::OnPaint(wxPaintEvent & WXUNUSED(event))
251 {
252  wxPaintDC dc(this);
253 
254  // Redraw the grabber
255  DrawGrabber(dc);
256 }
257 
258 void Grabber::OnKeyDown(wxKeyEvent &event)
259 {
260  event.Skip();
261 
262  if(event.GetKeyCode() == WXK_ESCAPE) {
263  // We must not only skip this key event, but propagate it up the window
264  // hierarchy, so that ToolFrame detects it too.
265  event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
266  SendEvent(EVT_GRABBER_CLICKED, wxPoint{ -1, -1 }, true);
267  }
268 }
269 
270 // Piggy back in same source file as Grabber.
271 // Audcaity Flicker-free StaticBitmap.
272 BEGIN_EVENT_TABLE(AStaticBitmap,wxStaticBitmap)
273  EVT_ERASE_BACKGROUND(AStaticBitmap::OnErase)
275 
276 
Grabber Class.
Definition: Grabber.h:43
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:209
virtual ~Grabber()
Definition: Grabber.cpp:80
bool mAsSpacer
Definition: Grabber.h:133
DEFINE_EVENT_TYPE(EVT_OPEN_AUDIO_FILE)
Custom events.
bool mPressed
Definition: Grabber.h:132
void DrawGrabber(wxDC &dc)
Definition: Grabber.cpp:115
static void Dark(wxDC *dc, bool selected, bool highlight=false)
Definition: AColor.cpp:338
void OnLeave(wxMouseEvent &event)
Definition: Grabber.cpp:233
static void Medium(wxDC *dc, bool selected)
Definition: AColor.cpp:319
void SendEvent(wxEventType type, const wxPoint &pos, bool escaping)
Definition: Grabber.cpp:87
static void Bevel(wxDC &dc, bool up, const wxRect &r)
Definition: AColor.cpp:202
#define grabberWidth
Definition: Grabber.h:96
void OnPaint(wxPaintEvent &event)
Definition: Grabber.cpp:250
bool mOver
Definition: Grabber.h:131
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:122
static void Light(wxDC *dc, bool selected, bool highlight=false)
Definition: AColor.cpp:308
void OnEnter(wxMouseEvent &event)
Definition: Grabber.cpp:214
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
void SetAsSpacer(bool bIsSpacer)
Definition: Grabber.cpp:101
void OnLeftDown(wxMouseEvent &event)
Definition: Grabber.cpp:200
The widget to the left of a ToolBar that allows it to be dragged around to NEW positions.
Definition: Grabber.h:98
wxColour & Colour(int iIndex)
Definition: Theme.cpp:1225
END_EVENT_TABLE()
void OnKeyDown(wxKeyEvent &event)
Definition: Grabber.cpp:258
void OnErase(wxEraseEvent &event)
Definition: Grabber.cpp:242
void PushButton(bool state)
Definition: Grabber.cpp:185