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