1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/srchctlg.cpp
3 // Purpose: implements wxSearchCtrl as a composite control
4 // Author: Vince Harron
7 // Copyright: Vince Harron
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
20 #include "wx/srchctrl.h"
23 #include "wx/button.h"
24 #include "wx/dcclient.h"
26 #include "wx/dcmemory.h"
29 #if !wxUSE_NATIVE_SEARCH_CONTROL
33 #define WXMAX(a,b) ((a)>(b)?(a):(b))
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // the margin between the text control and the search/cancel buttons
40 static const wxCoord MARGIN
= 2;
42 // border around all controls to compensate for wxSIMPLE_BORDER
43 #if defined(__WXMSW__)
44 static const wxCoord BORDER
= 0;
45 static const wxCoord ICON_MARGIN
= 2;
46 static const wxCoord ICON_OFFSET
= 2;
48 static const wxCoord BORDER
= 2;
49 static const wxCoord ICON_MARGIN
= 0;
50 static const wxCoord ICON_OFFSET
= 0;
53 // ----------------------------------------------------------------------------
54 // TODO: These functions or something like them should probably be made
55 // public. There are similar functions in src/aui/dockart.cpp...
57 static double wxBlendColour(double fg
, double bg
, double alpha
)
59 double result
= bg
+ (alpha
* (fg
- bg
));
67 static wxColor
wxStepColour(const wxColor
& c
, int ialpha
)
72 double r
= c
.Red(), g
= c
.Green(), b
= c
.Blue();
75 // ialpha is 0..200 where 0 is completely black
76 // and 200 is completely white and 100 is the same
77 // convert that to normal alpha 0.0 - 1.0
78 ialpha
= wxMin(ialpha
, 200);
79 ialpha
= wxMax(ialpha
, 0);
80 double alpha
= ((double)(ialpha
- 100.0))/100.0;
86 alpha
= 1.0 - alpha
; // 0 = transparent fg; 1 = opaque fg
92 alpha
= 1.0 + alpha
; // 0 = transparent fg; 1 = opaque fg
95 r
= wxBlendColour(r
, bg
, alpha
);
96 g
= wxBlendColour(g
, bg
, alpha
);
97 b
= wxBlendColour(b
, bg
, alpha
);
99 return wxColour((unsigned char)r
, (unsigned char)g
, (unsigned char)b
);
102 #define LIGHT_STEP 160
104 // ----------------------------------------------------------------------------
105 // wxSearchTextCtrl: text control used by search control
106 // ----------------------------------------------------------------------------
108 class wxSearchTextCtrl
: public wxTextCtrl
111 wxSearchTextCtrl(wxSearchCtrl
*search
, const wxString
& value
, int style
)
112 : wxTextCtrl(search
, wxID_ANY
, value
, wxDefaultPosition
, wxDefaultSize
,
116 m_defaultFG
= GetForegroundColour();
118 // remove the default minsize, the searchctrl will have one instead
119 SetSizeHints(wxDefaultCoord
,wxDefaultCoord
);
122 void SetDescriptiveText(const wxString
& text
)
124 if ( GetValue() == m_descriptiveText
)
126 ChangeValue(wxEmptyString
);
129 m_descriptiveText
= text
;
132 wxString
GetDescriptiveText() const
134 return m_descriptiveText
;
138 // provide access to the base class protected methods to wxSearchCtrl which
139 // needs to forward to them
140 void DoSetValue(const wxString
& value
, int flags
)
142 wxTextCtrl::DoSetValue(value
, flags
);
145 bool DoLoadFile(const wxString
& file
, int fileType
)
147 return wxTextCtrl::DoLoadFile(file
, fileType
);
150 bool DoSaveFile(const wxString
& file
, int fileType
)
152 return wxTextCtrl::DoSaveFile(file
, fileType
);
156 void OnText(wxCommandEvent
& eventText
)
158 wxCommandEvent
event(eventText
);
159 event
.SetEventObject(m_search
);
160 event
.SetId(m_search
->GetId());
162 m_search
->GetEventHandler()->ProcessEvent(event
);
165 void OnTextUrl(wxTextUrlEvent
& eventText
)
167 // copy constructor is disabled for some reason?
168 //wxTextUrlEvent event(eventText);
169 wxTextUrlEvent
event(
171 eventText
.GetMouseEvent(),
172 eventText
.GetURLStart(),
173 eventText
.GetURLEnd()
175 event
.SetEventObject(m_search
);
177 m_search
->GetEventHandler()->ProcessEvent(event
);
180 void OnIdle(wxIdleEvent
& WXUNUSED(event
))
182 if ( IsEmpty() && !(wxWindow::FindFocus() == this) )
184 ChangeValue(m_descriptiveText
);
185 SetInsertionPoint(0);
186 SetForegroundColour(wxStepColour(m_defaultFG
, LIGHT_STEP
));
190 void OnFocus(wxFocusEvent
& event
)
193 if ( GetValue() == m_descriptiveText
)
195 ChangeValue(wxEmptyString
);
196 SetForegroundColour(m_defaultFG
);
201 wxSearchCtrl
* m_search
;
202 wxString m_descriptiveText
;
203 wxColour m_defaultFG
;
205 DECLARE_EVENT_TABLE()
208 BEGIN_EVENT_TABLE(wxSearchTextCtrl
, wxTextCtrl
)
209 EVT_TEXT(wxID_ANY
, wxSearchTextCtrl::OnText
)
210 EVT_TEXT_ENTER(wxID_ANY
, wxSearchTextCtrl::OnText
)
211 EVT_TEXT_URL(wxID_ANY
, wxSearchTextCtrl::OnTextUrl
)
212 EVT_TEXT_MAXLEN(wxID_ANY
, wxSearchTextCtrl::OnText
)
213 EVT_IDLE(wxSearchTextCtrl::OnIdle
)
214 EVT_SET_FOCUS(wxSearchTextCtrl::OnFocus
)
217 // ----------------------------------------------------------------------------
218 // wxSearchButton: search button used by search control
219 // ----------------------------------------------------------------------------
221 class wxSearchButton
: public wxControl
224 wxSearchButton(wxSearchCtrl
*search
, int eventType
, const wxBitmap
& bmp
)
225 : wxControl(search
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxNO_BORDER
),
227 m_eventType(eventType
),
231 void SetBitmapLabel(const wxBitmap
& label
) { m_bmp
= label
; }
235 wxSize
DoGetBestSize() const
237 return wxSize(m_bmp
.GetWidth(), m_bmp
.GetHeight());
240 void OnLeftUp(wxMouseEvent
&)
242 wxCommandEvent
event(m_eventType
, m_search
->GetId());
243 event
.SetEventObject(m_search
);
245 if ( m_eventType
== wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN
)
247 // it's convenient to have the string to search for directly in the
248 // event instead of having to retrieve it from the control in the
249 // event handler code later, so provide it here
250 event
.SetString(m_search
->GetValue());
253 GetEventHandler()->ProcessEvent(event
);
255 m_search
->SetFocus();
258 if ( m_eventType
== wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN
)
260 // this happens automatically, just like on Mac OS X
261 m_search
->PopupSearchMenu();
263 #endif // wxUSE_MENUS
266 void OnPaint(wxPaintEvent
&)
269 dc
.DrawBitmap(m_bmp
, 0,0, true);
274 wxSearchCtrl
*m_search
;
275 wxEventType m_eventType
;
278 DECLARE_EVENT_TABLE()
281 BEGIN_EVENT_TABLE(wxSearchButton
, wxControl
)
282 EVT_LEFT_UP(wxSearchButton::OnLeftUp
)
283 EVT_PAINT(wxSearchButton::OnPaint
)
286 BEGIN_EVENT_TABLE(wxSearchCtrl
, wxSearchCtrlBase
)
287 EVT_SEARCHCTRL_SEARCH_BTN(wxID_ANY
, wxSearchCtrl::OnSearchButton
)
288 EVT_SET_FOCUS(wxSearchCtrl::OnSetFocus
)
289 EVT_SIZE(wxSearchCtrl::OnSize
)
292 IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl
, wxSearchCtrlBase
)
294 // ============================================================================
296 // ============================================================================
298 // ----------------------------------------------------------------------------
299 // wxSearchCtrl creation
300 // ----------------------------------------------------------------------------
305 wxSearchCtrl::wxSearchCtrl()
310 wxSearchCtrl::wxSearchCtrl(wxWindow
*parent
, wxWindowID id
,
311 const wxString
& value
,
315 const wxValidator
& validator
,
316 const wxString
& name
)
320 Create(parent
, id
, value
, pos
, size
, style
, validator
, name
);
323 void wxSearchCtrl::Init()
326 m_searchButton
= NULL
;
327 m_cancelButton
= NULL
;
330 #endif // wxUSE_MENUS
332 m_searchButtonVisible
= true;
333 m_cancelButtonVisible
= false;
335 m_searchBitmapUser
= false;
336 m_cancelBitmapUser
= false;
338 m_searchMenuBitmapUser
= false;
339 #endif // wxUSE_MENUS
342 bool wxSearchCtrl::Create(wxWindow
*parent
, wxWindowID id
,
343 const wxString
& value
,
347 const wxValidator
& validator
,
348 const wxString
& name
)
350 // force border style for more native appearance
351 style
&= ~wxBORDER_MASK
;
353 style
|= wxBORDER_SUNKEN
;
354 #elif defined(__WXMSW__)
355 // Don't set the style explicitly, let GetDefaultBorder() work it out, unless
356 // we will get a sunken border (e.g. on Windows 200) in which case we must
357 // override with a simple border.
358 if (GetDefaultBorder() == wxBORDER_SUNKEN
)
359 style
|= wxBORDER_SIMPLE
;
361 style
|= wxBORDER_SIMPLE
;
363 if ( !wxSearchCtrlBaseBaseClass::Create(parent
, id
, pos
, size
,
364 style
, validator
, name
) )
369 m_text
= new wxSearchTextCtrl(this, value
, style
& ~wxBORDER_MASK
);
370 m_text
->SetDescriptiveText(_("Search"));
372 m_searchButton
= new wxSearchButton(this,
373 wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN
,
375 m_cancelButton
= new wxSearchButton(this,
376 wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN
,
379 SetForegroundColour( m_text
->GetForegroundColour() );
380 m_searchButton
->SetForegroundColour( m_text
->GetForegroundColour() );
381 m_cancelButton
->SetForegroundColour( m_text
->GetForegroundColour() );
383 SetBackgroundColour( m_text
->GetBackgroundColour() );
384 m_searchButton
->SetBackgroundColour( m_text
->GetBackgroundColour() );
385 m_cancelButton
->SetBackgroundColour( m_text
->GetBackgroundColour() );
389 SetInitialSize(size
);
394 wxSearchCtrl::~wxSearchCtrl()
397 delete m_searchButton
;
398 delete m_cancelButton
;
401 #endif // wxUSE_MENUS
405 // search control specific interfaces
408 void wxSearchCtrl::SetMenu( wxMenu
* menu
)
410 if ( menu
== m_menu
)
415 bool hadMenu
= (m_menu
!= NULL
);
419 if ( m_menu
&& !hadMenu
)
421 m_searchButton
->SetBitmapLabel(m_searchMenuBitmap
);
422 m_searchButton
->Refresh();
424 else if ( !m_menu
&& hadMenu
)
426 m_searchButton
->SetBitmapLabel(m_searchBitmap
);
427 if ( m_searchButtonVisible
)
429 m_searchButton
->Refresh();
432 wxRect rect
= GetRect();
433 LayoutControls(0, 0, rect
.GetWidth(), rect
.GetHeight());
436 wxMenu
* wxSearchCtrl::GetMenu()
441 #endif // wxUSE_MENUS
443 void wxSearchCtrl::ShowSearchButton( bool show
)
445 if ( m_searchButtonVisible
== show
)
450 m_searchButtonVisible
= show
;
451 if ( m_searchButtonVisible
)
456 wxRect rect
= GetRect();
457 LayoutControls(0, 0, rect
.GetWidth(), rect
.GetHeight());
460 bool wxSearchCtrl::IsSearchButtonVisible() const
462 return m_searchButtonVisible
;
466 void wxSearchCtrl::ShowCancelButton( bool show
)
468 if ( m_cancelButtonVisible
== show
)
473 m_cancelButtonVisible
= show
;
475 wxRect rect
= GetRect();
476 LayoutControls(0, 0, rect
.GetWidth(), rect
.GetHeight());
479 bool wxSearchCtrl::IsCancelButtonVisible() const
481 return m_cancelButtonVisible
;
484 void wxSearchCtrl::SetDescriptiveText(const wxString
& text
)
486 m_text
->SetDescriptiveText(text
);
489 wxString
wxSearchCtrl::GetDescriptiveText() const
491 return m_text
->GetDescriptiveText();
494 // ----------------------------------------------------------------------------
496 // ----------------------------------------------------------------------------
498 wxSize
wxSearchCtrl::DoGetBestSize() const
500 wxSize sizeText
= m_text
->GetBestSize();
501 wxSize
sizeSearch(0,0);
502 wxSize
sizeCancel(0,0);
503 int searchMargin
= 0;
504 int cancelMargin
= 0;
505 if ( m_searchButtonVisible
|| HasMenu() )
507 sizeSearch
= m_searchButton
->GetBestSize();
508 searchMargin
= MARGIN
;
510 if ( m_cancelButtonVisible
)
512 sizeCancel
= m_cancelButton
->GetBestSize();
513 cancelMargin
= MARGIN
;
516 int horizontalBorder
= 1 + ( sizeText
.y
- sizeText
.y
* 14 / 21 ) / 2;
518 // buttons are square and equal to the height of the text control
519 int height
= sizeText
.y
;
520 return wxSize(sizeSearch
.x
+ searchMargin
+ sizeText
.x
+ cancelMargin
+ sizeCancel
.x
+ 2*horizontalBorder
,
524 void wxSearchCtrl::DoMoveWindow(int x
, int y
, int width
, int height
)
526 wxSearchCtrlBase::DoMoveWindow(x
, y
, width
, height
);
528 LayoutControls(0, 0, width
, height
);
531 void wxSearchCtrl::LayoutControls(int x
, int y
, int width
, int height
)
536 wxSize sizeText
= m_text
->GetBestSize();
537 // make room for the search menu & clear button
538 int horizontalBorder
= ( sizeText
.y
- sizeText
.y
* 14 / 21 ) / 2;
539 x
+= horizontalBorder
;
541 width
-= horizontalBorder
*2;
543 if (width
< 0) width
= 0;
544 if (height
< 0) height
= 0;
546 wxSize
sizeSearch(0,0);
547 wxSize
sizeCancel(0,0);
548 int searchMargin
= 0;
549 int cancelMargin
= 0;
550 if ( m_searchButtonVisible
|| HasMenu() )
552 sizeSearch
= m_searchButton
->GetBestSize();
553 searchMargin
= MARGIN
;
555 if ( m_cancelButtonVisible
)
557 sizeCancel
= m_cancelButton
->GetBestSize();
558 cancelMargin
= MARGIN
;
560 m_searchButton
->Show( m_searchButtonVisible
|| HasMenu() );
561 m_cancelButton
->Show( m_cancelButtonVisible
);
563 if ( sizeSearch
.x
+ sizeCancel
.x
> width
)
565 sizeSearch
.x
= width
/2;
566 sizeCancel
.x
= width
/2;
570 wxCoord textWidth
= width
- sizeSearch
.x
- sizeCancel
.x
- searchMargin
- cancelMargin
- 1;
571 if (textWidth
< 0) textWidth
= 0;
573 // position the subcontrols inside the client area
575 m_searchButton
->SetSize(x
, y
+ ICON_OFFSET
- 1, sizeSearch
.x
, height
);
576 m_text
->SetSize( x
+ sizeSearch
.x
+ searchMargin
,
577 y
+ ICON_OFFSET
- BORDER
,
580 m_cancelButton
->SetSize(x
+ sizeSearch
.x
+ searchMargin
+ textWidth
+ cancelMargin
,
581 y
+ ICON_OFFSET
- 1, sizeCancel
.x
, height
);
588 wxString
wxSearchCtrl::DoGetValue() const
590 wxString value
= m_text
->GetValue();
591 if (value
== m_text
->GetDescriptiveText())
592 return wxEmptyString
;
596 wxString
wxSearchCtrl::GetRange(long from
, long to
) const
598 return m_text
->GetRange(from
, to
);
601 int wxSearchCtrl::GetLineLength(long lineNo
) const
603 return m_text
->GetLineLength(lineNo
);
605 wxString
wxSearchCtrl::GetLineText(long lineNo
) const
607 return m_text
->GetLineText(lineNo
);
609 int wxSearchCtrl::GetNumberOfLines() const
611 return m_text
->GetNumberOfLines();
614 bool wxSearchCtrl::IsModified() const
616 return m_text
->IsModified();
618 bool wxSearchCtrl::IsEditable() const
620 return m_text
->IsEditable();
623 // more readable flag testing methods
624 bool wxSearchCtrl::IsSingleLine() const
626 return m_text
->IsSingleLine();
628 bool wxSearchCtrl::IsMultiLine() const
630 return m_text
->IsMultiLine();
633 // If the return values from and to are the same, there is no selection.
634 void wxSearchCtrl::GetSelection(long* from
, long* to
) const
636 m_text
->GetSelection(from
, to
);
639 wxString
wxSearchCtrl::GetStringSelection() const
641 return m_text
->GetStringSelection();
648 void wxSearchCtrl::Clear()
652 void wxSearchCtrl::Replace(long from
, long to
, const wxString
& value
)
654 m_text
->Replace(from
, to
, value
);
656 void wxSearchCtrl::Remove(long from
, long to
)
658 m_text
->Remove(from
, to
);
661 // load/save the controls contents from/to the file
662 bool wxSearchCtrl::LoadFile(const wxString
& file
)
664 return m_text
->LoadFile(file
);
666 bool wxSearchCtrl::SaveFile(const wxString
& file
)
668 return m_text
->SaveFile(file
);
671 // sets/clears the dirty flag
672 void wxSearchCtrl::MarkDirty()
676 void wxSearchCtrl::DiscardEdits()
678 m_text
->DiscardEdits();
681 // set the max number of characters which may be entered in a single line
683 void wxSearchCtrl::SetMaxLength(unsigned long len
)
685 m_text
->SetMaxLength(len
);
688 // writing text inserts it at the current position, appending always
689 // inserts it at the end
690 void wxSearchCtrl::WriteText(const wxString
& text
)
692 m_text
->WriteText(text
);
694 void wxSearchCtrl::AppendText(const wxString
& text
)
696 m_text
->AppendText(text
);
699 // insert the character which would have resulted from this key event,
700 // return true if anything has been inserted
701 bool wxSearchCtrl::EmulateKeyPress(const wxKeyEvent
& event
)
703 return m_text
->EmulateKeyPress(event
);
706 // text control under some platforms supports the text styles: these
707 // methods allow to apply the given text style to the given selection or to
708 // set/get the style which will be used for all appended text
709 bool wxSearchCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
711 return m_text
->SetStyle(start
, end
, style
);
713 bool wxSearchCtrl::GetStyle(long position
, wxTextAttr
& style
)
715 return m_text
->GetStyle(position
, style
);
717 bool wxSearchCtrl::SetDefaultStyle(const wxTextAttr
& style
)
719 return m_text
->SetDefaultStyle(style
);
721 const wxTextAttr
& wxSearchCtrl::GetDefaultStyle() const
723 return m_text
->GetDefaultStyle();
726 // translate between the position (which is just an index in the text ctrl
727 // considering all its contents as a single strings) and (x, y) coordinates
728 // which represent column and line.
729 long wxSearchCtrl::XYToPosition(long x
, long y
) const
731 return m_text
->XYToPosition(x
, y
);
733 bool wxSearchCtrl::PositionToXY(long pos
, long *x
, long *y
) const
735 return m_text
->PositionToXY(pos
, x
, y
);
738 void wxSearchCtrl::ShowPosition(long pos
)
740 m_text
->ShowPosition(pos
);
743 // find the character at position given in pixels
745 // NB: pt is in device coords (not adjusted for the client area origin nor
747 wxTextCtrlHitTestResult
wxSearchCtrl::HitTest(const wxPoint
& pt
, long *pos
) const
749 return m_text
->HitTest(pt
, pos
);
751 wxTextCtrlHitTestResult
wxSearchCtrl::HitTest(const wxPoint
& pt
,
753 wxTextCoord
*row
) const
755 return m_text
->HitTest(pt
, col
, row
);
758 // Clipboard operations
759 void wxSearchCtrl::Copy()
763 void wxSearchCtrl::Cut()
767 void wxSearchCtrl::Paste()
772 bool wxSearchCtrl::CanCopy() const
774 return m_text
->CanCopy();
776 bool wxSearchCtrl::CanCut() const
778 return m_text
->CanCut();
780 bool wxSearchCtrl::CanPaste() const
782 return m_text
->CanPaste();
786 void wxSearchCtrl::Undo()
790 void wxSearchCtrl::Redo()
795 bool wxSearchCtrl::CanUndo() const
797 return m_text
->CanUndo();
799 bool wxSearchCtrl::CanRedo() const
801 return m_text
->CanRedo();
805 void wxSearchCtrl::SetInsertionPoint(long pos
)
807 m_text
->SetInsertionPoint(pos
);
809 void wxSearchCtrl::SetInsertionPointEnd()
811 m_text
->SetInsertionPointEnd();
813 long wxSearchCtrl::GetInsertionPoint() const
815 return m_text
->GetInsertionPoint();
817 long wxSearchCtrl::GetLastPosition() const
819 return m_text
->GetLastPosition();
822 void wxSearchCtrl::SetSelection(long from
, long to
)
824 m_text
->SetSelection(from
, to
);
826 void wxSearchCtrl::SelectAll()
831 void wxSearchCtrl::SetEditable(bool editable
)
833 m_text
->SetEditable(editable
);
836 bool wxSearchCtrl::SetFont(const wxFont
& font
)
838 bool result
= wxSearchCtrlBase::SetFont(font
);
839 if ( result
&& m_text
)
841 result
= m_text
->SetFont(font
);
847 // search control generic only
848 void wxSearchCtrl::SetSearchBitmap( const wxBitmap
& bitmap
)
850 m_searchBitmap
= bitmap
;
851 m_searchBitmapUser
= bitmap
.Ok();
852 if ( m_searchBitmapUser
)
854 if ( m_searchButton
&& !HasMenu() )
856 m_searchButton
->SetBitmapLabel( m_searchBitmap
);
861 // the user bitmap was just cleared, generate one
868 void wxSearchCtrl::SetSearchMenuBitmap( const wxBitmap
& bitmap
)
870 m_searchMenuBitmap
= bitmap
;
871 m_searchMenuBitmapUser
= bitmap
.Ok();
872 if ( m_searchMenuBitmapUser
)
874 if ( m_searchButton
&& m_menu
)
876 m_searchButton
->SetBitmapLabel( m_searchMenuBitmap
);
881 // the user bitmap was just cleared, generate one
886 #endif // wxUSE_MENUS
888 void wxSearchCtrl::SetCancelBitmap( const wxBitmap
& bitmap
)
890 m_cancelBitmap
= bitmap
;
891 m_cancelBitmapUser
= bitmap
.Ok();
892 if ( m_cancelBitmapUser
)
894 if ( m_cancelButton
)
896 m_cancelButton
->SetBitmapLabel( m_cancelBitmap
);
901 // the user bitmap was just cleared, generate one
908 // override streambuf method
909 #if wxHAS_TEXT_WINDOW_STREAM
911 #endif // wxHAS_TEXT_WINDOW_STREAM
913 // stream-like insertion operators: these are always available, whether we
914 // were, or not, compiled with streambuf support
915 wxTextCtrl
& operator<<(const wxString
& s
);
916 wxTextCtrl
& operator<<(int i
);
917 wxTextCtrl
& operator<<(long i
);
918 wxTextCtrl
& operator<<(float f
);
919 wxTextCtrl
& operator<<(double d
);
920 wxTextCtrl
& operator<<(const wxChar c
);
923 void wxSearchCtrl::DoSetValue(const wxString
& value
, int flags
)
925 m_text
->DoSetValue(value
, flags
);
928 bool wxSearchCtrl::DoLoadFile(const wxString
& file
, int fileType
)
930 return m_text
->DoLoadFile(file
, fileType
);
933 bool wxSearchCtrl::DoSaveFile(const wxString
& file
, int fileType
)
935 return m_text
->DoSaveFile(file
, fileType
);
938 // do the window-specific processing after processing the update event
939 void wxSearchCtrl::DoUpdateWindowUI(wxUpdateUIEvent
& event
)
941 wxSearchCtrlBase::DoUpdateWindowUI(event
);
944 bool wxSearchCtrl::ShouldInheritColours() const
949 // icons are rendered at 3-8 times larger than necessary and downscaled for
951 static int GetMultiplier()
954 // speed up bitmap generation by using a small bitmap
957 int depth
= ::wxDisplayDepth();
967 wxBitmap
wxSearchCtrl::RenderSearchBitmap( int x
, int y
, bool renderDrop
)
969 wxColour bg
= GetBackgroundColour();
970 wxColour fg
= wxStepColour(GetForegroundColour(), LIGHT_STEP
-20);
972 //===============================================================================
973 // begin drawing code
974 //===============================================================================
977 // force width:height ratio
989 // glass 11x11, top left corner
990 // handle (9,9)-(13,13)
991 // drop (13,16)-(19,6)-(16,9)
993 int multiplier
= GetMultiplier();
994 int penWidth
= multiplier
* 2;
996 penWidth
= penWidth
* x
/ 20;
998 wxBitmap
bitmap( multiplier
*x
, multiplier
*y
);
1000 mem
.SelectObject(bitmap
);
1003 mem
.SetBrush( wxBrush(bg
) );
1004 mem
.SetPen( wxPen(bg
) );
1005 mem
.DrawRectangle(0,0,bitmap
.GetWidth(),bitmap
.GetHeight());
1008 mem
.SetBrush( wxBrush(fg
) );
1009 mem
.SetPen( wxPen(fg
) );
1010 int glassBase
= 5 * x
/ 20;
1011 int glassFactor
= 2*glassBase
+ 1;
1012 int radius
= multiplier
*glassFactor
/2;
1013 mem
.DrawCircle(radius
,radius
,radius
);
1014 mem
.SetBrush( wxBrush(bg
) );
1015 mem
.SetPen( wxPen(bg
) );
1016 mem
.DrawCircle(radius
,radius
,radius
-penWidth
);
1019 int lineStart
= radius
+ (radius
-penWidth
/2) * 707 / 1000; // 707 / 1000 = 0.707 = 1/sqrt(2);
1021 mem
.SetPen( wxPen(fg
) );
1022 mem
.SetBrush( wxBrush(fg
) );
1023 int handleCornerShift
= penWidth
* 707 / 1000 / 2; // 707 / 1000 = 0.707 = 1/sqrt(2);
1024 handleCornerShift
= WXMAX( handleCornerShift
, 1 );
1025 int handleBase
= 4 * x
/ 20;
1026 int handleLength
= 2*handleBase
+1;
1027 wxPoint handlePolygon
[] =
1029 wxPoint(-handleCornerShift
,+handleCornerShift
),
1030 wxPoint(+handleCornerShift
,-handleCornerShift
),
1031 wxPoint(multiplier
*handleLength
/2+handleCornerShift
,multiplier
*handleLength
/2-handleCornerShift
),
1032 wxPoint(multiplier
*handleLength
/2-handleCornerShift
,multiplier
*handleLength
/2+handleCornerShift
),
1034 mem
.DrawPolygon(WXSIZEOF(handlePolygon
),handlePolygon
,lineStart
,lineStart
);
1036 // draw drop triangle
1037 int triangleX
= 13 * x
/ 20;
1038 int triangleY
= 5 * x
/ 20;
1039 int triangleBase
= 3 * x
/ 20;
1040 int triangleFactor
= triangleBase
*2+1;
1043 wxPoint dropPolygon
[] =
1045 wxPoint(multiplier
*0,multiplier
*0), // triangle left
1046 wxPoint(multiplier
*triangleFactor
-1,multiplier
*0), // triangle right
1047 wxPoint(multiplier
*triangleFactor
/2,multiplier
*triangleFactor
/2), // triangle bottom
1049 mem
.DrawPolygon(WXSIZEOF(dropPolygon
),dropPolygon
,multiplier
*triangleX
,multiplier
*triangleY
);
1051 mem
.SelectObject(wxNullBitmap
);
1053 //===============================================================================
1055 //===============================================================================
1057 if ( multiplier
!= 1 )
1059 wxImage image
= bitmap
.ConvertToImage();
1061 bitmap
= wxBitmap( image
);
1065 // Trim the edge where the arrow would have gone
1066 bitmap
= bitmap
.GetSubBitmap(wxRect(0,0, y
,y
));
1072 wxBitmap
wxSearchCtrl::RenderCancelBitmap( int x
, int y
)
1074 wxColour bg
= GetBackgroundColour();
1075 wxColour fg
= wxStepColour(GetForegroundColour(), LIGHT_STEP
);
1077 //===============================================================================
1078 // begin drawing code
1079 //===============================================================================
1096 // cross line starts (4,4)-(10,10)
1097 // drop (13,16)-(19,6)-(16,9)
1099 int multiplier
= GetMultiplier();
1101 int penWidth
= multiplier
* x
/ 14;
1103 wxBitmap
bitmap( multiplier
*x
, multiplier
*y
);
1105 mem
.SelectObject(bitmap
);
1108 mem
.SetBrush( wxBrush(bg
) );
1109 mem
.SetPen( wxPen(bg
) );
1110 mem
.DrawRectangle(0,0,bitmap
.GetWidth(),bitmap
.GetHeight());
1113 mem
.SetBrush( wxBrush(fg
) );
1114 mem
.SetPen( wxPen(fg
) );
1115 int radius
= multiplier
*x
/2;
1116 mem
.DrawCircle(radius
,radius
,radius
);
1119 int lineStartBase
= 4 * x
/ 14;
1120 int lineLength
= x
- 2*lineStartBase
;
1122 mem
.SetPen( wxPen(bg
) );
1123 mem
.SetBrush( wxBrush(bg
) );
1124 int handleCornerShift
= penWidth
/2;
1125 handleCornerShift
= WXMAX( handleCornerShift
, 1 );
1126 wxPoint handlePolygon
[] =
1128 wxPoint(-handleCornerShift
,+handleCornerShift
),
1129 wxPoint(+handleCornerShift
,-handleCornerShift
),
1130 wxPoint(multiplier
*lineLength
+handleCornerShift
,multiplier
*lineLength
-handleCornerShift
),
1131 wxPoint(multiplier
*lineLength
-handleCornerShift
,multiplier
*lineLength
+handleCornerShift
),
1133 mem
.DrawPolygon(WXSIZEOF(handlePolygon
),handlePolygon
,multiplier
*lineStartBase
,multiplier
*lineStartBase
);
1134 wxPoint handlePolygon2
[] =
1136 wxPoint(+handleCornerShift
,+handleCornerShift
),
1137 wxPoint(-handleCornerShift
,-handleCornerShift
),
1138 wxPoint(multiplier
*lineLength
-handleCornerShift
,-multiplier
*lineLength
-handleCornerShift
),
1139 wxPoint(multiplier
*lineLength
+handleCornerShift
,-multiplier
*lineLength
+handleCornerShift
),
1141 mem
.DrawPolygon(WXSIZEOF(handlePolygon2
),handlePolygon2
,multiplier
*lineStartBase
,multiplier
*(x
-lineStartBase
));
1143 //===============================================================================
1145 //===============================================================================
1147 if ( multiplier
!= 1 )
1149 wxImage image
= bitmap
.ConvertToImage();
1151 bitmap
= wxBitmap( image
);
1157 void wxSearchCtrl::RecalcBitmaps()
1163 wxSize sizeText
= m_text
->GetBestSize();
1165 int bitmapHeight
= sizeText
.y
- 2 * ICON_MARGIN
;
1166 int bitmapWidth
= sizeText
.y
* 20 / 14;
1168 if ( !m_searchBitmapUser
)
1171 !m_searchBitmap
.Ok() ||
1172 m_searchBitmap
.GetHeight() != bitmapHeight
||
1173 m_searchBitmap
.GetWidth() != bitmapWidth
1176 m_searchBitmap
= RenderSearchBitmap(bitmapWidth
,bitmapHeight
,false);
1179 m_searchButton
->SetBitmapLabel(m_searchBitmap
);
1182 // else this bitmap was set by user, don't alter
1186 if ( !m_searchMenuBitmapUser
)
1189 !m_searchMenuBitmap
.Ok() ||
1190 m_searchMenuBitmap
.GetHeight() != bitmapHeight
||
1191 m_searchMenuBitmap
.GetWidth() != bitmapWidth
1194 m_searchMenuBitmap
= RenderSearchBitmap(bitmapWidth
,bitmapHeight
,true);
1197 m_searchButton
->SetBitmapLabel(m_searchMenuBitmap
);
1200 // else this bitmap was set by user, don't alter
1202 #endif // wxUSE_MENUS
1204 if ( !m_cancelBitmapUser
)
1207 !m_cancelBitmap
.Ok() ||
1208 m_cancelBitmap
.GetHeight() != bitmapHeight
||
1209 m_cancelBitmap
.GetWidth() != bitmapHeight
1212 m_cancelBitmap
= RenderCancelBitmap(bitmapHeight
-BORDER
-1,bitmapHeight
-BORDER
-1); // square
1213 m_cancelButton
->SetBitmapLabel(m_cancelBitmap
);
1215 // else this bitmap was set by user, don't alter
1219 void wxSearchCtrl::OnSearchButton( wxCommandEvent
& event
)
1224 void wxSearchCtrl::OnSetFocus( wxFocusEvent
& /*event*/ )
1232 void wxSearchCtrl::OnSize( wxSizeEvent
& WXUNUSED(event
) )
1235 GetSize(&width
, &height
);
1236 LayoutControls(0, 0, width
, height
);
1241 void wxSearchCtrl::PopupSearchMenu()
1245 wxSize size
= GetSize();
1246 PopupMenu( m_menu
, 0, size
.y
);
1250 #endif // wxUSE_MENUS
1252 #endif // !wxUSE_NATIVE_SEARCH_CONTROL
1254 #endif // wxUSE_SEARCHCTRL