Files
wxWidgets/src/gtk1/scrolbar.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

366 lines
10 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/gtk1/scrolbar.cpp
// Purpose:
// Author: Robert Roebling
// Copyright: (c) 1998 Robert Roebling
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#if wxUSE_SCROLLBAR
#include "wx/scrolbar.h"
#ifndef WX_PRECOMP
#include "wx/utils.h"
#include "wx/math.h"
#endif
#include "wx/gtk1/private.h"
//-----------------------------------------------------------------------------
// idle system
//-----------------------------------------------------------------------------
extern void wxapp_install_idle_handler();
extern bool g_isIdle;
//-----------------------------------------------------------------------------
// data
//-----------------------------------------------------------------------------
extern bool g_blockEventsOnDrag;
static wxEventType g_currentUpDownEvent = wxEVT_NULL;
static const float sensitivity = 0.02;
//-----------------------------------------------------------------------------
// "value_changed"
//-----------------------------------------------------------------------------
// FIXME: is GtkScrollType really passed to us as 2nd argument?
extern "C" {
static void gtk_scrollbar_callback( GtkAdjustment *adjust,
SCROLLBAR_CBACK_ARG
wxScrollBar *win )
{
if (g_isIdle) wxapp_install_idle_handler();
if (!win->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
float diff = adjust->value - win->m_oldPos;
if (fabs(diff) < sensitivity) return;
win->m_oldPos = adjust->value;
wxEventType command = GtkScrollTypeToWx(GET_SCROLL_TYPE(win->m_widget));
double dvalue = adjust->value;
int value = (int)(dvalue < 0 ? dvalue - 0.5 : dvalue + 0.5);
int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
// throw a LINEUP / LINEDOWN event if necessary
if (g_currentUpDownEvent != wxEVT_NULL)
{
wxScrollEvent event( g_currentUpDownEvent, win->GetId(), value, orient );
event.SetEventObject( win );
win->HandleWindowEvent( event );
}
// throw other event (wxEVT_SCROLL_THUMBTRACK)
wxScrollEvent event( command, win->GetId(), value, orient );
event.SetEventObject( win );
win->HandleWindowEvent( event );
/*
wxCommandEvent cevent( wxEVT_SCROLLBAR, win->GetId() );
cevent.SetEventObject( win );
win->ProcessEvent( cevent );
*/
}
}
//-----------------------------------------------------------------------------
// "button_press_event" from slider
//-----------------------------------------------------------------------------
extern "C" {
static gint gtk_scrollbar_button_press_callback( GtkRange *widget,
GdkEventButton *gdk_event,
wxScrollBar *win )
{
if (g_isIdle) wxapp_install_idle_handler();
// check if a LINEUP/LINEDOWN event must be thrown
// I suppose here the size of scrollbar top/bottom buttons is 16px height
if (gdk_event->type == GDK_BUTTON_PRESS && gdk_event->button == 1)
{
int scroll_height, mouse_pos;
// get the mouse position when the click is done
if (win->HasFlag(wxSB_VERTICAL))
{
scroll_height = GTK_WIDGET(widget)->allocation.height - 16;
mouse_pos = (int)gdk_event->y;
}
else
{
scroll_height = GTK_WIDGET(widget)->allocation.width - 16;
mouse_pos = (int)gdk_event->x;
}
// compare mouse position to scrollbar height
if (mouse_pos > scroll_height)
g_currentUpDownEvent = wxEVT_SCROLL_LINEDOWN;
else if (mouse_pos < 16)
g_currentUpDownEvent = wxEVT_SCROLL_LINEUP;
}
// There is no slider field any more
win->m_isScrolling = (gdk_event->window == widget->slider);
return FALSE;
}
}
//-----------------------------------------------------------------------------
// "button_release_event" from slider
//-----------------------------------------------------------------------------
extern "C" {
static gint
gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
GdkEventButton *WXUNUSED(gdk_event),
wxScrollBar *win )
{
if (g_isIdle)
wxapp_install_idle_handler();
if (win->m_isScrolling)
{
wxEventType command = wxEVT_SCROLL_THUMBRELEASE;
int value = (int)ceil(win->m_adjust->value);
int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
wxScrollEvent event( command, win->GetId(), value, orient );
event.SetEventObject( win );
win->HandleWindowEvent( event );
}
win->m_isScrolling = false;
// reset the LINEUP/LINEDOWN flag when the mouse button is released
g_currentUpDownEvent = wxEVT_NULL;
return FALSE;
}
}
//-----------------------------------------------------------------------------
// wxScrollBar
//-----------------------------------------------------------------------------
wxScrollBar::~wxScrollBar()
{
}
bool wxScrollBar::Create(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size,
long style, const wxValidator& validator, const wxString& name )
{
m_needParent = true;
m_acceptsFocus = true;
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, validator, name ))
{
wxFAIL_MSG( wxT("wxScrollBar creation failed") );
return false;
}
m_oldPos = 0.0;
if ((style & wxSB_VERTICAL) == wxSB_VERTICAL)
m_widget = gtk_vscrollbar_new( NULL );
else
m_widget = gtk_hscrollbar_new( NULL );
m_adjust = gtk_range_get_adjustment( GTK_RANGE(m_widget) );
gtk_signal_connect( GTK_OBJECT(m_adjust),
"value_changed",
(GtkSignalFunc) gtk_scrollbar_callback,
(gpointer) this );
gtk_signal_connect( GTK_OBJECT(m_widget),
"button_press_event",
(GtkSignalFunc)gtk_scrollbar_button_press_callback,
(gpointer) this );
gtk_signal_connect( GTK_OBJECT(m_widget),
"button_release_event",
(GtkSignalFunc)gtk_scrollbar_button_release_callback,
(gpointer) this );
m_parent->DoAddChild( this );
PostCreation(size);
return true;
}
int wxScrollBar::GetThumbPosition() const
{
double val = m_adjust->value;
return (int)(val < 0 ? val - 0.5 : val + 0.5);
}
int wxScrollBar::GetThumbSize() const
{
return (int)(m_adjust->page_size+0.5);
}
int wxScrollBar::GetPageSize() const
{
return (int)(m_adjust->page_increment+0.5);
}
int wxScrollBar::GetRange() const
{
return (int)(m_adjust->upper+0.5);
}
void wxScrollBar::SetThumbPosition( int viewStart )
{
if (m_isScrolling) return;
float fpos = (float)viewStart;
m_oldPos = fpos;
if (fabs(fpos-m_adjust->value) < 0.2) return;
m_adjust->value = fpos;
gtk_signal_disconnect_by_func( GTK_OBJECT(m_adjust),
(GtkSignalFunc) gtk_scrollbar_callback,
(gpointer) this );
gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" );
gtk_signal_connect( GTK_OBJECT(m_adjust),
"value_changed",
(GtkSignalFunc) gtk_scrollbar_callback,
(gpointer) this );
}
void wxScrollBar::SetScrollbar( int position, int thumbSize, int range, int pageSize,
bool WXUNUSED(refresh) )
{
float fpos = (float)position;
float frange = (float)range;
float fthumb = (float)thumbSize;
float fpage = (float)pageSize;
if ((fabs(frange-m_adjust->upper) < 0.2) &&
(fabs(fthumb-m_adjust->page_size) < 0.2) &&
(fabs(fpage-m_adjust->page_increment) < 0.2))
{
SetThumbPosition( position );
return;
}
m_oldPos = fpos;
m_adjust->lower = 0.0;
m_adjust->upper = frange;
m_adjust->value = fpos;
m_adjust->step_increment = 1.0;
m_adjust->page_increment = (float)(wxMax(fpage,0));
m_adjust->page_size = fthumb;
gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
}
/* Backward compatibility */
int wxScrollBar::GetValue() const
{
return GetThumbPosition();
}
void wxScrollBar::SetValue( int viewStart )
{
SetThumbPosition( viewStart );
}
void wxScrollBar::GetValues( int *viewStart, int *viewLength, int *objectLength, int *pageLength ) const
{
int pos = (int)(m_adjust->value+0.5);
int thumb = (int)(m_adjust->page_size+0.5);
int page = (int)(m_adjust->page_increment+0.5);
int range = (int)(m_adjust->upper+0.5);
*viewStart = pos;
*viewLength = range;
*objectLength = thumb;
*pageLength = page;
}
int wxScrollBar::GetViewLength() const
{
return (int)(m_adjust->upper+0.5);
}
int wxScrollBar::GetObjectLength() const
{
return (int)(m_adjust->page_size+0.5);
}
void wxScrollBar::SetPageSize( int pageLength )
{
int pos = (int)(m_adjust->value+0.5);
int thumb = (int)(m_adjust->page_size+0.5);
int range = (int)(m_adjust->upper+0.5);
SetScrollbar( pos, thumb, range, pageLength );
}
void wxScrollBar::SetObjectLength( int objectLength )
{
int pos = (int)(m_adjust->value+0.5);
int page = (int)(m_adjust->page_increment+0.5);
int range = (int)(m_adjust->upper+0.5);
SetScrollbar( pos, objectLength, range, page );
}
void wxScrollBar::SetViewLength( int viewLength )
{
int pos = (int)(m_adjust->value+0.5);
int thumb = (int)(m_adjust->page_size+0.5);
int page = (int)(m_adjust->page_increment+0.5);
SetScrollbar( pos, thumb, viewLength, page );
}
bool wxScrollBar::IsOwnGtkWindow( GdkWindow *window )
{
GtkRange *range = GTK_RANGE(m_widget);
return ( (window == GTK_WIDGET(range)->window)
|| (window == range->trough)
|| (window == range->slider)
|| (window == range->step_forw)
|| (window == range->step_back)
);
}
wxSize wxScrollBar::DoGetBestSize() const
{
return wxControl::DoGetBestSize();
}
// static
wxVisualAttributes
wxScrollBar::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
{
return GetDefaultAttributesFromGTKWidget(gtk_vscrollbar_new);
}
#endif // wxUSE_SCROLLBAR