]> git.saurik.com Git - wxWidgets.git/blob - src/motif/bmpbuttn.cpp
Implemented copy-on-demand for wxClipboard.
[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 wxSize best = m_bmpNormal.Ok() ? GetBestSize() : wxSize(30, 30);
105 if( size.x != -1 ) best.x = size.x;
106 if( size.y != -1 ) best.y = size.y;
107
108 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
109 pos.x, pos.y, best.x, best.y);
110
111 return TRUE;
112 }
113
114 wxBitmapButton::~wxBitmapButton()
115 {
116 SetBitmapLabel(wxNullBitmap);
117
118 if (m_insensPixmap)
119 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) GetXDisplay()),
120 (Pixmap) m_insensPixmap);
121 }
122
123 void wxBitmapButton::SetBitmapLabel(const wxBitmap& bitmap)
124 {
125 m_bmpNormalOriginal = bitmap;
126 m_bmpNormal = bitmap;
127
128 DoSetBitmap();
129 }
130
131 void wxBitmapButton::SetBitmapSelected(const wxBitmap& sel)
132 {
133 m_bmpSelected = sel;
134 m_bmpSelectedOriginal = sel;
135
136 DoSetBitmap();
137 };
138
139 void wxBitmapButton::SetBitmapFocus(const wxBitmap& focus)
140 {
141 m_bmpFocus = focus;
142 // Not used in Motif
143 };
144
145 void wxBitmapButton::SetBitmapDisabled(const wxBitmap& disabled)
146 {
147 m_bmpDisabled = disabled;
148 m_bmpDisabledOriginal = disabled;
149
150 DoSetBitmap();
151 };
152
153 void wxBitmapButton::DoSetBitmap()
154 {
155 if (m_bmpNormalOriginal.Ok())
156 {
157 Pixmap pixmap = 0;
158 Pixmap insensPixmap = 0;
159 Pixmap armPixmap = 0;
160
161 // Must re-make the bitmap to have its transparent areas drawn
162 // in the current widget background colour.
163 if (m_bmpNormalOriginal.GetMask())
164 {
165 int backgroundPixel;
166 XtVaGetValues((Widget) m_mainWidget,
167 XmNbackground, &backgroundPixel,
168 NULL);
169
170 wxColour col;
171 col.SetPixel(backgroundPixel);
172
173 wxBitmap newBitmap =
174 wxCreateMaskedBitmap(m_bmpNormalOriginal, col);
175 m_bmpNormal = newBitmap;
176 m_bitmapCache.SetBitmap( m_bmpNormal );
177
178 pixmap = (Pixmap) m_bmpNormal.GetDrawable();
179 }
180 else
181 {
182 m_bitmapCache.SetBitmap( m_bmpNormal );
183 pixmap = (Pixmap) m_bitmapCache.GetLabelPixmap(m_mainWidget);
184 }
185
186 if (m_bmpDisabledOriginal.Ok())
187 {
188 if (m_bmpDisabledOriginal.GetMask())
189 {
190 int backgroundPixel;
191 XtVaGetValues((Widget) m_mainWidget,
192 XmNbackground, &backgroundPixel,
193 NULL);
194
195 wxColour col;
196 col.SetPixel(backgroundPixel);
197
198 wxBitmap newBitmap =
199 wxCreateMaskedBitmap(m_bmpDisabledOriginal, col);
200 m_bmpDisabled = newBitmap;
201
202 insensPixmap = (Pixmap) m_bmpDisabled.GetDrawable();
203 }
204 else
205 insensPixmap = (Pixmap) m_bitmapCache.GetInsensPixmap(m_mainWidget);
206 }
207 else
208 insensPixmap = (Pixmap) m_bitmapCache.GetInsensPixmap(m_mainWidget);
209
210 // Now make the bitmap representing the armed state
211 if (m_bmpSelectedOriginal.Ok())
212 {
213 if (m_bmpSelectedOriginal.GetMask())
214 {
215 int backgroundPixel;
216 XtVaGetValues((Widget) m_mainWidget,
217 XmNarmColor, &backgroundPixel,
218 NULL);
219
220 wxColour col;
221 col.SetPixel(backgroundPixel);
222
223 wxBitmap newBitmap =
224 wxCreateMaskedBitmap(m_bmpSelectedOriginal, col);
225 m_bmpSelected = newBitmap;
226
227 armPixmap = (Pixmap) m_bmpSelected.GetDrawable();
228 }
229 else
230 armPixmap = (Pixmap) m_bitmapCache.GetArmPixmap(m_mainWidget);
231 }
232 else
233 armPixmap = (Pixmap) m_bitmapCache.GetArmPixmap(m_mainWidget);
234
235 #if 0
236 // <- the Get...Pixmap()-functions return the same pixmap!
237 if (insensPixmap == pixmap)
238 {
239 insensPixmap =
240 XCreateInsensitivePixmap(DisplayOfScreen(XtScreen((Widget) m_mainWidget)), pixmap);
241 m_insensPixmap = (WXPixmap) insensPixmap;
242 }
243 #endif
244
245 XtVaSetValues ((Widget) m_mainWidget,
246 XmNlabelPixmap, pixmap,
247 XmNlabelInsensitivePixmap, insensPixmap,
248 XmNarmPixmap, armPixmap,
249 XmNlabelType, XmPIXMAP,
250 NULL);
251 }
252 else
253 {
254 // Null bitmap: must not use current pixmap
255 // since it is no longer valid.
256 XtVaSetValues ((Widget) m_mainWidget,
257 XmNlabelType, XmSTRING,
258 XmNlabelPixmap, XmUNSPECIFIED_PIXMAP,
259 XmNlabelInsensitivePixmap, XmUNSPECIFIED_PIXMAP,
260 XmNarmPixmap, XmUNSPECIFIED_PIXMAP,
261 NULL);
262 }
263 }
264
265 void wxBitmapButton::ChangeBackgroundColour()
266 {
267 wxDoChangeBackgroundColour(m_mainWidget, m_backgroundColour, TRUE);
268
269 // Must reset the bitmaps since the colours have changed.
270 DoSetBitmap();
271 }
272
273 wxSize wxBitmapButton::DoGetBestSize() const
274 {
275 wxSize ret( 30,30 );
276
277 if (m_bmpNormal.Ok())
278 {
279 int border = (GetWindowStyle() & wxNO_BORDER) ? 4 : 10;
280 ret.x = m_bmpNormal.GetWidth()+border;
281 ret.y = m_bmpNormal.GetHeight()+border;
282 }
283
284 return ret;
285 }
286