mirror of
https://github.com/cookiengineer/audacity
synced 2026-03-24 23:25:53 +01:00
Locate and position the current Audacity source code, and clear a variety of old junk out of the way into junk-branches
This commit is contained in:
614
src/widgets/AButton.cpp
Normal file
614
src/widgets/AButton.cpp
Normal file
@@ -0,0 +1,614 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
AButton.cpp
|
||||
|
||||
Dominic Mazzoni
|
||||
|
||||
*******************************************************************//**
|
||||
|
||||
\class AButton
|
||||
\brief A wxButton with mouse-over behaviour.
|
||||
|
||||
AButton is a custom button class for Audacity. The main feature it
|
||||
supports that a wxButton does not is mouseovers.
|
||||
|
||||
It uses an image for all of its states: up, over, down, and
|
||||
disabled, allowing any sort of customization you want. Currently
|
||||
it does not support transparency effects, so the image musts be
|
||||
rectangular and opaque.
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#include "../Audacity.h"
|
||||
|
||||
#include "AButton.h"
|
||||
#include "../AColor.h"
|
||||
|
||||
#include <wx/dcclient.h>
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/dcbuffer.h>
|
||||
#include <wx/image.h>
|
||||
|
||||
//This is needed for tooltips
|
||||
#include "../Project.h"
|
||||
#include <wx/tooltip.h>
|
||||
|
||||
BEGIN_EVENT_TABLE(AButton, wxWindow)
|
||||
EVT_MOUSE_EVENTS(AButton::OnMouseEvent)
|
||||
EVT_MOUSE_CAPTURE_LOST(AButton::OnCaptureLost)
|
||||
EVT_KEY_DOWN(AButton::OnKeyDown)
|
||||
EVT_SET_FOCUS(AButton::OnSetFocus)
|
||||
EVT_KILL_FOCUS(AButton::OnKillFocus)
|
||||
EVT_PAINT(AButton::OnPaint)
|
||||
EVT_SIZE(AButton::OnSize)
|
||||
EVT_ERASE_BACKGROUND(AButton::OnErase)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
AButton::AButton(wxWindow * parent,
|
||||
wxWindowID id,
|
||||
const wxPoint & pos,
|
||||
const wxSize & size,
|
||||
wxImage up,
|
||||
wxImage over,
|
||||
wxImage down,
|
||||
wxImage dis,
|
||||
bool toggle):
|
||||
wxWindow()
|
||||
{
|
||||
Init(parent, id, pos, size,
|
||||
ImageRoll(up), ImageRoll(over),
|
||||
ImageRoll(down), ImageRoll(dis),
|
||||
toggle);
|
||||
}
|
||||
|
||||
AButton::AButton(wxWindow * parent,
|
||||
wxWindowID id,
|
||||
const wxPoint & pos,
|
||||
const wxSize & size,
|
||||
ImageRoll up,
|
||||
ImageRoll over,
|
||||
ImageRoll down,
|
||||
ImageRoll dis,
|
||||
bool toggle):
|
||||
wxWindow()
|
||||
{
|
||||
Init(parent, id, pos, size,
|
||||
up, over, down, dis,
|
||||
toggle);
|
||||
}
|
||||
|
||||
AButton::~AButton()
|
||||
{
|
||||
}
|
||||
|
||||
void AButton::Init(wxWindow * parent,
|
||||
wxWindowID id,
|
||||
const wxPoint & pos,
|
||||
const wxSize & size,
|
||||
ImageRoll up,
|
||||
ImageRoll over,
|
||||
ImageRoll down,
|
||||
ImageRoll dis,
|
||||
bool toggle)
|
||||
{
|
||||
Create(parent, id, pos, size);
|
||||
|
||||
mWasShiftDown = false;
|
||||
mWasControlDown = false;
|
||||
mButtonIsDown = false;
|
||||
mIsClicking = false;
|
||||
mEnabled = true;
|
||||
mCursorIsInWindow = false;
|
||||
mToggle = toggle;
|
||||
mUseDisabledAsDownHiliteImage = false;
|
||||
|
||||
mImage[0] = up;
|
||||
mImage[1] = over;
|
||||
mImage[2] = down;
|
||||
mImage[3] = dis;
|
||||
|
||||
mAlternate = false;
|
||||
|
||||
mButtonIsFocused = false;
|
||||
mFocusRect = GetRect().Deflate( 3, 3 );
|
||||
|
||||
SetSizeHints(mImage[0].GetMinSize(),
|
||||
mImage[0].GetMaxSize());
|
||||
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
SetName( wxT("") );
|
||||
SetAccessible(new AButtonAx(this));
|
||||
#endif
|
||||
}
|
||||
|
||||
void AButton::UseDisabledAsDownHiliteImage(bool flag)
|
||||
{
|
||||
mUseDisabledAsDownHiliteImage = flag;
|
||||
}
|
||||
|
||||
void AButton::SetAlternateImages(wxImage up,
|
||||
wxImage over,
|
||||
wxImage down,
|
||||
wxImage dis)
|
||||
{
|
||||
mAltImage[0] = ImageRoll(up);
|
||||
mAltImage[1] = ImageRoll(over);
|
||||
mAltImage[2] = ImageRoll(down);
|
||||
mAltImage[3] = ImageRoll(dis);
|
||||
}
|
||||
|
||||
void AButton::SetAlternateImages(ImageRoll up,
|
||||
ImageRoll over,
|
||||
ImageRoll down,
|
||||
ImageRoll dis)
|
||||
{
|
||||
mAltImage[0] = up;
|
||||
mAltImage[1] = over;
|
||||
mAltImage[2] = down;
|
||||
mAltImage[3] = dis;
|
||||
}
|
||||
|
||||
void AButton::SetAlternate(bool useAlternateImages)
|
||||
{
|
||||
mAlternate = useAlternateImages;
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
void AButton::SetFocusRect(wxRect & r)
|
||||
{
|
||||
mFocusRect = r;
|
||||
}
|
||||
|
||||
AButton::AButtonState AButton::GetState()
|
||||
{
|
||||
AButtonState state;
|
||||
|
||||
if (!mEnabled && (!mToggle || !mButtonIsDown))
|
||||
return AButtonDis;
|
||||
|
||||
if (mCursorIsInWindow) {
|
||||
if (mToggle) {
|
||||
if (mIsClicking) {
|
||||
state = mButtonIsDown ? AButtonUp : AButtonDown;
|
||||
if (mUseDisabledAsDownHiliteImage) {
|
||||
state = mButtonIsDown ? AButtonOver : AButtonDis;
|
||||
}
|
||||
}
|
||||
else {
|
||||
state = mButtonIsDown ? AButtonDown : AButtonOver;
|
||||
if (mUseDisabledAsDownHiliteImage) {
|
||||
state = mButtonIsDown ? AButtonDis : AButtonOver;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mIsClicking) {
|
||||
state = mButtonIsDown ? AButtonOver : AButtonDown;
|
||||
}
|
||||
else {
|
||||
state = mButtonIsDown ? AButtonDown : AButtonUp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mToggle) {
|
||||
state = mButtonIsDown ? AButtonDown : AButtonUp;
|
||||
}
|
||||
else {
|
||||
state = mButtonIsDown ? AButtonDown : AButtonUp;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void AButton::OnPaint(wxPaintEvent & event)
|
||||
{
|
||||
wxBufferedPaintDC dc(this);
|
||||
|
||||
AButtonState buttonState = GetState();
|
||||
|
||||
if (mAlternate)
|
||||
mAltImage[buttonState].Draw(dc, GetClientRect());
|
||||
else
|
||||
mImage[buttonState].Draw(dc, GetClientRect());
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
if( mButtonIsFocused )
|
||||
{
|
||||
AColor::DrawFocus( dc, mFocusRect );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AButton::OnErase(wxEraseEvent & event)
|
||||
{
|
||||
// Ignore it to prevent flashing
|
||||
}
|
||||
|
||||
void AButton::OnSize(wxSizeEvent & event)
|
||||
{
|
||||
mFocusRect = GetRect().Deflate( 3, 3 );
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
bool AButton::HasAlternateImages()
|
||||
{
|
||||
return (mAltImage[0].Ok() &&
|
||||
mAltImage[1].Ok() &&
|
||||
mAltImage[2].Ok() &&
|
||||
mAltImage[3].Ok());
|
||||
}
|
||||
|
||||
void AButton::OnMouseEvent(wxMouseEvent & event)
|
||||
{
|
||||
wxSize clientSize = GetClientSize();
|
||||
AButtonState prevState = GetState();
|
||||
|
||||
if (event.Entering())
|
||||
mCursorIsInWindow = true;
|
||||
else if (event.Leaving())
|
||||
mCursorIsInWindow = false;
|
||||
else
|
||||
mCursorIsInWindow =
|
||||
(event.m_x >= 0 && event.m_y >= 0 &&
|
||||
event.m_x < clientSize.x && event.m_y < clientSize.y);
|
||||
|
||||
if (HasAlternateImages() && !mButtonIsDown)
|
||||
mAlternate = event.ShiftDown();
|
||||
|
||||
if (mEnabled && event.IsButton()) {
|
||||
if (event.ButtonIsDown(wxMOUSE_BTN_ANY)) {
|
||||
mIsClicking = true;
|
||||
CaptureMouse();
|
||||
}
|
||||
else if (mIsClicking) {
|
||||
mIsClicking = false;
|
||||
|
||||
if (HasCapture())
|
||||
ReleaseMouse();
|
||||
|
||||
if (mCursorIsInWindow && (mToggle || !mButtonIsDown)) {
|
||||
if (mToggle)
|
||||
mButtonIsDown = !mButtonIsDown;
|
||||
else
|
||||
mButtonIsDown = true;
|
||||
|
||||
mWasShiftDown = event.ShiftDown();
|
||||
mWasControlDown = event.ControlDown();
|
||||
|
||||
Click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only redraw and change tooltips if the state has changed.
|
||||
AButtonState newState = GetState();
|
||||
|
||||
if (newState != prevState) {
|
||||
Refresh(false);
|
||||
|
||||
if (mCursorIsInWindow) {
|
||||
#if wxUSE_TOOLTIPS // Not available in wxX11
|
||||
// Display the tooltip in the status bar
|
||||
wxToolTip * pTip = this->GetToolTip();
|
||||
if( pTip ) {
|
||||
wxString tipText = pTip->GetTip();
|
||||
if (!mEnabled)
|
||||
tipText += _(" (disabled)");
|
||||
GetActiveProject()->TP_DisplayStatusMessage(tipText);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
GetActiveProject()->TP_DisplayStatusMessage(wxT(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AButton::OnCaptureLost(wxMouseCaptureLostEvent & event)
|
||||
{
|
||||
wxMouseEvent e(wxEVT_LEFT_UP);
|
||||
e.m_x = -1;
|
||||
e.m_y = -1;
|
||||
OnMouseEvent(e);
|
||||
}
|
||||
|
||||
void AButton::OnKeyDown(wxKeyEvent & event)
|
||||
{
|
||||
switch( event.GetKeyCode() )
|
||||
{
|
||||
case WXK_RETURN:
|
||||
mWasShiftDown = event.ShiftDown();
|
||||
mWasControlDown = event.ControlDown();
|
||||
Click();
|
||||
break;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void AButton::OnSetFocus(wxFocusEvent & event)
|
||||
{
|
||||
mButtonIsFocused = true;
|
||||
Refresh( false );
|
||||
}
|
||||
|
||||
void AButton::OnKillFocus(wxFocusEvent & event)
|
||||
{
|
||||
mButtonIsFocused = false;
|
||||
Refresh( false );
|
||||
}
|
||||
|
||||
bool AButton::WasShiftDown()
|
||||
{
|
||||
return mWasShiftDown;
|
||||
}
|
||||
|
||||
bool AButton::WasControlDown()
|
||||
{
|
||||
return mWasControlDown;
|
||||
}
|
||||
|
||||
void AButton::Enable()
|
||||
{
|
||||
mEnabled = true;
|
||||
this->Refresh(false);
|
||||
}
|
||||
|
||||
void AButton::Disable()
|
||||
{
|
||||
mEnabled = false;
|
||||
if (GetCapture()==this)
|
||||
ReleaseMouse();
|
||||
this->Refresh(false);
|
||||
}
|
||||
|
||||
void AButton::PushDown()
|
||||
{
|
||||
mButtonIsDown = true;
|
||||
this->Refresh(false);
|
||||
}
|
||||
|
||||
void AButton::PopUp()
|
||||
{
|
||||
mButtonIsDown = false;
|
||||
|
||||
if (GetCapture()==this)
|
||||
ReleaseMouse();
|
||||
|
||||
this->Refresh(false);
|
||||
}
|
||||
|
||||
void AButton::Click()
|
||||
{
|
||||
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
|
||||
event.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
void AButton::SetShift(bool shift)
|
||||
{
|
||||
mWasShiftDown = shift;
|
||||
}
|
||||
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
|
||||
AButtonAx::AButtonAx( wxWindow *window ):
|
||||
wxWindowAccessible( window )
|
||||
{
|
||||
}
|
||||
|
||||
AButtonAx::~AButtonAx()
|
||||
{
|
||||
}
|
||||
|
||||
// Performs the default action. childId is 0 (the action for this object)
|
||||
// or > 0 (the action for a child).
|
||||
// Return wxACC_NOT_SUPPORTED if there is no default action for this
|
||||
// window (e.g. an edit control).
|
||||
wxAccStatus AButtonAx::DoDefaultAction(int childId)
|
||||
{
|
||||
AButton *ab = wxDynamicCast( GetWindow(), AButton );
|
||||
|
||||
if(ab && ab->IsEnabled()) {
|
||||
ab->mWasShiftDown = false;
|
||||
ab->mWasControlDown = false;
|
||||
ab->Click();
|
||||
}
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// Retrieves the address of an IDispatch interface for the specified child.
|
||||
// All objects must support this property.
|
||||
wxAccStatus AButtonAx::GetChild( int childId, wxAccessible** child )
|
||||
{
|
||||
if( childId == wxACC_SELF )
|
||||
{
|
||||
*child = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*child = NULL;
|
||||
}
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// Gets the number of children.
|
||||
wxAccStatus AButtonAx::GetChildCount(int* childCount)
|
||||
{
|
||||
*childCount = 0;
|
||||
|
||||
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 AButtonAx::GetDefaultAction(int childId, wxString* actionName)
|
||||
{
|
||||
*actionName = _( "Press" );
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// Returns the description for this object or a child.
|
||||
wxAccStatus AButtonAx::GetDescription( int childId, wxString *description )
|
||||
{
|
||||
description->Clear();
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// 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 AButtonAx::GetFocus(int* childId, wxAccessible** child)
|
||||
{
|
||||
*childId = 0;
|
||||
*child = this;
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// Returns help text for this object or a child, similar to tooltip text.
|
||||
wxAccStatus AButtonAx::GetHelpText( int childId, wxString *helpText )
|
||||
{
|
||||
#if wxUSE_TOOLTIPS // Not available in wxX11
|
||||
AButton *ab = wxDynamicCast( GetWindow(), AButton );
|
||||
|
||||
wxToolTip *pTip = ab->GetToolTip();
|
||||
if( pTip )
|
||||
{
|
||||
*helpText = pTip->GetTip();
|
||||
}
|
||||
|
||||
return wxACC_OK;
|
||||
#else
|
||||
helpText->Clear();
|
||||
|
||||
return wxACC_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the keyboard shortcut for this object or child.
|
||||
// Return e.g. ALT+K
|
||||
wxAccStatus AButtonAx::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 AButtonAx::GetLocation( wxRect& rect, int elementId )
|
||||
{
|
||||
AButton *ab = wxDynamicCast( GetWindow(), AButton );
|
||||
|
||||
rect = ab->GetRect();
|
||||
rect.SetPosition( ab->GetParent()->ClientToScreen( rect.GetPosition() ) );
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// Gets the name of the specified object.
|
||||
wxAccStatus AButtonAx::GetName(int childId, wxString* name)
|
||||
{
|
||||
AButton *ab = wxDynamicCast( GetWindow(), AButton );
|
||||
|
||||
*name = ab->GetName();
|
||||
if( name->IsEmpty() )
|
||||
{
|
||||
*name = ab->GetLabel();
|
||||
}
|
||||
|
||||
if( name->IsEmpty() )
|
||||
{
|
||||
*name = _("Button");
|
||||
}
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// Returns a role constant.
|
||||
wxAccStatus AButtonAx::GetRole(int childId, wxAccRole* role)
|
||||
{
|
||||
*role = wxROLE_SYSTEM_PUSHBUTTON;
|
||||
|
||||
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 AButtonAx::GetSelections( wxVariant *selections )
|
||||
{
|
||||
return wxACC_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Returns a state constant.
|
||||
wxAccStatus AButtonAx::GetState(int childId, long* state)
|
||||
{
|
||||
AButton *ab = wxDynamicCast( GetWindow(), AButton );
|
||||
|
||||
switch( ab->GetState() )
|
||||
{
|
||||
case AButton::AButtonDown:
|
||||
*state = wxACC_STATE_SYSTEM_PRESSED | wxACC_STATE_SYSTEM_FOCUSABLE;
|
||||
break;
|
||||
|
||||
case AButton::AButtonOver:
|
||||
*state = wxACC_STATE_SYSTEM_HOTTRACKED | wxACC_STATE_SYSTEM_FOCUSABLE;
|
||||
break;
|
||||
|
||||
case AButton::AButtonDis:
|
||||
*state = wxACC_STATE_SYSTEM_UNAVAILABLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
*state = wxACC_STATE_SYSTEM_FOCUSABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Do not use mButtonIsFocused is not set until after this method
|
||||
// is called.
|
||||
*state |= ( ab == wxWindow::FindFocus() ? wxACC_STATE_SYSTEM_FOCUSED : 0 );
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
|
||||
// Returns a localized string representing the value for the object
|
||||
// or child.
|
||||
wxAccStatus AButtonAx::GetValue(int childId, wxString* strValue)
|
||||
{
|
||||
return wxACC_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
||||
// version control system. Please do not modify past this point.
|
||||
//
|
||||
// Local Variables:
|
||||
// c-basic-offset: 3
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
//
|
||||
// vim: et sts=3 sw=3
|
||||
// arch-tag: c0be128d-3a41-4ff8-9dc5-2264a0439761
|
||||
|
||||
Reference in New Issue
Block a user