blob: 0e6055b8efd5434bd776aaa23bd20c8b9d61797c [file] [log] [blame]
/*
* Copyright (C) 2009 Kevin Ollivier All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "scrollbar_render.h"
#include <wx/defs.h>
#include <wx/dc.h>
#include <wx/dcgraph.h>
#include <wx/renderer.h>
#include <wx/settings.h>
#include <wx/window.h>
#include <gtk/gtk.h>
#if wxCHECK_VERSION(2, 9, 0)
#include <wx/gtk/dc.h>
#else
#include "wx/gtk/win_gtk.h"
#endif
int wxStyleForPart(wxScrollbarPart part, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int flags)
{
int style = 0;
if (flags == wxCONTROL_DISABLED)
style = wxCONTROL_DISABLED;
else if (part == focusPart)
style = wxCONTROL_PRESSED;
else if (part == hoverPart)
style = wxCONTROL_CURRENT;
return style;
}
GtkWidget* GetButtonWidget()
{
static GtkWidget *s_button = NULL;
static GtkWidget *s_window = NULL;
if ( !s_button )
{
s_window = gtk_window_new( GTK_WINDOW_POPUP );
gtk_widget_realize( s_window );
s_button = gtk_button_new();
gtk_container_add( GTK_CONTAINER(s_window), s_button );
gtk_widget_realize( s_button );
}
return s_button;
}
GdkWindow* wxGetGdkWindowForDC(wxWindow* win, wxDC& dc)
{
GdkWindow* gdk_window = NULL;
#if wxCHECK_VERSION(2, 9, 0)
if ( dc.IsKindOf( CLASSINFO(wxGCDC) ) )
gdk_window = win->GTKGetDrawingWindow();
else
{
wxGTKDCImpl *impl = wxDynamicCast(dc.GetImpl(), wxGTKDCImpl);
if ( impl )
gdk_window = impl->GetGDKWindow();
}
#else // wx < 2.9
// The way to get a GdkWindow* from a wxWindow is to use
// GTK_PIZZA(win->m_wxwindow)->bin_window, but this approach
// won't work when drawing to a wxMemoryDC as it has its own
// GdkWindow* for its bitmap. wxWindowDC's GetGDKWindow() was
// designed to create a solution for all DCs, but we can't
// implement it with wxGCDC since it doesn't retain its wxWindow.
// So, to work around this, we use GetGDKWindow whenever possible
// and use bin_window for wxGCDC.
#if wxUSE_GRAPHICS_CONTEXT
if ( dc.IsKindOf( CLASSINFO(wxGCDC) ) )
gdk_window = GTK_PIZZA(win->m_wxwindow)->bin_window;
else
#endif
gdk_window = dc.GetGDKWindow();
wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
#endif // wx 2.9/2.8
return gdk_window;
}
void wxRenderer_DrawScrollbar(wxWindow* window, wxDC& dc, const wxRect& rect, wxOrientation orient,
int current, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int max, int step, int flags)
{
bool horiz = orient == wxHORIZONTAL;
wxColour scrollbar_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_SCROLLBAR);
dc.SetBrush(wxBrush(scrollbar_colour));
dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW)));
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
wxRendererNative& renderer = wxRendererNative::Get();
int x = rect.x;
int y = rect.y;
int buttonLength = 16;
renderer.DrawPushButton(window, dc, wxRect(x,y,buttonLength,buttonLength), wxStyleForPart(wxSCROLLPART_BACKBTNSTART, focusPart, hoverPart, flags));
GtkWidget* button = GetButtonWidget();
GdkWindow* gdk_window = wxGetGdkWindowForDC(window, dc);
GtkArrowType arrowType = GTK_ARROW_UP;
if (horiz)
arrowType = GTK_ARROW_LEFT;
gtk_paint_arrow( button->style, gdk_window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, button, "arrow", arrowType, false, x + 4, y + 4, 8, 8);
wxRect buttonRect = rect;
int physicalLength = horiz ? rect.width : rect.height;
physicalLength -= buttonLength*2;
int thumbStart = 0;
int thumbLength = 0;
calcThumbStartAndLength(physicalLength, max, current, step, &thumbStart, &thumbLength);
if (horiz) {
buttonRect.x = x + thumbStart + buttonLength;
buttonRect.y = y;
buttonRect.width = thumbLength;
} else {
buttonRect.x = x;
buttonRect.y = y + thumbStart + buttonLength;
buttonRect.height = thumbLength;
}
renderer.DrawPushButton(window, dc, buttonRect, wxStyleForPart(wxSCROLLPART_THUMB, focusPart, hoverPart, flags));
if (horiz)
x += rect.width - buttonLength;
else
y += rect.height - buttonLength;
renderer.DrawPushButton(window, dc, wxRect(x,y,buttonLength,buttonLength), wxStyleForPart(wxSCROLLPART_FWDBTNEND, focusPart, hoverPart, flags));
if (horiz)
arrowType = GTK_ARROW_RIGHT;
else
arrowType = GTK_ARROW_DOWN;
gtk_paint_arrow( button->style, gdk_window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, button, "arrow", arrowType, false, x + 4, y + 4, 8, 8);
}