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