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