]> git.saurik.com Git - wxWidgets.git/blob - src/motif/bmpbuttn.cpp
patch applied with thanks, fixes #13865
[wxWidgets.git] / src / motif / bmpbuttn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/bmpbuttn.cpp
3 // Purpose: wxBitmapButton
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #include "wx/bmpbuttn.h"
16
17 #ifdef __VMS__
18 #pragma message disable nosimpint
19 #endif
20 #include <Xm/PushBG.h>
21 #include <Xm/PushB.h>
22 #ifdef __VMS__
23 #pragma message enable nosimpint
24 #endif
25
26 #include "wx/motif/private.h"
27
28 // Implemented in button.cpp
29 void wxButtonCallback (Widget w, XtPointer clientData, XtPointer ptr);
30
31 // Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap );
32
33 wxBitmapButton::wxBitmapButton()
34 {
35 m_marginX = m_marginY = wxDEFAULT_BUTTON_MARGIN;
36 m_insensPixmap = (WXPixmap) 0;
37 }
38
39 bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id,
40 const wxBitmap& bitmap,
41 const wxPoint& pos,
42 const wxSize& size, long style,
43 const wxValidator& validator,
44 const wxString& name)
45 {
46 if( !CreateControl( parent, id, pos, size, style, validator, name ) )
47 return false;
48 PreCreation();
49
50 m_bitmaps[State_Normal] =
51 m_bitmapsOriginal[State_Normal] = bitmap;
52 m_bitmaps[State_Pressed] =
53 m_bitmapsOriginal[State_Pressed] = bitmap;
54
55 Widget parentWidget = (Widget) parent->GetClientWidget();
56
57 /*
58 * Patch Note (important)
59 * There is no major reason to put a defaultButtonThickness here.
60 * Not requesting it give the ability to put wxButton with a spacing
61 * as small as requested. However, if some button become a DefaultButton,
62 * other buttons are no more aligned -- This is why we set
63 * defaultButtonThickness of ALL buttons belonging to the same wxPanel,
64 * in the ::SetDefaultButton method.
65 */
66 Widget buttonWidget = XtVaCreateManagedWidget ("button",
67
68 // Gadget causes problems for default button operation.
69 #if wxUSE_GADGETS
70 xmPushButtonGadgetClass, parentWidget,
71 #else
72 xmPushButtonWidgetClass, parentWidget,
73 #endif
74 // See comment for wxButton::SetDefault
75 // XmNdefaultButtonShadowThickness, 1,
76 XmNrecomputeSize, False,
77 NULL);
78
79 m_mainWidget = (WXWidget) buttonWidget;
80
81 XtAddCallback (buttonWidget,
82 XmNactivateCallback, (XtCallbackProc) wxButtonCallback,
83 (XtPointer) this);
84
85 wxSize best = GetBitmapLabel().IsOk() ? GetBestSize() : wxSize(30, 30);
86 if( size.x != -1 ) best.x = size.x;
87 if( size.y != -1 ) best.y = size.y;
88
89 PostCreation();
90 OnSetBitmap();
91
92 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
93 pos.x, pos.y, best.x, best.y);
94
95 return true;
96 }
97
98 wxBitmapButton::~wxBitmapButton()
99 {
100 SetBitmapLabel(wxNullBitmap);
101
102 if (m_insensPixmap)
103 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) GetXDisplay()),
104 (Pixmap) m_insensPixmap);
105 }
106
107 void wxBitmapButton::DoSetBitmap(const wxBitmap& bitmap, State which)
108 {
109 m_bitmapsOriginal[which] = bitmap;
110
111 wxBitmapButtonBase::DoSetBitmap(bitmap, which);
112 }
113
114 void wxBitmapButton::OnSetBitmap()
115 {
116 wxBitmapButtonBase::OnSetBitmap();
117
118 if ( m_bitmapsOriginal[State_Normal].IsOk() )
119 {
120 Pixmap pixmap = 0;
121 Pixmap insensPixmap = 0;
122 Pixmap armPixmap = 0;
123
124 // Must re-make the bitmap to have its transparent areas drawn
125 // in the current widget background colour.
126 if ( m_bitmapsOriginal[State_Normal].GetMask() )
127 {
128 WXPixel backgroundPixel;
129 XtVaGetValues((Widget) m_mainWidget,
130 XmNbackground, &backgroundPixel,
131 NULL);
132
133 wxColour col;
134 col.SetPixel(backgroundPixel);
135
136 wxBitmap newBitmap =
137 wxCreateMaskedBitmap(m_bitmapsOriginal[State_Normal], col);
138 m_bitmaps[State_Normal] = newBitmap;
139 m_bitmapCache.SetBitmap( m_bitmaps[State_Normal] );
140
141 pixmap = (Pixmap) m_bitmaps[State_Normal].GetDrawable();
142 }
143 else
144 {
145 m_bitmapCache.SetBitmap( m_bitmaps[State_Normal] );
146 pixmap = (Pixmap) m_bitmapCache.GetLabelPixmap(m_mainWidget);
147 }
148
149 if (m_bitmapsOriginal[State_Disabled].IsOk())
150 {
151 if (m_bitmapsOriginal[State_Disabled].GetMask())
152 {
153 WXPixel backgroundPixel;
154 XtVaGetValues((Widget) m_mainWidget,
155 XmNbackground, &backgroundPixel,
156 NULL);
157
158 wxColour col;
159 col.SetPixel(backgroundPixel);
160
161 wxBitmap newBitmap =
162 wxCreateMaskedBitmap(m_bitmapsOriginal[State_Disabled], col);
163 m_bitmaps[State_Disabled] = newBitmap;
164
165 insensPixmap = (Pixmap) m_bitmaps[State_Disabled].GetDrawable();
166 }
167 else
168 insensPixmap = (Pixmap) m_bitmapCache.GetInsensPixmap(m_mainWidget);
169 }
170 else
171 insensPixmap = (Pixmap) m_bitmapCache.GetInsensPixmap(m_mainWidget);
172
173 // Now make the bitmap representing the armed state
174 if (m_bitmapsOriginal[State_Pressed].IsOk())
175 {
176 if (m_bitmapsOriginal[State_Pressed].GetMask())
177 {
178 WXPixel backgroundPixel;
179 XtVaGetValues((Widget) m_mainWidget,
180 XmNarmColor, &backgroundPixel,
181 NULL);
182
183 wxColour col;
184 col.SetPixel(backgroundPixel);
185
186 wxBitmap newBitmap =
187 wxCreateMaskedBitmap(m_bitmapsOriginal[State_Pressed], col);
188 m_bitmaps[State_Pressed] = newBitmap;
189
190 armPixmap = (Pixmap) m_bitmaps[State_Pressed].GetDrawable();
191 }
192 else
193 armPixmap = (Pixmap) m_bitmapCache.GetArmPixmap(m_mainWidget);
194 }
195 else
196 armPixmap = (Pixmap) m_bitmapCache.GetArmPixmap(m_mainWidget);
197
198 XtVaSetValues ((Widget) m_mainWidget,
199 XmNlabelPixmap, pixmap,
200 XmNlabelInsensitivePixmap, insensPixmap,
201 XmNarmPixmap, armPixmap,
202 XmNlabelType, XmPIXMAP,
203 NULL);
204 }
205 else
206 {
207 // Null bitmap: must not use current pixmap
208 // since it is no longer valid.
209 XtVaSetValues ((Widget) m_mainWidget,
210 XmNlabelType, XmSTRING,
211 XmNlabelPixmap, XmUNSPECIFIED_PIXMAP,
212 XmNlabelInsensitivePixmap, XmUNSPECIFIED_PIXMAP,
213 XmNarmPixmap, XmUNSPECIFIED_PIXMAP,
214 NULL);
215 }
216 }
217
218 void wxBitmapButton::ChangeBackgroundColour()
219 {
220 wxDoChangeBackgroundColour(m_mainWidget, m_backgroundColour, true);
221
222 // Must reset the bitmaps since the colours have changed.
223 OnSetBitmap();
224 }
225
226 wxSize wxBitmapButton::DoGetBestSize() const
227 {
228 wxSize ret( 30,30 );
229
230 if (GetBitmapLabel().IsOk())
231 {
232 int border = HasFlag(wxNO_BORDER) ? 4 : 10;
233 ret.x += border;
234 ret.y += border;
235
236 ret += GetBitmapLabel().GetSize();
237 }
238
239 return ret;
240 }