wxScrollBar for wxGTK done

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8175 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-08-24 20:28:33 +00:00
parent 89196a1dab
commit a360b8503e
15 changed files with 276 additions and 38 deletions

View File

@@ -20,6 +20,7 @@
class WXDLLEXPORT wxControlRenderer;
class WXDLLEXPORT wxInputHandler;
class WXDLLEXPORT wxRenderer;
// ----------------------------------------------------------------------------
// constants
@@ -143,6 +144,10 @@ public:
const wxEvent& event);
protected:
// returns the (low level) renderer to use for drawing the control by
// querying the current theme
wxRenderer *GetRenderer() const;
// create the event translator object for this control: the base class
// action creates the default one which doesn't do anything
virtual wxInputHandler *CreateInputHandler() const;

View File

@@ -19,6 +19,9 @@
#include "wx/control.h" // for wxControlAction(s)
class WXDLLEXPORT wxRenderer;
class WXDLLEXPORT wxScrollBar;
// ----------------------------------------------------------------------------
// wxInputHandler: maps the events to the actions
// ----------------------------------------------------------------------------
@@ -124,6 +127,8 @@ public:
const wxMouseEvent& event);
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
virtual ~wxStdScrollBarInputHandler();
protected:
// the methods which must be overridden in the derived class
@@ -159,6 +164,10 @@ protected:
// the renderer (we use it only for hit testing)
wxRenderer *m_renderer;
// the timer for generating scroll events when the mouse stays pressed on
// a scrollbar
class wxScrollBarTimer *m_timerScroll;
};
#endif // _WX_UNIV_INPHAND_H_

View File

@@ -134,9 +134,15 @@ public:
// ---------------------
// returns one of wxHT_SCROLLBAR_XXX constants
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt) const = 0;
// translate the scrollbar position (in logical units) into physical
// coordinate (in pixels) and the other way round
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar) = 0;
virtual int PixelToScrollbar(const wxScrollBar *scrollbar,
wxCoord coord) = 0;
// virtual dtor for any base class
virtual ~wxRenderer();
@@ -144,9 +150,16 @@ protected:
// standard scrollbar hit testing: this assumes that it only has 2 arrows
// and a thumb, so the themes which have more complicated scrollbars (e.g.
// BeOS) can't use this method
static wxHitTest StandardHitTestScrollbar(wxScrollBar *scrollbar,
static wxHitTest StandardHitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt,
const wxSize& sizeArrow);
static wxCoord StandardScrollbarToPixel(const wxScrollBar *scrollbar,
const wxSize& sizeArrow);
static int StandardPixelToScrollbar(const wxScrollBar *scrollbar,
wxCoord coord,
const wxSize& sizeArrow);
static wxCoord StandardScrollBarSize(const wxScrollBar *scrollbar,
const wxSize& sizeArrow);
};
// ----------------------------------------------------------------------------
@@ -207,9 +220,14 @@ public:
virtual void AdjustSize(wxSize *size, const wxWindow *window)
{ m_renderer->AdjustSize(size, window); }
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt) const
{ return m_renderer->HitTestScrollbar(scrollbar, pt); }
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar)
{ return m_renderer->ScrollbarToPixel(scrollbar); }
virtual int PixelToScrollbar(const wxScrollBar *scrollbar,
wxCoord coord)
{ return m_renderer->PixelToScrollbar(scrollbar, coord); }
protected:
wxRenderer *m_renderer;
@@ -232,7 +250,7 @@ public:
void DrawButtonBorder();
void DrawFrame();
void DrawBackgroundBitmap();
void DrawScrollbar(wxScrollBar *scrollbar);
void DrawScrollbar(const wxScrollBar *scrollbar);
// accessors
wxRenderer *GetRenderer() const { return m_renderer; }

View File

@@ -52,7 +52,7 @@ public:
Element_Arrow_Line_2,
Element_Arrow_Page_1,
Element_Arrow_Page_2,
Element_Arrow_Thumb,
Element_Thumb,
Element_Bar_1,
Element_Bar_2,
Element_Max
@@ -117,6 +117,10 @@ protected:
void Init();
private:
// get the mouse coordinates in the scrollbar direction from a
// wxMouseEvent (the event *must* really be of this type!)
wxCoord GetMouseCoord(const wxEvent& event) const;
// total range of the scrollbar in logical units
int m_range;
@@ -132,6 +136,10 @@ private:
// the state of the sub elements
int m_elementsState[Element_Max];
// the offset of the top/left of the scrollbar relative to the mouse to
// keep during the thumb drag
int m_ofsMouse;
DECLARE_DYNAMIC_CLASS(wxScrollBar)
};

View File

@@ -118,7 +118,7 @@ bool MyUnivApp::OnInit()
// ----------------------------------------------------------------------------
MyUnivFrame::MyUnivFrame(const wxString& title)
: wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(600, 450))
: wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(600, 600))
{
#ifdef __WXMSW__
SetBackgroundColour(*wxLIGHT_GREY);
@@ -181,9 +181,9 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
new wxButton(this, Univ_Button2, _T("&And me"), wxPoint(100, 300));
wxScrollBar *sb;
sb = new wxScrollBar(this, -1, wxPoint(200, 300), wxSize(100, -1));
sb = new wxScrollBar(this, -1, wxPoint(200, 300), wxSize(300, -1));
sb->SetScrollbar(0, 10, 100, 10);
sb = new wxScrollBar(this, -1, wxPoint(200, 330), wxSize(-1, 50), wxSB_VERTICAL);
sb = new wxScrollBar(this, -1, wxPoint(200, 330), wxSize(-1, 150), wxSB_VERTICAL);
sb->SetScrollbar(50, 50, 100, 10);
}

View File

@@ -993,6 +993,7 @@ GUI_LOWLEVEL_OBJS = \
pen.o \
region.o \
settings.o \
timer.o \
utilsgtk.o \
win_gtk.o \
window.o
@@ -1018,6 +1019,7 @@ GUI_LOWLEVEL_DEPS = \
pen.d \
region.d \
settings.d \
timer.d \
utilsgtk.d \
win_gtk.d \
window.d

View File

@@ -1437,8 +1437,6 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
// the mouse changed window
g_captureWindowHasMouse = hasMouse;
printf("Generating mouse %s event.\n",
g_captureWindowHasMouse ? "enter" : "leave");
wxMouseEvent event(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW
: wxEVT_LEAVE_WINDOW);
InitMouseEvent(event, gdk_event);

View File

@@ -993,6 +993,7 @@ GUI_LOWLEVEL_OBJS = \
pen.o \
region.o \
settings.o \
timer.o \
utilsgtk.o \
win_gtk.o \
window.o
@@ -1018,6 +1019,7 @@ GUI_LOWLEVEL_DEPS = \
pen.d \
region.d \
settings.d \
timer.d \
utilsgtk.d \
win_gtk.d \
window.d

View File

@@ -1437,8 +1437,6 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
// the mouse changed window
g_captureWindowHasMouse = hasMouse;
printf("Generating mouse %s event.\n",
g_captureWindowHasMouse ? "enter" : "leave");
wxMouseEvent event(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW
: wxEVT_LEAVE_WINDOW);
InitMouseEvent(event, gdk_event);

View File

@@ -217,6 +217,11 @@ const wxBitmap& wxControl::GetBackgroundBitmap(int *alignment,
// painting
// ----------------------------------------------------------------------------
wxRenderer *wxControl::GetRenderer() const
{
return wxTheme::Get()->GetRenderer();
}
// the event handler executed when the window background must be painted
void wxControl::OnErase(wxEraseEvent& event)
{
@@ -235,7 +240,7 @@ void wxControl::OnPaint(wxPaintEvent& event)
{
// get the DC to use and create renderer on it
wxPaintDC dc(this);
wxControlRenderer renderer(this, dc, wxTheme::Get()->GetRenderer());
wxControlRenderer renderer(this, dc, GetRenderer());
// do draw the control!
DoDraw(&renderer);

View File

@@ -29,14 +29,73 @@
#endif
#ifndef WX_PRECOMP
#include "wx/timer.h"
#include "wx/button.h"
#include "wx/scrolbar.h"
#include "wx/univ/renderer.h"
#endif // WX_PRECOMP
#include "wx/univ/inphand.h"
// ----------------------------------------------------------------------------
// 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
// given scroll action command periodically.
// ----------------------------------------------------------------------------
class wxScrollBarTimer : public wxTimer
{
public:
wxScrollBarTimer(const wxControlAction& action,
const wxMouseEvent& event,
wxControl *control);
virtual void Notify();
private:
wxControlAction m_action;
wxMouseEvent m_event;
wxControl *m_control;
};
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxScrollBarTimer
// ----------------------------------------------------------------------------
wxScrollBarTimer::wxScrollBarTimer(const wxControlAction& action,
const wxMouseEvent& event,
wxControl *control)
: m_event(event)
{
m_action = action;
m_control = control;
// start scrolling immediately
Notify();
// and continue it later
Start(100); // FIXME make this delay configurable
}
void wxScrollBarTimer::Notify()
{
if ( m_control->PerformAction(m_action, m_event) )
{
// keep scrolling
m_control->Refresh();
}
else
{
// we scrolled till the end
Stop();
}
}
// ----------------------------------------------------------------------------
// wxInputHandler
// ----------------------------------------------------------------------------
@@ -163,6 +222,14 @@ wxStdScrollBarInputHandler::wxStdScrollBarInputHandler(wxRenderer *renderer,
m_renderer = renderer;
m_winCapture = NULL;
m_htLast = wxHT_NOWHERE;
m_timerScroll = NULL;
}
wxStdScrollBarInputHandler::~wxStdScrollBarInputHandler()
{
// normally, it's NULL by now but just in case the user somehow managed to
// keep the mouse captured until now...
delete m_timerScroll;
}
void wxStdScrollBarInputHandler::SetElementState(wxScrollBar *control,
@@ -266,22 +333,36 @@ wxControlActions wxStdScrollBarInputHandler::Map(wxControl *control,
action = wxACTION_SCROLL_PAGE_DOWN;
break;
case wxHT_SCROLLBAR_THUMB:
control->PerformAction(wxACTION_SCROLL_THUMB_DRAG, event);
// fall through: there is no immediate action
default:
hasAction = FALSE;
}
if ( hasAction )
{
control->PerformAction(action, event);
}
// remove highlighting and press the arrow instead
// remove highlighting
Highlight(scrollbar, FALSE);
m_htLast = ht;
// and press the arrow or highlight thumb now instead
if ( m_htLast == wxHT_SCROLLBAR_THUMB )
Highlight(scrollbar, TRUE);
else
Press(scrollbar, TRUE);
// start dragging
if ( hasAction )
{
m_timerScroll = new wxScrollBarTimer(action, event, control);
}
else // no (immediate) action
{
// highlighting still might have changed
control->Refresh();
}
}
//else: mouse already captured, nothing to do
}
// release mouse if the *same* button went up
@@ -289,10 +370,23 @@ wxControlActions wxStdScrollBarInputHandler::Map(wxControl *control,
{
if ( m_winCapture )
{
// return everything to the normal state
m_winCapture->ReleaseMouse();
m_winCapture = NULL;
m_btnCapture = -1;
if ( m_timerScroll )
{
delete m_timerScroll;
m_timerScroll = NULL;
}
// if we were dragging the thumb, send the last event
if ( m_htLast == wxHT_SCROLLBAR_THUMB )
{
control->PerformAction(wxACTION_SCROLL_THUMB_RELEASE, event);
}
// unpress the arrow and highlight the current element
Press(scrollbar, FALSE);
m_htLast = ht;
@@ -318,8 +412,14 @@ bool wxStdScrollBarInputHandler::OnMouseMove(wxControl *control,
{
if ( m_winCapture )
{
// everything is locked while the mouse is captured, so don't do
// anything
if ( (m_htLast == wxHT_SCROLLBAR_THUMB) && event.Moving() )
{
// drag the thumb so that it follows the mouse
if ( control->PerformAction(wxACTION_SCROLL_THUMB_MOVE, event) )
return TRUE;
}
// no other changes are possible while the mouse is captured
return FALSE;
}

View File

@@ -44,11 +44,54 @@
// ============================================================================
// ----------------------------------------------------------------------------
// wxRenderer
// wxRenderer: scrollbar geometry
// ----------------------------------------------------------------------------
/* static */
wxHitTest wxRenderer::StandardHitTestScrollbar(wxScrollBar *scrollbar,
wxCoord wxRenderer::StandardScrollBarSize(const wxScrollBar *scrollbar,
const wxSize& sizeArrowSB)
{
wxCoord sizeArrow, sizeTotal;
if ( scrollbar->GetWindowStyle() & wxVERTICAL )
{
sizeArrow = sizeArrowSB.y;
sizeTotal = scrollbar->GetSize().y;
}
else // horizontal
{
sizeArrow = sizeArrowSB.x;
sizeTotal = scrollbar->GetSize().x;
}
return sizeTotal - 2*sizeArrow;
}
/* static */
wxCoord wxRenderer::StandardScrollbarToPixel(const wxScrollBar *scrollbar,
const wxSize& sizeArrow)
{
int range = scrollbar->GetRange();
if ( !range )
{
// the only valid position anyhow
return 0;
}
return ( scrollbar->GetThumbPosition() *
StandardScrollBarSize(scrollbar, sizeArrow) ) / range;
}
/* static */
int wxRenderer::StandardPixelToScrollbar(const wxScrollBar *scrollbar,
wxCoord coord,
const wxSize& sizeArrow)
{
return ( coord * scrollbar->GetRange() )
/ StandardScrollBarSize(scrollbar, sizeArrow);
}
/* static */
wxHitTest wxRenderer::StandardHitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt,
const wxSize& sizeArrowSB)
{
@@ -242,7 +285,7 @@ void wxControlRenderer::DrawBackgroundBitmap()
m_dc.DrawBitmap(bmp, x, y);
}
void wxControlRenderer::DrawScrollbar(wxScrollBar *scrollbar)
void wxControlRenderer::DrawScrollbar(const wxScrollBar *scrollbar)
{
int thumbStart, thumbEnd;
int range = scrollbar->GetRange();

View File

@@ -180,10 +180,27 @@ void wxScrollBar::DoDraw(wxControlRenderer *renderer)
// input processing
// ----------------------------------------------------------------------------
wxCoord wxScrollBar::GetMouseCoord(const wxEvent& eventOrig) const
{
const wxMouseEvent& event = (const wxMouseEvent&)eventOrig;
wxPoint pt = event.GetPosition();
return GetWindowStyle() & wxVERTICAL ? pt.y : pt.x;
}
bool wxScrollBar::PerformAction(const wxControlAction& action,
const wxEvent& event)
{
if ( action == wxACTION_SCROLL_START )
int thumbOld = m_thumbPos;
// test for thumb move first as these events happen in quick succession
if ( action == wxACTION_SCROLL_THUMB_MOVE )
{
// make the thumb follow the mouse by keeping the same offset between
// the mouse position and the top/left of the thumb
int thumbPos = GetMouseCoord(event) - m_ofsMouse;
DoSetThumb(GetRenderer()->PixelToScrollbar(this, thumbPos));
}
else if ( action == wxACTION_SCROLL_START )
ScrollToStart();
else if ( action == wxACTION_SCROLL_END )
ScrollToEnd();
@@ -195,11 +212,18 @@ bool wxScrollBar::PerformAction(const wxControlAction& action,
ScrollPages(-1);
else if ( action == wxACTION_SCROLL_PAGE_DOWN )
ScrollPages(1);
else if ( action == wxACTION_SCROLL_THUMB_DRAG )
{
m_ofsMouse = GetMouseCoord(event) -
GetRenderer()->ScrollbarToPixel(this);
}
else if ( action == wxACTION_SCROLL_THUMB_RELEASE )
; // nothing special to do
else
return wxControl::PerformAction(action, event);
// scrollbar position changed - update
return TRUE;
// if scrollbar position changed - update
return m_thumbPos != thumbOld;
}
void wxScrollBar::ScrollToStart()

View File

@@ -90,8 +90,10 @@ public:
virtual void AdjustSize(wxSize *size, const wxWindow *window);
// hit testing for the input handlers
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt) const;
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar);
virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord);
protected:
// DrawBackground() helpers
@@ -773,9 +775,9 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
"\tthumb: 0x%04x\n"
"\tthumb from %d to %d",
orient == wxVERTICAL ? "vertical" : "horizontal",
flags[wxHT_SCROLLBAR_ARROW_LINE_1],
flags[wxHT_SCROLLBAR_ARROW_LINE_2],
flags[wxHT_SCROLLBAR_THUMB],
flags[wxScrollBar::Element_Arrow_Line_1],
flags[wxScrollBar::Element_Arrow_Line_2],
flags[wxScrollBar::Element_Thumb],
thumbPosStart, thumbPosEnd);
#endif // DEBUG_MOUSE
@@ -813,7 +815,7 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
for ( size_t nArrow = 0; nArrow < 2; nArrow++ )
{
DrawArrow(dc, arrowDir[nArrow], rectArrow[nArrow],
flags[wxHT_SCROLLBAR_ARROW_LINE_1 + nArrow]);
flags[wxScrollBar::Element_Arrow_Line_1 + nArrow]);
}
// and, finally, the thumb, if any
@@ -837,19 +839,30 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
// the thumb is never pressed never has focus border under GTK and the
// scrollbar background never changes at all
int flagsThumb = flags[wxHT_SCROLLBAR_THUMB] &
int flagsThumb = flags[wxScrollBar::Element_Thumb] &
~(wxCONTROL_PRESSED | wxCONTROL_FOCUSED);
DrawButtonBorder(dc, rectThumb, flagsThumb, &rectThumb);
DrawBackground(dc, rectThumb, flagsThumb);
}
}
wxHitTest wxGTKRenderer::HitTestScrollbar(wxScrollBar *scrollbar,
wxHitTest wxGTKRenderer::HitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt) const
{
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
}
wxCoord wxGTKRenderer::ScrollbarToPixel(const wxScrollBar *scrollbar)
{
return StandardScrollbarToPixel(scrollbar, m_sizeScrollbarArrow);
}
int wxGTKRenderer::PixelToScrollbar(const wxScrollBar *scrollbar,
wxCoord coord)
{
return StandardPixelToScrollbar(scrollbar, coord, m_sizeScrollbarArrow);
}
// ----------------------------------------------------------------------------
// size adjustments
// ----------------------------------------------------------------------------

View File

@@ -106,8 +106,10 @@ public:
virtual void AdjustSize(wxSize *size, const wxWindow *window);
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt) const;
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar);
virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord);
protected:
// DrawButtonBorder() helper
@@ -1049,12 +1051,23 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
}
}
wxHitTest wxWin32Renderer::HitTestScrollbar(wxScrollBar *scrollbar,
wxHitTest wxWin32Renderer::HitTestScrollbar(const wxScrollBar *scrollbar,
const wxPoint& pt) const
{
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
}
wxCoord wxWin32Renderer::ScrollbarToPixel(const wxScrollBar *scrollbar)
{
return StandardScrollbarToPixel(scrollbar, m_sizeScrollbarArrow);
}
int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar,
wxCoord coord)
{
return StandardPixelToScrollbar(scrollbar, coord, m_sizeScrollbarArrow);
}
// ----------------------------------------------------------------------------
// size adjustments
// ----------------------------------------------------------------------------