Derive wxBitmapButton from wxBitmapButtonBase + misc cleanup.
[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
179 pixmap = (Pixmap) m_bmpNormal.GetPixmap();
180 }
181 else
182 pixmap = (Pixmap) m_bmpNormal.GetLabelPixmap(m_mainWidget);
183
184 if (m_bmpDisabledOriginal.Ok())
185 {
186 if (m_bmpDisabledOriginal.GetMask())
187 {
188 int backgroundPixel;
189 XtVaGetValues((Widget) m_mainWidget,
190 XmNbackground, &backgroundPixel,
191 NULL);
192
193 wxColour col;
194 col.SetPixel(backgroundPixel);
195
196 wxBitmap newBitmap =
197 wxCreateMaskedBitmap(m_bmpDisabledOriginal, col);
198 m_bmpDisabled = newBitmap;
199
200 insensPixmap = (Pixmap) m_bmpDisabled.GetPixmap();
201 }
202 else
203 insensPixmap = (Pixmap) m_bmpNormal.GetInsensPixmap(m_mainWidget);
204 }
205 else
206 insensPixmap = (Pixmap) m_bmpNormal.GetInsensPixmap(m_mainWidget);
207
208 // Now make the bitmap representing the armed state
209 if (m_bmpSelectedOriginal.Ok())
210 {
211 if (m_bmpSelectedOriginal.GetMask())
212 {
213 int backgroundPixel;
214 XtVaGetValues((Widget) m_mainWidget,
215 XmNarmColor, &backgroundPixel,
216 NULL);
217
218 wxColour col;
219 col.SetPixel(backgroundPixel);
220
221 wxBitmap newBitmap =
222 wxCreateMaskedBitmap(m_bmpSelectedOriginal, col);
223 m_bmpSelected = newBitmap;
224
225 armPixmap = (Pixmap) m_bmpSelected.GetPixmap();
226 }
227 else
228 armPixmap = (Pixmap) m_bmpNormal.GetArmPixmap(m_mainWidget);
229 }
230 else
231 armPixmap = (Pixmap) m_bmpNormal.GetArmPixmap(m_mainWidget);
232
233 // <- the Get...Pixmap()-functions return the same pixmap!
234 if (insensPixmap == pixmap)
235 {
236 insensPixmap =
237 XCreateInsensitivePixmap(DisplayOfScreen(XtScreen((Widget) m_mainWidget)), pixmap);
238 m_insensPixmap = (WXPixmap) insensPixmap;
239 }
240
241 XtVaSetValues ((Widget) m_mainWidget,
242 XmNlabelPixmap, pixmap,
243 XmNlabelInsensitivePixmap, insensPixmap,
244 XmNarmPixmap, armPixmap,
245 XmNlabelType, XmPIXMAP,
246 NULL);
247 }
248 else
249 {
250 // Null bitmap: must not use current pixmap
251 // since it is no longer valid.
252 XtVaSetValues ((Widget) m_mainWidget,
253 XmNlabelType, XmSTRING,
254 XmNlabelPixmap, XmUNSPECIFIED_PIXMAP,
255 XmNlabelInsensitivePixmap, XmUNSPECIFIED_PIXMAP,
256 XmNarmPixmap, XmUNSPECIFIED_PIXMAP,
257 NULL);
258 }
259 }
260
261 void wxBitmapButton::ChangeBackgroundColour()
262 {
263 DoChangeBackgroundColour(m_mainWidget, m_backgroundColour, TRUE);
264
265 // Must reset the bitmaps since the colours have changed.
266 DoSetBitmap();
267 }
268
269 wxSize wxBitmapButton::DoGetBestSize() const
270 {
271 wxSize ret( 30,30 );
272
273 if (m_bmpNormal.Ok())
274 {
275 int border = (GetWindowStyle() & wxNO_BORDER) ? 4 : 10;
276 ret.x = m_bmpNormal.GetWidth()+border;
277 ret.y = m_bmpNormal.GetHeight()+border;
278 }
279
280 return ret;
281 }
282