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