Use the wxBitmap implementation from wxX11
[wxWidgets.git] / src / motif / bmpbuttn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #ifdef __GNUG__
13 #pragma implementation "bmpbuttn.h"
14 #endif
15
16 #ifdef __VMS
17 #define XtScreen XTSCREEN
18 #endif
19
20 #include "wx/defs.h"
21
22 #include "wx/bmpbuttn.h"
23
24 #ifdef __VMS__
25 #pragma message disable nosimpint
26 #endif
27 #include <Xm/PushBG.h>
28 #include <Xm/PushB.h>
29 #ifdef __VMS__
30 #pragma message enable nosimpint
31 #endif
32
33 #include "wx/motif/private.h"
34
35 // Implemented in button.cpp
36 void wxButtonCallback (Widget w, XtPointer clientData, XtPointer ptr);
37
38 // Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap );
39
40 IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
41
42 wxBitmapButton::wxBitmapButton()
43 {
44 m_marginX = m_marginY = wxDEFAULT_BUTTON_MARGIN;
45 m_insensPixmap = (WXPixmap) 0;
46 }
47
48 bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id,
49 const wxBitmap& bitmap,
50 const wxPoint& pos,
51 const wxSize& size, long style,
52 const wxValidator& validator,
53 const wxString& name)
54 {
55 if( !CreateControl( parent, id, pos, size, style, validator, name ) )
56 return false;
57
58 m_bmpNormal = m_bmpNormalOriginal = bitmap;
59 m_bmpSelected = m_bmpSelectedOriginal = bitmap;
60
61 /*
62 int x = pos.x;
63 int y = pos.y;
64 int width = size.x;
65 int height = size.y;
66 */
67
68 Widget parentWidget = (Widget) parent->GetClientWidget();
69
70 /*
71 * Patch Note (important)
72 * There is no major reason to put a defaultButtonThickness here.
73 * Not requesting it give the ability to put wxButton with a spacing
74 * as small as requested. However, if some button become a DefaultButton,
75 * other buttons are no more aligned -- This is why we set
76 * defaultButtonThickness of ALL buttons belonging to the same wxPanel,
77 * in the ::SetDefaultButton method.
78 */
79 Widget buttonWidget = XtVaCreateManagedWidget ("button",
80
81 // Gadget causes problems for default button operation.
82 #if wxUSE_GADGETS
83 xmPushButtonGadgetClass, parentWidget,
84 #else
85 xmPushButtonWidgetClass, parentWidget,
86 #endif
87 // See comment for wxButton::SetDefault
88 // XmNdefaultButtonShadowThickness, 1,
89 XmNrecomputeSize, False,
90 NULL);
91
92 m_mainWidget = (WXWidget) buttonWidget;
93
94 ChangeFont(FALSE);
95
96 ChangeBackgroundColour ();
97
98 DoSetBitmap();
99
100 XtAddCallback (buttonWidget,
101 XmNactivateCallback, (XtCallbackProc) wxButtonCallback,
102 (XtPointer) this);
103
104 SetCanAddEventHandler(TRUE);
105
106 wxSize best = m_bmpNormal.Ok() ? GetBestSize() : wxSize(30, 30);
107 if( size.x != -1 ) best.x = size.x;
108 if( size.y != -1 ) best.y = size.y;
109
110 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
111 pos.x, pos.y, best.x, best.y);
112
113 return TRUE;
114 }
115
116 wxBitmapButton::~wxBitmapButton()
117 {
118 SetBitmapLabel(wxNullBitmap);
119
120 if (m_insensPixmap)
121 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) GetXDisplay()),
122 (Pixmap) m_insensPixmap);
123 }
124
125 void wxBitmapButton::SetBitmapLabel(const wxBitmap& bitmap)
126 {
127 m_bmpNormalOriginal = bitmap;
128 m_bmpNormal = bitmap;
129
130 DoSetBitmap();
131 }
132
133 void wxBitmapButton::SetBitmapSelected(const wxBitmap& sel)
134 {
135 m_bmpSelected = sel;
136 m_bmpSelectedOriginal = sel;
137
138 DoSetBitmap();
139 };
140
141 void wxBitmapButton::SetBitmapFocus(const wxBitmap& focus)
142 {
143 m_bmpFocus = focus;
144 // Not used in Motif
145 };
146
147 void wxBitmapButton::SetBitmapDisabled(const wxBitmap& disabled)
148 {
149 m_bmpDisabled = disabled;
150 m_bmpDisabledOriginal = disabled;
151
152 DoSetBitmap();
153 };
154
155 void wxBitmapButton::DoSetBitmap()
156 {
157 if (m_bmpNormalOriginal.Ok())
158 {
159 Pixmap pixmap = 0;
160 Pixmap insensPixmap = 0;
161 Pixmap armPixmap = 0;
162
163 // Must re-make the bitmap to have its transparent areas drawn
164 // in the current widget background colour.
165 if (m_bmpNormalOriginal.GetMask())
166 {
167 int backgroundPixel;
168 XtVaGetValues((Widget) m_mainWidget,
169 XmNbackground, &backgroundPixel,
170 NULL);
171
172 wxColour col;
173 col.SetPixel(backgroundPixel);
174
175 wxBitmap newBitmap =
176 wxCreateMaskedBitmap(m_bmpNormalOriginal, col);
177 m_bmpNormal = newBitmap;
178 m_bitmapCache.SetBitmap( m_bmpNormal );
179
180 pixmap = (Pixmap) m_bmpNormal.GetDrawable();
181 }
182 else
183 {
184 m_bitmapCache.SetBitmap( m_bmpNormal );
185 pixmap = (Pixmap) m_bitmapCache.GetLabelPixmap(m_mainWidget);
186 }
187
188 if (m_bmpDisabledOriginal.Ok())
189 {
190 if (m_bmpDisabledOriginal.GetMask())
191 {
192 int backgroundPixel;
193 XtVaGetValues((Widget) m_mainWidget,
194 XmNbackground, &backgroundPixel,
195 NULL);
196
197 wxColour col;
198 col.SetPixel(backgroundPixel);
199
200 wxBitmap newBitmap =
201 wxCreateMaskedBitmap(m_bmpDisabledOriginal, col);
202 m_bmpDisabled = newBitmap;
203
204 insensPixmap = (Pixmap) m_bmpDisabled.GetDrawable();
205 }
206 else
207 insensPixmap = (Pixmap) m_bitmapCache.GetInsensPixmap(m_mainWidget);
208 }
209 else
210 insensPixmap = (Pixmap) m_bitmapCache.GetInsensPixmap(m_mainWidget);
211
212 // Now make the bitmap representing the armed state
213 if (m_bmpSelectedOriginal.Ok())
214 {
215 if (m_bmpSelectedOriginal.GetMask())
216 {
217 int backgroundPixel;
218 XtVaGetValues((Widget) m_mainWidget,
219 XmNarmColor, &backgroundPixel,
220 NULL);
221
222 wxColour col;
223 col.SetPixel(backgroundPixel);
224
225 wxBitmap newBitmap =
226 wxCreateMaskedBitmap(m_bmpSelectedOriginal, col);
227 m_bmpSelected = newBitmap;
228
229 armPixmap = (Pixmap) m_bmpSelected.GetDrawable();
230 }
231 else
232 armPixmap = (Pixmap) m_bitmapCache.GetArmPixmap(m_mainWidget);
233 }
234 else
235 armPixmap = (Pixmap) m_bitmapCache.GetArmPixmap(m_mainWidget);
236
237 #if 0
238 // <- the Get...Pixmap()-functions return the same pixmap!
239 if (insensPixmap == pixmap)
240 {
241 insensPixmap =
242 XCreateInsensitivePixmap(DisplayOfScreen(XtScreen((Widget) m_mainWidget)), pixmap);
243 m_insensPixmap = (WXPixmap) insensPixmap;
244 }
245 #endif
246
247 XtVaSetValues ((Widget) m_mainWidget,
248 XmNlabelPixmap, pixmap,
249 XmNlabelInsensitivePixmap, insensPixmap,
250 XmNarmPixmap, armPixmap,
251 XmNlabelType, XmPIXMAP,
252 NULL);
253 }
254 else
255 {
256 // Null bitmap: must not use current pixmap
257 // since it is no longer valid.
258 XtVaSetValues ((Widget) m_mainWidget,
259 XmNlabelType, XmSTRING,
260 XmNlabelPixmap, XmUNSPECIFIED_PIXMAP,
261 XmNlabelInsensitivePixmap, XmUNSPECIFIED_PIXMAP,
262 XmNarmPixmap, XmUNSPECIFIED_PIXMAP,
263 NULL);
264 }
265 }
266
267 void wxBitmapButton::ChangeBackgroundColour()
268 {
269 DoChangeBackgroundColour(m_mainWidget, m_backgroundColour, TRUE);
270
271 // Must reset the bitmaps since the colours have changed.
272 DoSetBitmap();
273 }
274
275 wxSize wxBitmapButton::DoGetBestSize() const
276 {
277 wxSize ret( 30,30 );
278
279 if (m_bmpNormal.Ok())
280 {
281 int border = (GetWindowStyle() & wxNO_BORDER) ? 4 : 10;
282 ret.x = m_bmpNormal.GetWidth()+border;
283 ret.y = m_bmpNormal.GetHeight()+border;
284 }
285
286 return ret;
287 }
288