implement wxGTK wxBitmapButton in terms of wxButton

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61081 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-06-16 19:31:50 +00:00
parent b4a4eafbcc
commit c37dd6dad7
4 changed files with 68 additions and 291 deletions

View File

@@ -18,10 +18,10 @@
#include "wx/button.h" #include "wx/button.h"
// FIXME: right now only wxMSW implements bitmap support in wxButton // FIXME: right now only wxMSW and wxGTK implement bitmap support in wxButton
// itself, this shouldn't be used for the other platforms neither // itself, this shouldn't be used for the other platforms neither
// when all of them do it // when all of them do it
#ifdef __WXMSW__ #if defined(__WXMSW__) || defined(__WXGTK__)
#define wxHAS_BUTTON_BITMAP #define wxHAS_BUTTON_BITMAP
#endif #endif

View File

@@ -14,22 +14,20 @@
// wxBitmapButton // wxBitmapButton
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxBitmapButton: public wxBitmapButtonBase class WXDLLIMPEXP_CORE wxBitmapButton : public wxBitmapButtonBase
{ {
public: public:
wxBitmapButton() { Init(); } wxBitmapButton() { }
wxBitmapButton(wxWindow *parent, wxBitmapButton(wxWindow *parent,
wxWindowID id, wxWindowID id,
const wxBitmap& bitmap, const wxBitmap& bitmap,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = wxBU_AUTODRAW, long style = 0,
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxButtonNameStr) const wxString& name = wxButtonNameStr)
{ {
Init();
Create(parent, id, bitmap, pos, size, style, validator, name); Create(parent, id, bitmap, pos, size, style, validator, name);
} }
@@ -38,40 +36,21 @@ public:
const wxBitmap& bitmap, const wxBitmap& bitmap,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = wxBU_AUTODRAW, long style = 0,
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxButtonNameStr); const wxString& name = wxButtonNameStr)
{
if ( !wxBitmapButtonBase::Create(parent, id, "",
pos, size, style,
validator, name) )
return false;
void SetLabel( const wxString &label ); SetBitmapLabel(bitmap);
virtual void SetLabel( const wxBitmap& bitmap ) { SetBitmapLabel(bitmap); }
virtual bool Enable(bool enable = true); return true;
}
// implementation
// --------------
void GTKMouseEnters();
void GTKMouseLeaves();
void GTKPressed();
void GTKReleased();
protected:
virtual void OnSetBitmap();
virtual wxSize DoGetBestSize() const;
void DoApplyWidgetStyle(GtkRcStyle *style);
void Init();
private:
void OnFocusChange(wxFocusEvent& event);
// true iff mouse hovers over the button
bool m_mouseHovers;
// true iff the button is in pressed state
bool m_isPressed;
DECLARE_DYNAMIC_CLASS(wxBitmapButton) DECLARE_DYNAMIC_CLASS(wxBitmapButton)
DECLARE_EVENT_TABLE()
}; };
#endif // _WX_GTK_BMPBUTTON_H_ #endif // _WX_GTK_BMPBUTTON_H_

View File

@@ -14,252 +14,6 @@
#include "wx/bmpbuttn.h" #include "wx/bmpbuttn.h"
#include <gtk/gtk.h>
//-----------------------------------------------------------------------------
// classes
//-----------------------------------------------------------------------------
class wxBitmapButton;
//-----------------------------------------------------------------------------
// data
//-----------------------------------------------------------------------------
extern bool g_blockEventsOnDrag;
//-----------------------------------------------------------------------------
// "clicked"
//-----------------------------------------------------------------------------
extern "C" {
static void gtk_bmpbutton_clicked_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
{
if (!button->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, button->GetId());
event.SetEventObject(button);
button->HandleWindowEvent(event);
}
}
//-----------------------------------------------------------------------------
// "enter"
//-----------------------------------------------------------------------------
extern "C" {
static void gtk_bmpbutton_enter_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
{
if (!button->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
button->GTKMouseEnters();
}
}
//-----------------------------------------------------------------------------
// "leave"
//-----------------------------------------------------------------------------
extern "C" {
static void gtk_bmpbutton_leave_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
{
if (!button->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
button->GTKMouseLeaves();
}
}
//-----------------------------------------------------------------------------
// "pressed"
//-----------------------------------------------------------------------------
extern "C" {
static void gtk_bmpbutton_press_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
{
if (!button->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
button->GTKPressed();
}
}
//-----------------------------------------------------------------------------
// "released"
//-----------------------------------------------------------------------------
extern "C" {
static void gtk_bmpbutton_release_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
{
if (!button->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
button->GTKReleased();
}
}
//-----------------------------------------------------------------------------
// wxBitmapButton
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton,wxButton) IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton,wxButton)
BEGIN_EVENT_TABLE(wxBitmapButton, wxButton)
EVT_SET_FOCUS(wxBitmapButton::OnFocusChange)
EVT_KILL_FOCUS(wxBitmapButton::OnFocusChange)
END_EVENT_TABLE()
void wxBitmapButton::Init()
{
m_mouseHovers =
m_isPressed = false;
}
bool wxBitmapButton::Create( wxWindow *parent,
wxWindowID id,
const wxBitmap& bitmap,
const wxPoint& pos,
const wxSize& size,
long style,
const wxValidator& validator,
const wxString &name )
{
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, validator, name ))
{
wxFAIL_MSG( wxT("wxBitmapButton creation failed") );
return false;
}
m_bitmaps[State_Normal] = bitmap;
m_widget = gtk_button_new();
g_object_ref(m_widget);
if (style & wxNO_BORDER)
gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
if (bitmap.IsOk())
{
OnSetBitmap();
}
g_signal_connect_after (m_widget, "clicked",
G_CALLBACK (gtk_bmpbutton_clicked_callback),
this);
g_signal_connect (m_widget, "enter",
G_CALLBACK (gtk_bmpbutton_enter_callback), this);
g_signal_connect (m_widget, "leave",
G_CALLBACK (gtk_bmpbutton_leave_callback), this);
g_signal_connect (m_widget, "pressed",
G_CALLBACK (gtk_bmpbutton_press_callback), this);
g_signal_connect (m_widget, "released",
G_CALLBACK (gtk_bmpbutton_release_callback), this);
m_parent->DoAddChild( this );
PostCreation(size);
return true;
}
void wxBitmapButton::SetLabel( const wxString &label )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid button") );
wxControl::SetLabel( label );
}
void wxBitmapButton::DoApplyWidgetStyle(GtkRcStyle *style)
{
if (!GTK_BIN(m_widget)->child)
return;
wxButton::DoApplyWidgetStyle(style);
}
void wxBitmapButton::OnSetBitmap()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid bitmap button") );
InvalidateBestSize();
wxBitmap the_one;
if (!IsThisEnabled())
the_one = GetBitmapDisabled();
else if (m_isPressed)
the_one = GetBitmapPressed();
else if (m_mouseHovers)
the_one = GetBitmapHover();
else if (HasFocus())
the_one = GetBitmapFocus();
if (!the_one.IsOk())
{
the_one = GetBitmapLabel();
if (!the_one.IsOk())
return;
}
GtkWidget* image = GTK_BIN(m_widget)->child;
if (image == NULL)
{
image = gtk_image_new();
gtk_widget_show(image);
gtk_container_add(GTK_CONTAINER(m_widget), image);
}
// always use pixbuf, because pixmap mask does not
// work with disabled images in some themes
gtk_image_set_from_pixbuf(GTK_IMAGE(image), the_one.GetPixbuf());
}
wxSize wxBitmapButton::DoGetBestSize() const
{
return wxControl::DoGetBestSize();
}
bool wxBitmapButton::Enable( bool enable )
{
if ( !wxWindow::Enable(enable) )
return false;
OnSetBitmap();
return true;
}
void wxBitmapButton::GTKMouseEnters()
{
m_mouseHovers = true;
OnSetBitmap();
}
void wxBitmapButton::GTKMouseLeaves()
{
m_mouseHovers = false;
OnSetBitmap();
}
void wxBitmapButton::GTKPressed()
{
m_isPressed = true;
OnSetBitmap();
}
void wxBitmapButton::GTKReleased()
{
m_isPressed = false;
OnSetBitmap();
}
void wxBitmapButton::OnFocusChange(wxFocusEvent& event)
{
event.Skip();
OnSetBitmap();
}
#endif // wxUSE_BMPBUTTON #endif // wxUSE_BMPBUTTON

View File

@@ -123,7 +123,23 @@ bool wxButton::Create(wxWindow *parent,
return false; return false;
} }
m_widget = gtk_button_new_with_mnemonic(""); // create either a standard button with text label (which may still contain
// an image under GTK+ 2.6+) or a bitmap-only button if we don't have any
// label
const bool useLabel = !label.empty() || wxIsStockID(id);
if ( useLabel )
{
m_widget = gtk_button_new_with_mnemonic("");
}
else // no label, suppose we will have a bitmap
{
m_widget = gtk_button_new();
GtkWidget *image = gtk_image_new();
gtk_widget_show(image);
gtk_container_add(GTK_CONTAINER(m_widget), image);
}
g_object_ref(m_widget); g_object_ref(m_widget);
float x_alignment = 0.5; float x_alignment = 0.5;
@@ -140,7 +156,8 @@ bool wxButton::Create(wxWindow *parent,
gtk_button_set_alignment(GTK_BUTTON(m_widget), x_alignment, y_alignment); gtk_button_set_alignment(GTK_BUTTON(m_widget), x_alignment, y_alignment);
SetLabel(label); if ( useLabel )
SetLabel(label);
if (style & wxNO_BORDER) if (style & wxNO_BORDER)
gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE ); gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
@@ -392,15 +409,35 @@ void wxButton::GTKDoShowBitmap(const wxBitmap& bitmap)
{ {
wxASSERT_MSG( bitmap.IsOk(), "invalid bitmap" ); wxASSERT_MSG( bitmap.IsOk(), "invalid bitmap" );
#ifdef __WXGTK26__ GtkWidget *image;
if ( !gtk_check_version(2,6,0) ) if ( GetLabel().empty() )
{ {
GtkWidget *image = gtk_button_get_image(GTK_BUTTON(m_widget)); image = GTK_BIN(m_widget)->child;
wxCHECK_RET( image, "must have image widget" );
gtk_image_set_from_pixbuf(GTK_IMAGE(image), bitmap.GetPixbuf());
} }
else // have both label and bitmap
{
#ifdef __WXGTK26__
if ( !gtk_check_version(2,6,0) )
{
image = gtk_button_get_image(GTK_BUTTON(m_widget));
}
else
#endif // __WXGTK26__ #endif // __WXGTK26__
{
// buttons with both label and bitmap are only supported with GTK+
// 2.6 so far
//
// it shouldn't be difficult to implement them ourselves for the
// previous GTK+ versions by stuffing a container with a label and
// an image inside GtkButton but there doesn't seem to be much
// point in doing this for ancient GTK+ versions
return;
}
}
wxCHECK_RET( image && GTK_IS_IMAGE(image), "must have image widget" );
gtk_image_set_from_pixbuf(GTK_IMAGE(image), bitmap.GetPixbuf());
} }
wxBitmap wxButton::DoGetBitmap(State which) const wxBitmap wxButton::DoGetBitmap(State which) const
@@ -413,10 +450,17 @@ void wxButton::DoSetBitmap(const wxBitmap& bitmap, State which)
switch ( which ) switch ( which )
{ {
case State_Normal: case State_Normal:
if ( GetLabel().empty() )
{
// we only have the bitmap in this button, never remove it but
// do invalidate the best size when the bitmap (and presumably
// its size) changes
InvalidateBestSize();
}
#ifdef __WXGTK26__ #ifdef __WXGTK26__
// normal image is special: setting it enables images for the button and // normal image is special: setting it enables images for the button and
// resetting it to nothing disables all of them // resetting it to nothing disables all of them
if ( !gtk_check_version(2,6,0) ) else if ( !gtk_check_version(2,6,0) )
{ {
GtkWidget *image = gtk_button_get_image(GTK_BUTTON(m_widget)); GtkWidget *image = gtk_button_get_image(GTK_BUTTON(m_widget));
if ( image && !bitmap.IsOk() ) if ( image && !bitmap.IsOk() )