// Created: 20.08.00
// RCS-ID: $Id$
// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "univscrolbar.h"
#endif
#include "wx/univ/renderer.h"
#include "wx/univ/inphand.h"
#include "wx/univ/theme.h"
+#include "wx/log.h"
#define WXDEBUG_SCROLLBAR
#undef WXDEBUG_SCROLLBAR
#endif // !__WXDEBUG__
+#if defined(WXDEBUG_SCROLLBAR) && defined(__WXMSW__) && !defined(__WXMICROWIN__)
+#include "wx/msw/private.h"
+#endif
+
// ----------------------------------------------------------------------------
// wxScrollBarTimer: this class is used to repeatedly scroll the scrollbar
// when the mouse is help pressed on the arrow or on the bar. It generates the
IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
BEGIN_EVENT_TABLE(wxScrollBar, wxScrollBarBase)
- EVT_IDLE(wxScrollBar::OnIdle)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
m_elementsState[n] = 0;
}
- m_dirty = FALSE;
+ m_dirty = false;
}
bool wxScrollBar::Create(wxWindow *parent,
// the scrollbars never have the border
style &= ~wxBORDER_MASK;
- if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) )
- return FALSE;
+ if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
+ return false;
SetBestSize(size);
CreateInputHandler(wxINP_HANDLER_SCROLLBAR);
- return TRUE;
+ return true;
}
wxScrollBar::~wxScrollBar()
{
}
+// ----------------------------------------------------------------------------
+// misc accessors
+// ----------------------------------------------------------------------------
+
+bool wxScrollBar::IsStandalone() const
+{
+ wxWindow *parent = GetParent();
+ if ( !parent )
+ {
+ return true;
+ }
+
+ return (parent->GetScrollbar(wxHORIZONTAL) != this) &&
+ (parent->GetScrollbar(wxVERTICAL) != this);
+}
+
+bool wxScrollBar::AcceptsFocus() const
+{
+ // the window scrollbars never accept focus
+ return wxScrollBarBase::AcceptsFocus() && IsStandalone();
+}
+
// ----------------------------------------------------------------------------
// scrollbar API
// ----------------------------------------------------------------------------
m_elementsState[Element_Thumb] |= wxCONTROL_DIRTY;
m_elementsState[m_thumbPos > m_thumbPosOld
? Element_Bar_1 : Element_Bar_2] |= wxCONTROL_DIRTY;
- m_dirty = TRUE;
+ m_dirty = true;
}
int wxScrollBar::GetThumbPosition() const
int range, int pageSize,
bool refresh)
{
- // we only refresh everythign when the range changes, thumb position
+ // we only refresh everything when the range changes, thumb position
// changes are handled in OnIdle
bool needsRefresh = (range != m_range) ||
(thumbSize != m_thumbSize) ||
// drawing
// ----------------------------------------------------------------------------
-void wxScrollBar::OnIdle(wxIdleEvent& event)
+void wxScrollBar::OnInternalIdle()
+{
+ UpdateThumb();
+ wxControl::OnInternalIdle();
+}
+
+void wxScrollBar::UpdateThumb()
{
if ( m_dirty )
{
}
#ifdef WXDEBUG_SCROLLBAR
- static bool s_refreshDebug = FALSE;
+ static bool s_refreshDebug = false;
if ( s_refreshDebug )
{
wxClientDC dc(this);
}
#endif // WXDEBUG_SCROLLBAR
- Refresh(TRUE, &rect);
+ Refresh(false, &rect);
}
m_elementsState[n] &= ~wxCONTROL_DIRTY;
}
}
- m_dirty = FALSE;
+ m_dirty = false;
}
-
- event.Skip();
}
void wxScrollBar::DoDraw(wxControlRenderer *renderer)
renderer->DrawScrollbar(this, m_thumbPosOld);
// clear all dirty flags
- m_dirty = FALSE;
+ m_dirty = false;
m_thumbPosOld = -1;
}
{
m_elementsState[which] = flags | wxCONTROL_DIRTY;
- m_dirty = TRUE;
+ m_dirty = true;
}
}
{
int thumbOld = m_thumbPos;
- bool notify = FALSE; // send an event about the change?
+ bool notify = false; // send an event about the change?
wxEventType scrollType;
{
DoSetThumb(numArg);
+ // VS: we have to force redraw here, otherwise the thumb will lack
+ // behind mouse cursor
+ UpdateThumb();
+
scrollType = wxEVT_SCROLLWIN_THUMBTRACK;
}
else if ( action == wxACTION_SCROLL_LINE_UP )
else if ( action == wxACTION_SCROLL_THUMB_RELEASE )
{
// always notify about this
- notify = TRUE;
+ notify = true;
scrollType = wxEVT_SCROLLWIN_THUMBRELEASE;
}
else
bool changed = m_thumbPos != thumbOld;
if ( notify || changed )
{
+ if ( IsStandalone() )
+ {
+ // we should generate EVT_SCROLL events for the standalone
+ // scrollbars and not the EVT_SCROLLWIN ones
+ //
+ // NB: we assume that scrollbar events are sequentially numbered
+ // but this should be ok as other code relies on this as well
+ scrollType += wxEVT_SCROLL_TOP - wxEVT_SCROLLWIN_TOP;
+ }
+
wxScrollWinEvent event(scrollType, m_thumbPos,
IsVertical() ? wxVERTICAL : wxHORIZONTAL);
event.SetEventObject(this);
GetParent()->GetEventHandler()->ProcessEvent(event);
}
- return TRUE;
+ return true;
}
void wxScrollBar::ScrollToStart()
bool wxScrollBar::ScrollLines(int nLines)
{
DoSetThumb(m_thumbPos + nLines);
- return TRUE;
+ return true;
}
bool wxScrollBar::ScrollPages(int nPages)
{
DoSetThumb(m_thumbPos + nPages*m_pageSize);
- return TRUE;
+ return true;
}
// ============================================================================
int oldThumbPos = scrollbar->GetThumbPosition();
scrollbar->PerformAction(action);
if ( scrollbar->GetThumbPosition() != oldThumbPos )
- return TRUE;
+ return true;
// we scrolled till the end
m_timerScroll->Stop();
- return FALSE;
+ return false;
}
void wxStdScrollBarInputHandler::StopScrolling(wxScrollBar *control)
}
// unpress the arrow and highlight the current element
- Press(control, FALSE);
+ Press(control, false);
}
wxCoord
scrollbar->PerformAction(wxACTION_SCROLL_THUMB_MOVE, thumbPos);
}
-bool wxStdScrollBarInputHandler::HandleKey(wxControl *control,
+bool wxStdScrollBarInputHandler::HandleKey(wxInputConsumer *consumer,
const wxKeyEvent& event,
bool pressed)
{
case WXK_LEFT: action = wxACTION_SCROLL_LINE_UP; break;
case WXK_HOME: action = wxACTION_SCROLL_START; break;
case WXK_END: action = wxACTION_SCROLL_END; break;
+ case WXK_PAGEUP:
case WXK_PRIOR: action = wxACTION_SCROLL_PAGE_UP; break;
+ case WXK_PAGEDOWN:
case WXK_NEXT: action = wxACTION_SCROLL_PAGE_DOWN; break;
}
- if ( !!action )
+ if ( !action.IsEmpty() )
{
- control->PerformAction(action);
+ consumer->PerformAction(action);
- return TRUE;
+ return true;
}
}
- return wxStdInputHandler::HandleKey(control, event, pressed);
+ return wxStdInputHandler::HandleKey(consumer, event, pressed);
}
-bool wxStdScrollBarInputHandler::HandleMouse(wxControl *control,
+bool wxStdScrollBarInputHandler::HandleMouse(wxInputConsumer *consumer,
const wxMouseEvent& event)
{
// is this a click event from an acceptable button?
if ( (btn != -1) && IsAllowedButton(btn) )
{
// determine which part of the window mouse is in
- wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar);
+ wxScrollBar *scrollbar = wxStaticCast(consumer->GetInputWindow(), wxScrollBar);
wxHitTest ht = m_renderer->HitTestScrollbar
(
scrollbar,
if ( !m_winCapture )
{
m_btnCapture = btn;
- m_winCapture = control;
+ m_winCapture = consumer->GetInputWindow();
m_winCapture->CaptureMouse();
// generate the command
- bool hasAction = TRUE;
+ bool hasAction = true;
wxControlAction action;
switch ( ht )
{
break;
case wxHT_SCROLLBAR_THUMB:
- control->PerformAction(wxACTION_SCROLL_THUMB_DRAG);
+ consumer->PerformAction(wxACTION_SCROLL_THUMB_DRAG);
m_ofsMouse = GetMouseCoord(scrollbar, event) -
m_renderer->ScrollbarToPixel(scrollbar);
// fall through: there is no immediate action
default:
- hasAction = FALSE;
+ hasAction = false;
}
// remove highlighting
- Highlight(scrollbar, FALSE);
+ Highlight(scrollbar, false);
m_htLast = ht;
// and press the arrow or highlight thumb now instead
if ( m_htLast == wxHT_SCROLLBAR_THUMB )
- Highlight(scrollbar, TRUE);
+ Highlight(scrollbar, true);
else
- Press(scrollbar, TRUE);
+ Press(scrollbar, true);
// start dragging
if ( hasAction )
}
m_htLast = ht;
- Highlight(scrollbar, TRUE);
+ Highlight(scrollbar, true);
}
else
{
}
}
- return wxStdInputHandler::HandleMouse(control, event);
+ return wxStdInputHandler::HandleMouse(consumer, event);
}
-bool wxStdScrollBarInputHandler::HandleMouseMove(wxControl *control,
+bool wxStdScrollBarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
const wxMouseEvent& event)
{
- wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar);
+ wxScrollBar *scrollbar = wxStaticCast(consumer->GetInputWindow(), wxScrollBar);
if ( m_winCapture )
{
- if ( (m_htLast == wxHT_SCROLLBAR_THUMB) && event.Moving() )
+ if ( (m_htLast == wxHT_SCROLLBAR_THUMB) && event.Dragging() )
{
// make the thumb follow the mouse by keeping the same offset
// between the mouse position and the top/left of the thumb
HandleThumbMove(scrollbar, event);
- return TRUE;
+ return true;
}
// no other changes are possible while the mouse is captured
- return FALSE;
+ return false;
}
bool isArrow = scrollbar->GetArrows().HandleMouseMove(event);
- if ( event.Moving() )
+ if ( event.Dragging() )
{
wxHitTest ht = m_renderer->HitTestScrollbar
(
if ( ht == m_htLast )
{
// nothing changed
- return FALSE;
+ return false;
}
#ifdef DEBUG_MOUSE
wxLogDebug("Scrollbar::OnMouseMove: ht = %d", ht);
#endif // DEBUG_MOUSE
- Highlight(scrollbar, FALSE);
+ Highlight(scrollbar, false);
m_htLast = ht;
if ( !isArrow )
- Highlight(scrollbar, TRUE);
+ Highlight(scrollbar, true);
//else: already done by wxScrollArrows::HandleMouseMove
}
else if ( event.Leaving() )
{
if ( !isArrow )
- Highlight(scrollbar, FALSE);
+ Highlight(scrollbar, false);
m_htLast = wxHT_NOWHERE;
}
else // event.Entering()
{
// we don't process this event
- return FALSE;
+ return false;
}
// we did something
- return TRUE;
+ return true;
}
#endif // wxUSE_SCROLLBAR
wxScrollTimer::wxScrollTimer()
{
- m_skipNext = FALSE;
+ m_skipNext = false;
}
void wxScrollTimer::StartAutoScroll()
// there is an initial delay before the scrollbar starts scrolling -
// implement it by ignoring the first timer expiration and only start
// scrolling from the second one
- m_skipNext = TRUE;
+ m_skipNext = true;
Start(200); // FIXME: hardcoded delay
}
Stop();
Start(50); // FIXME: hardcoded delay
- m_skipNext = FALSE;
+ m_skipNext = false;
}
else
{