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