]>
git.saurik.com Git - wxWidgets.git/blob - src/common/ctrlcmn.cpp
b9e57a8eec1943783c8b8cadafe9ef21c0514871
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/ctrlcmn.cpp
3 // Purpose: wxControl common interface
4 // Author: Vadim Zeitlin
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/control.h"
33 #include "wx/radiobut.h"
34 #include "wx/statbmp.h"
35 #include "wx/bitmap.h"
36 #include "wx/utils.h" // for wxStripMenuCodes()
39 const char wxControlNameStr
[] = "control";
41 // ============================================================================
43 // ============================================================================
45 wxControlBase::~wxControlBase()
47 // this destructor is required for Darwin
50 bool wxControlBase::Create(wxWindow
*parent
,
55 const wxValidator
& wxVALIDATOR_PARAM(validator
),
58 bool ret
= wxWindow::Create(parent
, id
, pos
, size
, style
, name
);
62 SetValidator(validator
);
63 #endif // wxUSE_VALIDATORS
68 bool wxControlBase::CreateControl(wxWindowBase
*parent
,
73 const wxValidator
& validator
,
76 // even if it's possible to create controls without parents in some port,
77 // it should surely be discouraged because it doesn't work at all under
79 wxCHECK_MSG( parent
, false, wxT("all controls must have parents") );
81 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
84 parent
->AddChild(this);
90 wxString
wxControlBase::GetLabelText(const wxString
& label
)
92 // we don't want strip the TABs here, just the mnemonics
93 return wxStripMenuCodes(label
, wxStrip_Mnemonics
);
96 void wxControlBase::Command(wxCommandEvent
& event
)
98 (void)GetEventHandler()->ProcessEvent(event
);
101 void wxControlBase::InitCommandEvent(wxCommandEvent
& event
) const
103 event
.SetEventObject((wxControlBase
*)this); // const_cast
105 // event.SetId(GetId()); -- this is usuall done in the event ctor
107 switch ( m_clientDataType
)
109 case wxClientData_Void
:
110 event
.SetClientData(GetClientData());
113 case wxClientData_Object
:
114 event
.SetClientObject(GetClientObject());
117 case wxClientData_None
:
123 bool wxControlBase::SetFont(const wxFont
& font
)
125 InvalidateBestSize();
126 return wxWindow::SetFont(font
);
129 // wxControl-specific processing after processing the update event
130 void wxControlBase::DoUpdateWindowUI(wxUpdateUIEvent
& event
)
133 wxWindowBase::DoUpdateWindowUI(event
);
136 if ( event
.GetSetText() )
138 if ( event
.GetText() != GetLabel() )
139 SetLabel(event
.GetText());
142 // Unfortunately we don't yet have common base class for
143 // wxRadioButton, so we handle updates of radiobuttons here.
144 // TODO: If once wxRadioButtonBase will exist, move this code there.
146 if ( event
.GetSetChecked() )
148 wxRadioButton
*radiobtn
= wxDynamicCastThis(wxRadioButton
);
150 radiobtn
->SetValue(event
.GetChecked());
152 #endif // wxUSE_RADIOBTN
156 wxString
wxControlBase::RemoveMnemonics(const wxString
& str
)
158 return wxStripMenuCodes(str
, wxStrip_Mnemonics
);
162 int wxControlBase::FindAccelIndex(const wxString
& label
, wxString
*labelOnly
)
164 // the character following MNEMONIC_PREFIX is the accelerator for this
165 // control unless it is MNEMONIC_PREFIX too - this allows to insert
166 // literal MNEMONIC_PREFIX chars into the label
167 static const wxChar MNEMONIC_PREFIX
= _T('&');
172 labelOnly
->Alloc(label
.length());
176 for ( wxString::const_iterator pc
= label
.begin(); pc
!= label
.end(); ++pc
)
178 if ( *pc
== MNEMONIC_PREFIX
)
181 if ( pc
== label
.end() )
183 else if ( *pc
!= MNEMONIC_PREFIX
)
185 if ( indexAccel
== -1 )
187 // remember it (-1 is for MNEMONIC_PREFIX itself
188 indexAccel
= pc
- label
.begin() - 1;
192 wxFAIL_MSG(_T("duplicate accel char in control label"));
206 #define wxELLIPSE_REPLACEMENT wxT("...")
209 wxString
wxControlBase::Ellipsize(const wxString
& label
, const wxDC
& dc
,
210 wxEllipsizeMode mode
, int maxFinalWidth
)
212 wxArrayInt charOffsets
;
215 // these cannot be cached as they can change because of e.g. a font change
216 int replacementWidth
= dc
.GetTextExtent(wxELLIPSE_REPLACEMENT
).GetWidth();
217 int marginWidth
= dc
.GetCharWidth()*2;
219 // NB: we must handle correctly labels with newlines:
223 for ( wxString::const_iterator pc
= label
.begin(); ; ++pc
)
225 if ( pc
== label
.end() || *pc
== _T('\n') )
227 len
= curLine
.length();
229 dc
.GetPartialTextExtents(curLine
, charOffsets
))
231 wxASSERT(charOffsets
.GetCount() == len
);
233 size_t totalWidth
= charOffsets
.Last();
234 if ( totalWidth
> (size_t)maxFinalWidth
)
236 // we need to ellipsize this row
237 int excessPixels
= totalWidth
- maxFinalWidth
+
239 marginWidth
; // security margin (NEEDED!)
241 // remove characters in excess
242 size_t initialChar
, // index of first char to erase
243 nChars
; // how many chars do we need to erase?
244 if (mode
== wxELLIPSIZE_START
)
248 nChars
< len
&& charOffsets
[nChars
] < excessPixels
;
252 else if (mode
== wxELLIPSIZE_MIDDLE
)
254 // the start & end of the removed span of chars
256 size_t endChar
= len
/2;
259 for ( ; removed
< excessPixels
; )
263 // width of the initialChar-th character
264 int width
= charOffsets
[initialChar
] -
265 charOffsets
[initialChar
-1];
267 // remove the initialChar-th character
272 if (endChar
< len
- 1 &&
273 removed
< excessPixels
)
275 // width of the (endChar+1)-th character
276 int width
= charOffsets
[endChar
+1] -
277 charOffsets
[endChar
];
279 // remove the endChar-th character
284 if (initialChar
== 0 && endChar
== len
-1)
292 nChars
= endChar
- initialChar
+ 1;
296 wxASSERT(mode
== wxELLIPSIZE_END
);
299 int maxWidth
= totalWidth
- excessPixels
;
302 charOffsets
[initialChar
] < maxWidth
;
306 if (initialChar
== 0)
312 initialChar
--; // go back one character
313 nChars
= len
- initialChar
;
319 // need to remove the entire row!
324 // erase nChars characters after initialChar (included):
325 curLine
.erase(initialChar
, nChars
+1);
327 // if there is space for the replacement dots, add them
328 if (maxFinalWidth
> replacementWidth
)
329 curLine
.insert(initialChar
, wxELLIPSE_REPLACEMENT
);
332 // if everything was ok, we should have shortened this line
333 // enough to make it fit in maxFinalWidth:
334 wxASSERT(dc
.GetTextExtent(curLine
).GetWidth() < maxFinalWidth
);
338 // add this (ellipsized) row to the rest of the label
340 if ( pc
== label
.end() )
342 // NOTE: this is the return which always exits the function
351 // we need to remove mnemonics from the label for correct calculations
352 else if ( *pc
== _T('&') )
354 // pc+1 is safe: at worst we'll be at end()
355 wxString::const_iterator next
= pc
+ 1;
356 if ( next
!= label
.end() && *next
== _T('&') )
357 curLine
+= _T('&'); // && becomes &
358 //else: remove this ampersand
360 // we need also to expand tabs to properly calc their size
361 else if ( *pc
== _T('\t') )
363 // Windows natively expands the TABs to 6 spaces. Do the same:
372 // this return would generate a
373 // warning C4702: unreachable code
374 // with MSVC since the function always exits from inside the loop
378 wxBorder
wxControlBase::GetDefaultBorder() const
380 return wxBORDER_THEME
;
384 // ----------------------------------------------------------------------------
386 // ----------------------------------------------------------------------------
390 wxStaticBitmapBase::~wxStaticBitmapBase()
392 // this destructor is required for Darwin
395 wxSize
wxStaticBitmapBase::DoGetBestSize() const
398 wxBitmap bmp
= GetBitmap();
400 best
= wxSize(bmp
.GetWidth(), bmp
.GetHeight());
402 // this is completely arbitrary
403 best
= wxSize(16, 16);
408 #endif // wxUSE_STATBMP
410 #endif // wxUSE_CONTROLS