502 lines
10 KiB
C++
502 lines
10 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
TrackPanelAx.cpp
|
|
|
|
Leland Lucius
|
|
and lots of other contributors
|
|
|
|
******************************************************************//*!
|
|
|
|
\class TrackPanelAx
|
|
\brief Helper to TrackPanel to give accessibility.
|
|
|
|
*//*******************************************************************/
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include <wx/wxprec.h>
|
|
|
|
#ifndef WX_PRECOMP
|
|
// Include your minimal set of headers here, or wx.h
|
|
#include <wx/wx.h>
|
|
#endif
|
|
|
|
|
|
#include "Audacity.h"
|
|
#include "TrackPanelAx.h"
|
|
|
|
#include <wx/intl.h>
|
|
|
|
TrackPanelAx::TrackPanelAx( wxWindow *window )
|
|
#if wxUSE_ACCESSIBILITY
|
|
:wxWindowAccessible( window )
|
|
#endif
|
|
{
|
|
mTrackPanel = wxDynamicCast( window, TrackPanel );
|
|
mFocusedTrack = NULL;
|
|
}
|
|
|
|
TrackPanelAx::~TrackPanelAx()
|
|
{
|
|
}
|
|
|
|
// Returns currently focused track or first one if none focused
|
|
Track *TrackPanelAx::GetFocus()
|
|
{
|
|
if( !mFocusedTrack )
|
|
{
|
|
SetFocus( NULL );
|
|
}
|
|
|
|
if( !TrackNum( mFocusedTrack ) )
|
|
{
|
|
mFocusedTrack = NULL;
|
|
}
|
|
|
|
return( mFocusedTrack );
|
|
}
|
|
|
|
// Changes focus to a specified track
|
|
void TrackPanelAx::SetFocus( Track *track )
|
|
{
|
|
#if wxUSE_ACCESSIBILITY
|
|
if( mFocusedTrack != NULL )
|
|
{
|
|
NotifyEvent( wxACC_EVENT_OBJECT_SELECTIONREMOVE,
|
|
mTrackPanel,
|
|
wxOBJID_CLIENT,
|
|
TrackNum( mFocusedTrack ) );
|
|
}
|
|
#endif
|
|
|
|
if( track == NULL )
|
|
{
|
|
TrackListIterator iter( mTrackPanel->mTracks );
|
|
track = iter.First();
|
|
}
|
|
|
|
mFocusedTrack = track;
|
|
|
|
#if wxUSE_ACCESSIBILITY
|
|
if( mFocusedTrack != NULL )
|
|
{
|
|
int num = TrackNum( mFocusedTrack );
|
|
|
|
NotifyEvent( wxACC_EVENT_OBJECT_FOCUS,
|
|
mTrackPanel,
|
|
wxOBJID_CLIENT,
|
|
num );
|
|
|
|
if( mFocusedTrack->GetSelected() )
|
|
{
|
|
NotifyEvent( wxACC_EVENT_OBJECT_SELECTION,
|
|
mTrackPanel,
|
|
wxOBJID_CLIENT,
|
|
num );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
// Returns TRUE if passed track has the focus
|
|
bool TrackPanelAx::IsFocused( Track *track )
|
|
{
|
|
if( !mFocusedTrack )
|
|
{
|
|
SetFocus( NULL );
|
|
}
|
|
|
|
if( ( track == mFocusedTrack ) ||
|
|
( track == mFocusedTrack->GetLink() ) )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int TrackPanelAx::TrackNum( Track *target )
|
|
{
|
|
TrackListIterator iter( mTrackPanel->mTracks );
|
|
Track *t = iter.First();
|
|
int ndx = 0;
|
|
|
|
while( t != NULL )
|
|
{
|
|
ndx++;
|
|
if( t == target )
|
|
{
|
|
return ndx;
|
|
}
|
|
|
|
t = iter.Next( true );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
Track *TrackPanelAx::FindTrack( int num )
|
|
{
|
|
TrackListIterator iter( mTrackPanel->mTracks );
|
|
Track *t = iter.First();
|
|
int ndx = 0;
|
|
|
|
while( t != NULL )
|
|
{
|
|
ndx++;
|
|
if( ndx == num )
|
|
{
|
|
break;
|
|
}
|
|
|
|
t = iter.Next( true );
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
void TrackPanelAx::Updated()
|
|
{
|
|
#if wxUSE_ACCESSIBILITY
|
|
Track *t = GetFocus();
|
|
NotifyEvent(wxACC_EVENT_OBJECT_NAMECHANGE,
|
|
mTrackPanel,
|
|
wxOBJID_CLIENT,
|
|
TrackNum(t));
|
|
SetFocus(t);
|
|
#endif
|
|
}
|
|
|
|
#if wxUSE_ACCESSIBILITY
|
|
|
|
// Retrieves the address of an IDispatch interface for the specified child.
|
|
// All objects must support this property.
|
|
wxAccStatus TrackPanelAx::GetChild( int childId, wxAccessible** child )
|
|
{
|
|
if( childId == wxACC_SELF )
|
|
{
|
|
*child = this;
|
|
}
|
|
else
|
|
{
|
|
*child = NULL;
|
|
}
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Gets the number of children.
|
|
wxAccStatus TrackPanelAx::GetChildCount( int* childCount )
|
|
{
|
|
TrackListIterator iter( mTrackPanel->mTracks );
|
|
Track *t = iter.First();
|
|
int cnt = 0;
|
|
|
|
while( t != NULL )
|
|
{
|
|
cnt++;
|
|
|
|
if( t->GetLink() != NULL )
|
|
{
|
|
t = iter.Next();
|
|
}
|
|
|
|
t = iter.Next();
|
|
}
|
|
|
|
*childCount = cnt;
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Gets the default action for this object (0) or > 0 (the action for a child).
|
|
// Return wxACC_OK even if there is no action. actionName is the action, or the empty
|
|
// string if there is no action.
|
|
// The retrieved string describes the action that is performed on an object,
|
|
// not what the object does as a result. For example, a toolbar button that prints
|
|
// a document has a default action of "Press" rather than "Prints the current document."
|
|
wxAccStatus TrackPanelAx::GetDefaultAction( int childId, wxString *actionName )
|
|
{
|
|
actionName->Clear();
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Returns the description for this object or a child.
|
|
wxAccStatus TrackPanelAx::GetDescription( int childId, wxString *description )
|
|
{
|
|
description->Clear();
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Returns help text for this object or a child, similar to tooltip text.
|
|
wxAccStatus TrackPanelAx::GetHelpText( int childId, wxString *helpText )
|
|
{
|
|
helpText->Clear();
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Returns the keyboard shortcut for this object or child.
|
|
// Return e.g. ALT+K
|
|
wxAccStatus TrackPanelAx::GetKeyboardShortcut( int childId, wxString *shortcut )
|
|
{
|
|
shortcut->Clear();
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Returns the rectangle for this object (id = 0) or a child element (id > 0).
|
|
// rect is in screen coordinates.
|
|
wxAccStatus TrackPanelAx::GetLocation( wxRect& rect, int elementId )
|
|
{
|
|
wxRect client;
|
|
|
|
if( elementId == wxACC_SELF )
|
|
{
|
|
rect = mTrackPanel->GetRect();
|
|
}
|
|
else
|
|
{
|
|
Track *t = FindTrack( elementId );
|
|
|
|
if( t == NULL )
|
|
{
|
|
return wxACC_FAIL;
|
|
}
|
|
|
|
rect = mTrackPanel->FindTrackRect( t, true );
|
|
}
|
|
|
|
rect.SetPosition( mTrackPanel->GetParent()->ClientToScreen( rect.GetPosition() ) );
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Gets the name of the specified object.
|
|
wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
|
|
{
|
|
#if defined(__WXMSW__)
|
|
if( childId == wxACC_SELF )
|
|
{
|
|
*name = _( "TrackView" );
|
|
}
|
|
else
|
|
{
|
|
Track *t = FindTrack( childId );
|
|
|
|
if( t == NULL )
|
|
{
|
|
return wxACC_FAIL;
|
|
}
|
|
else
|
|
{
|
|
*name = t->GetName();
|
|
if( *name == t->GetDefaultName() )
|
|
{
|
|
/* i18n-hint: The %d is replaced by th enumber of the track.*/
|
|
name->Printf(_("Track %d"), TrackNum( t ) );
|
|
}
|
|
|
|
// LLL: Remove these during "refactor"
|
|
if( t->GetMute() )
|
|
{
|
|
/* i18n-hint: This is for screen reader software and indicates that
|
|
on this track mute is on.*/
|
|
*name->Append( _( " Mute On" ) );
|
|
}
|
|
|
|
if( t->GetSolo() )
|
|
{
|
|
/* i18n-hint: This is for screen reader software and indicates that
|
|
on this track solo is on.*/
|
|
*name->Append( _( " Solo On" ) );
|
|
}
|
|
if( t->GetSelected() )
|
|
{
|
|
/* i18n-hint: This is for screen reader software and indicates that
|
|
this track is selected.*/
|
|
*name->Append( _( " Select On" ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return wxACC_OK;
|
|
#endif
|
|
|
|
#if defined(__WXMAC__)
|
|
return wxACC_NOT_IMPLEMENTED;
|
|
#endif
|
|
}
|
|
|
|
// Returns a role constant.
|
|
wxAccStatus TrackPanelAx::GetRole( int childId, wxAccRole* role )
|
|
{
|
|
#if defined(__WXMSW__)
|
|
if( childId == wxACC_SELF )
|
|
{
|
|
*role = wxROLE_SYSTEM_TABLE;
|
|
}
|
|
else
|
|
{
|
|
*role = wxROLE_SYSTEM_ROW;
|
|
}
|
|
#endif
|
|
|
|
#if defined(__WXMAC__)
|
|
if( childId == wxACC_SELF )
|
|
{
|
|
*role = wxROLE_SYSTEM_PANE;
|
|
}
|
|
else
|
|
{
|
|
*role = wxROLE_SYSTEM_STATICTEXT;
|
|
}
|
|
#endif
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Gets a variant representing the selected children
|
|
// of this object.
|
|
// Acceptable values:
|
|
// - a null variant (IsNull() returns TRUE)
|
|
// - a list variant (GetType() == wxT("list"))
|
|
// - an integer representing the selected child element,
|
|
// or 0 if this object is selected (GetType() == wxT("long"))
|
|
// - a "void*" pointer to a wxAccessible child object
|
|
wxAccStatus TrackPanelAx::GetSelections( wxVariant *selections )
|
|
{
|
|
return wxACC_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
// Returns a state constant.
|
|
wxAccStatus TrackPanelAx::GetState( int childId, long* state )
|
|
{
|
|
*state = wxACC_STATE_SYSTEM_FOCUSABLE | wxACC_STATE_SYSTEM_SELECTABLE;
|
|
|
|
if( childId > 0 )
|
|
{
|
|
Track *t = FindTrack( childId );
|
|
|
|
if (t)
|
|
{
|
|
if( t == mFocusedTrack )
|
|
{
|
|
*state |= wxACC_STATE_SYSTEM_FOCUSED;
|
|
}
|
|
|
|
if( t->GetSelected() )
|
|
{
|
|
*state |= wxACC_STATE_SYSTEM_SELECTED;
|
|
}
|
|
}
|
|
}
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
// Returns a localized string representing the value for the object
|
|
// or child.
|
|
wxAccStatus TrackPanelAx::GetValue( int childId, wxString* strValue )
|
|
{
|
|
#if defined(__WXMSW__)
|
|
return wxACC_NOT_IMPLEMENTED;
|
|
#endif
|
|
|
|
#if defined(__WXMAC__)
|
|
if( childId == wxACC_SELF )
|
|
{
|
|
*strValue = _( "TrackView" );
|
|
}
|
|
else
|
|
{
|
|
Track *t = FindTrack( childId );
|
|
|
|
if( t == NULL )
|
|
{
|
|
return wxACC_FAIL;
|
|
}
|
|
else
|
|
{
|
|
*strValue = t->GetName();
|
|
if( *strValue == t->GetDefaultName() )
|
|
{
|
|
strValue->Printf(_("Track %d"), TrackNum( t ) );
|
|
}
|
|
|
|
// LLL: Remove these during "refactor"
|
|
if( t->GetMute() )
|
|
{
|
|
strValue->Append( _( " Mute On" ) );
|
|
}
|
|
|
|
if( t->GetSolo() )
|
|
{
|
|
strValue->Append( _( " Solo On" ) );
|
|
}
|
|
if( t->GetSelected() )
|
|
{
|
|
strValue->Append( _( " Select On" ) );
|
|
}
|
|
}
|
|
}
|
|
return wxACC_OK;
|
|
#endif
|
|
}
|
|
|
|
// Gets the window with the keyboard focus.
|
|
// If childId is 0 and child is NULL, no object in
|
|
// this subhierarchy has the focus.
|
|
// If this object has the focus, child should be 'this'.
|
|
wxAccStatus TrackPanelAx::GetFocus( int *childId, wxAccessible **child )
|
|
{
|
|
#if defined(__WXMSW__)
|
|
if( *childId == wxACC_SELF )
|
|
{
|
|
if( mFocusedTrack )
|
|
{
|
|
*child = this;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*child = NULL;
|
|
}
|
|
|
|
return wxACC_OK;
|
|
#endif
|
|
|
|
#if defined(__WXMAC__)
|
|
if( GetWindow() == wxWindow::FindFocus() )
|
|
{
|
|
if( mFocusedTrack )
|
|
{
|
|
*childId = TrackNum( mFocusedTrack );
|
|
}
|
|
else
|
|
{
|
|
*childId = wxACC_SELF;
|
|
}
|
|
|
|
return wxACC_OK;
|
|
}
|
|
|
|
return wxACC_NOT_IMPLEMENTED;
|
|
#endif
|
|
}
|
|
|
|
#endif // wxUSE_ACCESSIBILITY
|
|
|
|
// Indentation settings for Vim and Emacs.
|
|
// Please do not modify past this point.
|
|
//
|
|
// Local Variables:
|
|
// c-basic-offset: 3
|
|
// indent-tabs-mode: nil
|
|
// End:
|