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