]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/motif/button.cpp
correcting CGImage handling to be always correctly initialized and freed on OSX build...
[wxWidgets.git] / src / motif / button.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: button.cpp
3// Purpose: wxButton
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 XtDisplay XTDISPLAY
17#endif
18
19#include "wx/defs.h"
20
21#include "wx/button.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/stockitem.h"
33#include "wx/motif/private.h"
34#include "wx/sysopt.h"
35
36void wxButtonCallback (Widget w, XtPointer clientData, XtPointer ptr);
37
38IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
39
40#define MIN_WIDTH 78
41#define MIN_LARGE_HEIGHT 30
42
43// Button
44
45bool wxButton::Create(wxWindow *parent, wxWindowID id, const wxString& lbl,
46 const wxPoint& pos,
47 const wxSize& size, long style,
48 const wxValidator& validator,
49 const wxString& name)
50{
51 wxString label(lbl);
52 if (label.empty() && wxIsStockID(id))
53 label = wxGetStockLabel(id);
54
55 if( !CreateControl( parent, id, pos, size, style, validator, name ) )
56 return false;
57
58 wxString label1(wxStripMenuCodes(label));
59 wxXmString text( label1 );
60
61 Widget parentWidget = (Widget) parent->GetClientWidget();
62
63 /*
64 * Patch Note (important)
65 * There is no major reason to put a defaultButtonThickness here.
66 * Not requesting it give the ability to put wxButton with a spacing
67 * as small as requested. However, if some button become a DefaultButton,
68 * other buttons are no more aligned -- This is why we set
69 * defaultButtonThickness of ALL buttons belonging to the same wxPanel,
70 * in the ::SetDefaultButton method.
71 */
72 m_mainWidget = (WXWidget) XtVaCreateManagedWidget ("button",
73 xmPushButtonWidgetClass,
74 parentWidget,
75 wxFont::GetFontTag(), m_font.GetFontTypeC(XtDisplay(parentWidget)),
76 XmNlabelString, text(),
77 XmNrecomputeSize, False,
78 // See comment for wxButton::SetDefault
79 // XmNdefaultButtonShadowThickness, 1,
80 NULL);
81
82 XtAddCallback ((Widget) m_mainWidget,
83 XmNactivateCallback, (XtCallbackProc) wxButtonCallback,
84 (XtPointer) this);
85
86 wxSize best = GetBestSize();
87 if( size.x != -1 ) best.x = size.x;
88 if( size.y != -1 ) best.y = size.y;
89
90 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
91 pos.x, pos.y, best.x, best.y);
92
93 ChangeBackgroundColour();
94
95 return true;
96}
97
98void wxButton::SetDefaultShadowThicknessAndResize()
99{
100 Widget buttonWidget = (Widget)GetMainWidget();
101 bool managed = XtIsManaged( buttonWidget );
102 if( managed )
103 XtUnmanageChild( buttonWidget );
104
105 XtVaSetValues( buttonWidget,
106 XmNdefaultButtonShadowThickness, 1,
107 NULL );
108
109 if( managed )
110 XtManageChild( buttonWidget );
111
112 // this can't currently be done, because user code that calls SetDefault
113 // will break otherwise
114#if 0
115 wxSize best = GetBestSize(), actual = GetSize();
116 if( best.x < actual.x ) best.x = actual.x;
117 if( best.y < actual.y ) best.y = actual.y;
118
119 if( best != actual )
120 SetSize( best );
121#endif
122 InvalidateBestSize();
123}
124
125
126void wxButton::SetDefault()
127{
128 wxWindow *parent = GetParent();
129 if ( parent )
130 parent->SetDefaultItem(this);
131
132 // We initially do not set XmNdefaultShadowThickness, to have
133 // small buttons. Unfortunately, buttons are now mis-aligned. We
134 // try to correct this now -- setting this ressource to 1 for each
135 // button in the same row. Because it's very hard to find
136 // wxButton in the same row, correction is straighforward: we set
137 // resource for all wxButton in this parent (but not sub panels)
138
139 for (wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst ();
140 node; node = node->GetNext ())
141 {
142 wxWindow *win = node->GetData ();
143 wxButton *item = wxDynamicCast(win, wxButton);
144 if (item)
145 item->SetDefaultShadowThicknessAndResize();
146 }
147
148 XtVaSetValues ((Widget) parent->GetMainWidget(),
149 XmNdefaultButton, (Widget) GetMainWidget(),
150 NULL);
151}
152
153static inline bool wxMotifLargeButtons()
154{
155 return wxSystemOptions::HasOption("motif.largebuttons")
156 && wxSystemOptions::GetOptionInt("motif.largebuttons") != 0;
157}
158
159/* static */
160wxSize wxButton::GetDefaultSize()
161{
162 // TODO: check font size as in wxMSW ? MB
163 // Note: this is the button size (text + margin + shadow + defaultBorder)
164 return wxSize( MIN_WIDTH, MIN_LARGE_HEIGHT );
165}
166
167wxSize wxButton::DoGetBestSize() const
168{
169 if( wxMotifLargeButtons() )
170 return OldGetBestSize();
171
172 wxSize best = wxControl::DoGetBestSize();
173
174 if( HasFlag( wxBU_EXACTFIT ) )
175 return best;
176 else if( best.x < MIN_WIDTH )
177 best.x = MIN_WIDTH;
178
179 return best;
180}
181
182wxSize wxButton::GetMinSize() const
183{
184 if( wxMotifLargeButtons() )
185 return OldGetMinSize();
186
187 return DoGetBestSize();
188}
189
190wxSize wxButton::OldGetMinSize() const
191{
192 return OldGetBestSize();
193}
194
195wxSize wxButton::OldGetBestSize() const
196{
197 Dimension xmargin, ymargin, highlight, shadow, defThickness;
198
199 XtVaGetValues( (Widget)m_mainWidget,
200 XmNmarginWidth, &xmargin,
201 XmNmarginHeight, &ymargin,
202 XmNhighlightThickness, &highlight,
203 XmNshadowThickness, &shadow,
204 XmNdefaultButtonShadowThickness, &defThickness,
205 NULL );
206
207 int x = 0; int y = 0;
208 GetTextExtent( GetLabel(), &x, &y );
209
210 int margin = highlight * 2 +
211 ( defThickness ? ( ( shadow + defThickness ) * 4 ) : ( shadow * 2 ) );
212
213 wxSize best( x + xmargin * 2 + margin,
214 y + ymargin * 2 + margin );
215
216 // all buttons have at least the standard size unless the user explicitly
217 // wants them to be of smaller size and used wxBU_EXACTFIT style when
218 // creating the button
219 if( !HasFlag( wxBU_EXACTFIT ) )
220 {
221 wxSize def = GetDefaultSize();
222 int margin = highlight * 2 +
223 ( defThickness ? ( shadow * 4 + defThickness * 4 ) : 0 );
224 def.x += margin;
225 def.y += margin;
226
227 if( def.x > best.x )
228 best.x = def.x;
229 if( def.y > best.y )
230 best.y = def.y;
231 }
232
233 return best;
234}
235
236void wxButton::Command (wxCommandEvent & event)
237{
238 ProcessCommand (event);
239}
240
241void wxButtonCallback (Widget w, XtPointer clientData, XtPointer WXUNUSED(ptr))
242{
243 if (!wxGetWindowFromTable(w))
244 // Widget has been deleted!
245 return;
246
247 wxButton *item = (wxButton *) clientData;
248 wxCommandEvent event (wxEVT_COMMAND_BUTTON_CLICKED, item->GetId());
249 event.SetEventObject(item);
250 item->ProcessCommand (event);
251}