Files
wxWidgets/src/univ/scrarrow.cpp
Vadim Zeitlin 442b35b53b changed copyright to SciTech one
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10795 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2001-07-02 19:42:27 +00:00

275 lines
7.8 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: src/univ/scrarrow.cpp
// Purpose: wxScrollArrows class implementation
// Author: Vadim Zeitlin
// Modified by:
// Created: 22.01.01
// RCS-ID: $Id$
// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "univscrarrow.h"
#endif
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#endif
#include "wx/univ/scrtimer.h"
#include "wx/univ/scrarrow.h"
#include "wx/univ/renderer.h"
#include "wx/univ/inphand.h"
#include "wx/univ/theme.h"
// ----------------------------------------------------------------------------
// wxScrollArrowCaptureData: contains the data used while the arrow is being
// pressed by the user
// ----------------------------------------------------------------------------
struct wxScrollArrowCaptureData
{
wxScrollArrowCaptureData()
{
m_arrowPressed = wxScrollArrows::Arrow_None;
m_window = NULL;
m_btnCapture = -1;
m_timerScroll = NULL;
}
~wxScrollArrowCaptureData()
{
if ( m_window )
m_window->ReleaseMouse();
delete m_timerScroll;
}
// the arrow being held pressed (may be Arrow_None)
wxScrollArrows::Arrow m_arrowPressed;
// the mouse button which started the capture (-1 if none)
int m_btnCapture;
// the window which has captured the mouse
wxWindow *m_window;
// the timer for generating the scroll events
wxScrollTimer *m_timerScroll;
};
// ----------------------------------------------------------------------------
// wxScrollArrowTimer: a wxScrollTimer which calls OnArrow()
// ----------------------------------------------------------------------------
class wxScrollArrowTimer : public wxScrollTimer
{
public:
wxScrollArrowTimer(wxControlWithArrows *control,
wxScrollArrows::Arrow arrow)
{
m_control = control;
m_arrow = arrow;
StartAutoScroll();
}
protected:
virtual bool DoNotify()
{
return m_control->OnArrow(m_arrow);
}
wxControlWithArrows *m_control;
wxScrollArrows::Arrow m_arrow;
};
// ============================================================================
// implementation of wxScrollArrows
// ============================================================================
// ----------------------------------------------------------------------------
// con/destruction
// ----------------------------------------------------------------------------
wxScrollArrows::wxScrollArrows(wxControlWithArrows *control)
{
m_control = control;
m_captureData = NULL;
}
wxScrollArrows::~wxScrollArrows()
{
// it should have been destroyed
wxASSERT_MSG( !m_captureData, _T("memory leak in wxScrollArrows") );
}
// ----------------------------------------------------------------------------
// drawing
// ----------------------------------------------------------------------------
void wxScrollArrows::DrawArrow(Arrow arrow,
wxDC& dc,
const wxRect& rect,
bool scrollbarLike) const
{
static const wxDirection arrowDirs[2][Arrow_Max] =
{
{ wxLEFT, wxRIGHT },
{ wxUP, wxDOWN }
};
void (wxRenderer::*pfn)(wxDC&, wxDirection, const wxRect&, int) =
scrollbarLike ? &wxRenderer::DrawScrollbarArrow
: &wxRenderer::DrawArrow;
(m_control->GetRenderer()->*pfn)
(
dc,
arrowDirs[m_control->IsVertical()][arrow],
rect,
m_control->GetArrowState(arrow)
);
}
// ----------------------------------------------------------------------------
// input handling
// ----------------------------------------------------------------------------
void wxScrollArrows::UpdateCurrentFlag(Arrow arrow, Arrow arrowCur) const
{
m_control->SetArrowFlag(arrow, wxCONTROL_CURRENT, arrow == arrowCur);
}
bool wxScrollArrows::HandleMouseMove(const wxMouseEvent& event) const
{
Arrow arrow;
if ( event.Leaving() )
{
// no arrow has mouse if it left the window completely
arrow = Arrow_None;
}
else // Moving() or Entering(), treat them the same here
{
arrow = m_control->HitTest(event.GetPosition());
}
if ( m_captureData )
{
// the mouse is captured, we may want to pause scrolling if it goes
// outside the arrow or to resume it if we had paused it before
wxTimer *timer = m_captureData->m_timerScroll;
if ( !timer->IsRunning() )
{
// timer is paused
if ( arrow == m_captureData->m_arrowPressed )
{
// resume now
m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, TRUE);
timer->Start();
return TRUE;
}
}
else if ( 1 ) //FIXME: m_control->ShouldPauseScrolling() )
{
// we may want to stop it
if ( arrow != m_captureData->m_arrowPressed )
{
// stop as the mouse left the arrow
m_control->SetArrowFlag(m_captureData->m_arrowPressed,
wxCONTROL_PRESSED, FALSE);
timer->Stop();
return TRUE;
}
}
return FALSE;
}
// reset the wxCONTROL_CURRENT flag for the arrows which don't have the
// mouse and set it for the one which has
UpdateCurrentFlag(Arrow_First, arrow);
UpdateCurrentFlag(Arrow_Second, arrow);
// return TRUE if it was really an event for an arrow
return !event.Leaving() && arrow != Arrow_None;
}
bool wxScrollArrows::HandleMouse(const wxMouseEvent& event) const
{
int btn = event.GetButton();
if ( btn == -1 )
{
// we only care about button press/release events
return FALSE;
}
if ( event.ButtonDown() || event.ButtonDClick() )
{
if ( !m_captureData )
{
Arrow arrow = m_control->HitTest(event.GetPosition());
if ( arrow == Arrow_None )
{
// mouse pressed over something else
return FALSE;
}
if ( m_control->GetArrowState(arrow) & wxCONTROL_DISABLED )
{
// don't allow to press disabled arrows
return TRUE;
}
wxConstCast(this, wxScrollArrows)->m_captureData =
new wxScrollArrowCaptureData;
m_captureData->m_arrowPressed = arrow;
m_captureData->m_btnCapture = btn;
m_captureData->m_window = m_control->GetWindow();
m_captureData->m_window->CaptureMouse();
// start scrolling
m_captureData->m_timerScroll =
new wxScrollArrowTimer(m_control, arrow);
m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, TRUE);
}
//else: mouse already captured, nothing to do
}
// release mouse if the *same* button went up
else if ( m_captureData && (btn == m_captureData->m_btnCapture) )
{
Arrow arrow = m_captureData->m_arrowPressed;
delete m_captureData;
wxConstCast(this, wxScrollArrows)->m_captureData = NULL;
m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, FALSE);
}
else
{
// we don't process this
return FALSE;
}
return TRUE;
}