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 #define LIGHT_STEP 160
55 // ----------------------------------------------------------------------------
56 // wxSearchTextCtrl: text control used by search control
57 // ----------------------------------------------------------------------------
59 class wxSearchTextCtrl
: public wxTextCtrl
62 wxSearchTextCtrl(wxSearchCtrl
*search
, const wxString
& value
, int style
)
63 : wxTextCtrl(search
, wxID_ANY
, value
, wxDefaultPosition
, wxDefaultSize
,
64 (style
& ~wxBORDER_MASK
) | wxNO_BORDER
)
70 // remove the default minsize, the searchctrl will have one instead
71 SetSizeHints(wxDefaultCoord
,wxDefaultCoord
);
75 // provide access to the base class protected methods to wxSearchCtrl which
76 // needs to forward to them
77 void DoSetValue(const wxString
& value
, int flags
)
79 wxTextCtrl::DoSetValue(value
, flags
);
82 bool DoLoadFile(const wxString
& file
, int fileType
)
84 return wxTextCtrl::DoLoadFile(file
, fileType
);
87 bool DoSaveFile(const wxString
& file
, int fileType
)
89 return wxTextCtrl::DoSaveFile(file
, fileType
);
93 void OnText(wxCommandEvent
& eventText
)
95 wxCommandEvent
event(eventText
);
96 event
.SetEventObject(m_search
);
97 event
.SetId(m_search
->GetId());
99 m_search
->GetEventHandler()->ProcessEvent(event
);
102 void OnTextUrl(wxTextUrlEvent
& eventText
)
104 // copy constructor is disabled for some reason?
105 //wxTextUrlEvent event(eventText);
106 wxTextUrlEvent
event(
108 eventText
.GetMouseEvent(),
109 eventText
.GetURLStart(),
110 eventText
.GetURLEnd()
112 event
.SetEventObject(m_search
);
114 m_search
->GetEventHandler()->ProcessEvent(event
);
118 wxSearchCtrl
* m_search
;
120 DECLARE_EVENT_TABLE()
123 BEGIN_EVENT_TABLE(wxSearchTextCtrl
, wxTextCtrl
)
124 EVT_TEXT(wxID_ANY
, wxSearchTextCtrl::OnText
)
125 EVT_TEXT_ENTER(wxID_ANY
, wxSearchTextCtrl::OnText
)
126 EVT_TEXT_URL(wxID_ANY
, wxSearchTextCtrl::OnTextUrl
)
127 EVT_TEXT_MAXLEN(wxID_ANY
, wxSearchTextCtrl::OnText
)
130 // ----------------------------------------------------------------------------
131 // wxSearchButton: search button used by search control
132 // ----------------------------------------------------------------------------
134 class wxSearchButton
: public wxControl
137 wxSearchButton(wxSearchCtrl
*search
, int eventType
, const wxBitmap
& bmp
)
138 : wxControl(search
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxNO_BORDER
),
140 m_eventType(eventType
),
144 void SetBitmapLabel(const wxBitmap
& label
) { m_bmp
= label
; }
146 // The buttons in wxSearchCtrl shouldn't accept focus from keyboard because
147 // this would interfere with the usual TAB processing: the user expects
148 // that pressing TAB in the search control should switch focus to the next
149 // control and not give it to the button inside the same control. Besides,
150 // the search button can be already activated by pressing "Enter" so there
151 // is really no reason for it to be able to get focus from keyboard.
152 virtual bool AcceptsFocusFromKeyboard() const { return false; }
155 wxSize
DoGetBestSize() const
157 return wxSize(m_bmp
.GetWidth(), m_bmp
.GetHeight());
160 void OnLeftUp(wxMouseEvent
&)
162 wxCommandEvent
event(m_eventType
, m_search
->GetId());
163 event
.SetEventObject(m_search
);
165 if ( m_eventType
== wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN
)
167 // it's convenient to have the string to search for directly in the
168 // event instead of having to retrieve it from the control in the
169 // event handler code later, so provide it here
170 event
.SetString(m_search
->GetValue());
173 GetEventHandler()->ProcessEvent(event
);
175 m_search
->SetFocus();
178 if ( m_eventType
== wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN
)
180 // this happens automatically, just like on Mac OS X
181 m_search
->PopupSearchMenu();
183 #endif // wxUSE_MENUS
186 void OnPaint(wxPaintEvent
&)
189 dc
.DrawBitmap(m_bmp
, 0,0, true);
194 wxSearchCtrl
*m_search
;
195 wxEventType m_eventType
;
198 DECLARE_EVENT_TABLE()
201 BEGIN_EVENT_TABLE(wxSearchButton
, wxControl
)
202 EVT_LEFT_UP(wxSearchButton::OnLeftUp
)
203 EVT_PAINT(wxSearchButton::OnPaint
)
206 BEGIN_EVENT_TABLE(wxSearchCtrl
, wxSearchCtrlBase
)
207 EVT_SEARCHCTRL_SEARCH_BTN(wxID_ANY
, wxSearchCtrl::OnSearchButton
)
208 EVT_SET_FOCUS(wxSearchCtrl::OnSetFocus
)
209 EVT_SIZE(wxSearchCtrl::OnSize
)
212 IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl
, wxSearchCtrlBase
)
214 // ============================================================================
216 // ============================================================================
218 // ----------------------------------------------------------------------------
219 // wxSearchCtrl creation
220 // ----------------------------------------------------------------------------
225 wxSearchCtrl::wxSearchCtrl()
230 wxSearchCtrl::wxSearchCtrl(wxWindow
*parent
, wxWindowID id
,
231 const wxString
& value
,
235 const wxValidator
& validator
,
236 const wxString
& name
)
240 Create(parent
, id
, value
, pos
, size
, style
, validator
, name
);
243 void wxSearchCtrl::Init()
246 m_searchButton
= NULL
;
247 m_cancelButton
= NULL
;
250 #endif // wxUSE_MENUS
252 m_searchButtonVisible
= true;
253 m_cancelButtonVisible
= false;
255 m_searchBitmapUser
= false;
256 m_cancelBitmapUser
= false;
258 m_searchMenuBitmapUser
= false;
259 #endif // wxUSE_MENUS
262 bool wxSearchCtrl::Create(wxWindow
*parent
, wxWindowID id
,
263 const wxString
& value
,
267 const wxValidator
& validator
,
268 const wxString
& name
)
270 // force border style for more native appearance
271 style
&= ~wxBORDER_MASK
;
273 style
|= wxBORDER_SUNKEN
;
274 #elif defined(__WXMSW__)
275 // Don't set the style explicitly, let GetDefaultBorder() work it out, unless
276 // we will get a sunken border (e.g. on Windows 200) in which case we must
277 // override with a simple border.
278 if (GetDefaultBorder() == wxBORDER_SUNKEN
)
279 style
|= wxBORDER_SIMPLE
;
281 style
|= wxBORDER_SIMPLE
;
283 if ( !wxSearchCtrlBaseBaseClass::Create(parent
, id
, pos
, size
,
284 style
, validator
, name
) )
289 m_text
= new wxSearchTextCtrl(this, value
, style
);
291 m_searchButton
= new wxSearchButton(this,
292 wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN
,
294 m_cancelButton
= new wxSearchButton(this,
295 wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN
,
298 SetForegroundColour( m_text
->GetForegroundColour() );
299 SetBackgroundColour( m_text
->GetBackgroundColour() );
303 SetInitialSize(size
);
308 wxSearchCtrl::~wxSearchCtrl()
311 delete m_searchButton
;
312 delete m_cancelButton
;
315 #endif // wxUSE_MENUS
319 // search control specific interfaces
322 void wxSearchCtrl::SetMenu( wxMenu
* menu
)
324 if ( menu
== m_menu
)
329 bool hadMenu
= (m_menu
!= NULL
);
333 if ( m_menu
&& !hadMenu
)
335 m_searchButton
->SetBitmapLabel(m_searchMenuBitmap
);
336 m_searchButton
->Refresh();
338 else if ( !m_menu
&& hadMenu
)
340 m_searchButton
->SetBitmapLabel(m_searchBitmap
);
341 if ( m_searchButtonVisible
)
343 m_searchButton
->Refresh();
346 wxRect rect
= GetRect();
347 LayoutControls(0, 0, rect
.GetWidth(), rect
.GetHeight());
350 wxMenu
* wxSearchCtrl::GetMenu()
355 #endif // wxUSE_MENUS
357 void wxSearchCtrl::ShowSearchButton( bool show
)
359 if ( m_searchButtonVisible
== show
)
364 m_searchButtonVisible
= show
;
365 if ( m_searchButtonVisible
)
370 wxRect rect
= GetRect();
371 LayoutControls(0, 0, rect
.GetWidth(), rect
.GetHeight());
374 bool wxSearchCtrl::IsSearchButtonVisible() const
376 return m_searchButtonVisible
;
380 void wxSearchCtrl::ShowCancelButton( bool show
)
382 if ( m_cancelButtonVisible
== show
)
387 m_cancelButtonVisible
= show
;
389 wxRect rect
= GetRect();
390 LayoutControls(0, 0, rect
.GetWidth(), rect
.GetHeight());
393 bool wxSearchCtrl::IsCancelButtonVisible() const
395 return m_cancelButtonVisible
;
398 void wxSearchCtrl::SetDescriptiveText(const wxString
& text
)
400 m_text
->SetHint(text
);
403 wxString
wxSearchCtrl::GetDescriptiveText() const
405 return m_text
->GetHint();
408 // ----------------------------------------------------------------------------
410 // ----------------------------------------------------------------------------
412 wxSize
wxSearchCtrl::DoGetBestSize() const
414 wxSize sizeText
= m_text
->GetBestSize();
415 wxSize
sizeSearch(0,0);
416 wxSize
sizeCancel(0,0);
417 int searchMargin
= 0;
418 int cancelMargin
= 0;
419 if ( m_searchButtonVisible
|| HasMenu() )
421 sizeSearch
= m_searchButton
->GetBestSize();
422 searchMargin
= MARGIN
;
424 if ( m_cancelButtonVisible
)
426 sizeCancel
= m_cancelButton
->GetBestSize();
427 cancelMargin
= MARGIN
;
430 int horizontalBorder
= 1 + ( sizeText
.y
- sizeText
.y
* 14 / 21 ) / 2;
432 // buttons are square and equal to the height of the text control
433 int height
= sizeText
.y
;
434 return wxSize(sizeSearch
.x
+ searchMargin
+ sizeText
.x
+ cancelMargin
+ sizeCancel
.x
+ 2*horizontalBorder
,
438 void wxSearchCtrl::DoMoveWindow(int x
, int y
, int width
, int height
)
440 wxSearchCtrlBase::DoMoveWindow(x
, y
, width
, height
);
442 LayoutControls(0, 0, width
, height
);
445 void wxSearchCtrl::LayoutControls(int x
, int y
, int width
, int height
)
450 wxSize sizeText
= m_text
->GetBestSize();
451 // make room for the search menu & clear button
452 int horizontalBorder
= ( sizeText
.y
- sizeText
.y
* 14 / 21 ) / 2;
453 x
+= horizontalBorder
;
455 width
-= horizontalBorder
*2;
457 if (width
< 0) width
= 0;
458 if (height
< 0) height
= 0;
460 wxSize
sizeSearch(0,0);
461 wxSize
sizeCancel(0,0);
462 int searchMargin
= 0;
463 int cancelMargin
= 0;
464 if ( m_searchButtonVisible
|| HasMenu() )
466 sizeSearch
= m_searchButton
->GetBestSize();
467 searchMargin
= MARGIN
;
469 if ( m_cancelButtonVisible
)
471 sizeCancel
= m_cancelButton
->GetBestSize();
472 cancelMargin
= MARGIN
;
474 m_searchButton
->Show( m_searchButtonVisible
|| HasMenu() );
475 m_cancelButton
->Show( m_cancelButtonVisible
);
477 if ( sizeSearch
.x
+ sizeCancel
.x
> width
)
479 sizeSearch
.x
= width
/2;
480 sizeCancel
.x
= width
/2;
484 wxCoord textWidth
= width
- sizeSearch
.x
- sizeCancel
.x
- searchMargin
- cancelMargin
- 1;
485 if (textWidth
< 0) textWidth
= 0;
487 // position the subcontrols inside the client area
489 m_searchButton
->SetSize(x
, y
+ ICON_OFFSET
- 1, sizeSearch
.x
, height
);
490 m_text
->SetSize( x
+ sizeSearch
.x
+ searchMargin
,
491 y
+ ICON_OFFSET
- BORDER
,
494 m_cancelButton
->SetSize(x
+ sizeSearch
.x
+ searchMargin
+ textWidth
+ cancelMargin
,
495 y
+ ICON_OFFSET
- 1, sizeCancel
.x
, height
);
498 wxWindowList
wxSearchCtrl::GetCompositeWindowParts() const
501 parts
.push_back(m_text
);
502 parts
.push_back(m_searchButton
);
503 parts
.push_back(m_cancelButton
);
510 wxString
wxSearchCtrl::DoGetValue() const
512 return m_text
->GetValue();
514 wxString
wxSearchCtrl::GetRange(long from
, long to
) const
516 return m_text
->GetRange(from
, to
);
519 int wxSearchCtrl::GetLineLength(long lineNo
) const
521 return m_text
->GetLineLength(lineNo
);
523 wxString
wxSearchCtrl::GetLineText(long lineNo
) const
525 return m_text
->GetLineText(lineNo
);
527 int wxSearchCtrl::GetNumberOfLines() const
529 return m_text
->GetNumberOfLines();
532 bool wxSearchCtrl::IsModified() const
534 return m_text
->IsModified();
536 bool wxSearchCtrl::IsEditable() const
538 return m_text
->IsEditable();
541 // more readable flag testing methods
542 bool wxSearchCtrl::IsSingleLine() const
544 return m_text
->IsSingleLine();
546 bool wxSearchCtrl::IsMultiLine() const
548 return m_text
->IsMultiLine();
551 // If the return values from and to are the same, there is no selection.
552 void wxSearchCtrl::GetSelection(long* from
, long* to
) const
554 m_text
->GetSelection(from
, to
);
557 wxString
wxSearchCtrl::GetStringSelection() const
559 return m_text
->GetStringSelection();
566 void wxSearchCtrl::Clear()
570 void wxSearchCtrl::Replace(long from
, long to
, const wxString
& value
)
572 m_text
->Replace(from
, to
, value
);
574 void wxSearchCtrl::Remove(long from
, long to
)
576 m_text
->Remove(from
, to
);
579 // load/save the controls contents from/to the file
580 bool wxSearchCtrl::LoadFile(const wxString
& file
)
582 return m_text
->LoadFile(file
);
584 bool wxSearchCtrl::SaveFile(const wxString
& file
)
586 return m_text
->SaveFile(file
);
589 // sets/clears the dirty flag
590 void wxSearchCtrl::MarkDirty()
594 void wxSearchCtrl::DiscardEdits()
596 m_text
->DiscardEdits();
599 // set the max number of characters which may be entered in a single line
601 void wxSearchCtrl::SetMaxLength(unsigned long len
)
603 m_text
->SetMaxLength(len
);
606 // writing text inserts it at the current position, appending always
607 // inserts it at the end
608 void wxSearchCtrl::WriteText(const wxString
& text
)
610 m_text
->WriteText(text
);
612 void wxSearchCtrl::AppendText(const wxString
& text
)
614 m_text
->AppendText(text
);
617 // insert the character which would have resulted from this key event,
618 // return true if anything has been inserted
619 bool wxSearchCtrl::EmulateKeyPress(const wxKeyEvent
& event
)
621 return m_text
->EmulateKeyPress(event
);
624 // text control under some platforms supports the text styles: these
625 // methods allow to apply the given text style to the given selection or to
626 // set/get the style which will be used for all appended text
627 bool wxSearchCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
629 return m_text
->SetStyle(start
, end
, style
);
631 bool wxSearchCtrl::GetStyle(long position
, wxTextAttr
& style
)
633 return m_text
->GetStyle(position
, style
);
635 bool wxSearchCtrl::SetDefaultStyle(const wxTextAttr
& style
)
637 return m_text
->SetDefaultStyle(style
);
639 const wxTextAttr
& wxSearchCtrl::GetDefaultStyle() const
641 return m_text
->GetDefaultStyle();
644 // translate between the position (which is just an index in the text ctrl
645 // considering all its contents as a single strings) and (x, y) coordinates
646 // which represent column and line.
647 long wxSearchCtrl::XYToPosition(long x
, long y
) const
649 return m_text
->XYToPosition(x
, y
);
651 bool wxSearchCtrl::PositionToXY(long pos
, long *x
, long *y
) const
653 return m_text
->PositionToXY(pos
, x
, y
);
656 void wxSearchCtrl::ShowPosition(long pos
)
658 m_text
->ShowPosition(pos
);
661 // find the character at position given in pixels
663 // NB: pt is in device coords (not adjusted for the client area origin nor
665 wxTextCtrlHitTestResult
wxSearchCtrl::HitTest(const wxPoint
& pt
, long *pos
) const
667 return m_text
->HitTest(pt
, pos
);
669 wxTextCtrlHitTestResult
wxSearchCtrl::HitTest(const wxPoint
& pt
,
671 wxTextCoord
*row
) const
673 return m_text
->HitTest(pt
, col
, row
);
676 // Clipboard operations
677 void wxSearchCtrl::Copy()
681 void wxSearchCtrl::Cut()
685 void wxSearchCtrl::Paste()
690 bool wxSearchCtrl::CanCopy() const
692 return m_text
->CanCopy();
694 bool wxSearchCtrl::CanCut() const
696 return m_text
->CanCut();
698 bool wxSearchCtrl::CanPaste() const
700 return m_text
->CanPaste();
704 void wxSearchCtrl::Undo()
708 void wxSearchCtrl::Redo()
713 bool wxSearchCtrl::CanUndo() const
715 return m_text
->CanUndo();
717 bool wxSearchCtrl::CanRedo() const
719 return m_text
->CanRedo();
723 void wxSearchCtrl::SetInsertionPoint(long pos
)
725 m_text
->SetInsertionPoint(pos
);
727 void wxSearchCtrl::SetInsertionPointEnd()
729 m_text
->SetInsertionPointEnd();
731 long wxSearchCtrl::GetInsertionPoint() const
733 return m_text
->GetInsertionPoint();
735 long wxSearchCtrl::GetLastPosition() const
737 return m_text
->GetLastPosition();
740 void wxSearchCtrl::SetSelection(long from
, long to
)
742 m_text
->SetSelection(from
, to
);
744 void wxSearchCtrl::SelectAll()
749 void wxSearchCtrl::SetEditable(bool editable
)
751 m_text
->SetEditable(editable
);
754 bool wxSearchCtrl::SetFont(const wxFont
& font
)
756 if ( !wxSearchCtrlBase::SetFont(font
) )
759 // Recreate the bitmaps as their size may have changed.
765 bool wxSearchCtrl::SetBackgroundColour(const wxColour
& colour
)
767 if ( !wxSearchCtrlBase::SetBackgroundColour(colour
) )
770 // When the background changes, re-render the bitmaps so that the correct
771 // colour shows in their "transparent" area.
777 // search control generic only
778 void wxSearchCtrl::SetSearchBitmap( const wxBitmap
& bitmap
)
780 m_searchBitmap
= bitmap
;
781 m_searchBitmapUser
= bitmap
.IsOk();
782 if ( m_searchBitmapUser
)
784 if ( m_searchButton
&& !HasMenu() )
786 m_searchButton
->SetBitmapLabel( m_searchBitmap
);
791 // the user bitmap was just cleared, generate one
798 void wxSearchCtrl::SetSearchMenuBitmap( const wxBitmap
& bitmap
)
800 m_searchMenuBitmap
= bitmap
;
801 m_searchMenuBitmapUser
= bitmap
.IsOk();
802 if ( m_searchMenuBitmapUser
)
804 if ( m_searchButton
&& m_menu
)
806 m_searchButton
->SetBitmapLabel( m_searchMenuBitmap
);
811 // the user bitmap was just cleared, generate one
816 #endif // wxUSE_MENUS
818 void wxSearchCtrl::SetCancelBitmap( const wxBitmap
& bitmap
)
820 m_cancelBitmap
= bitmap
;
821 m_cancelBitmapUser
= bitmap
.IsOk();
822 if ( m_cancelBitmapUser
)
824 if ( m_cancelButton
)
826 m_cancelButton
->SetBitmapLabel( m_cancelBitmap
);
831 // the user bitmap was just cleared, generate one
838 // override streambuf method
839 #if wxHAS_TEXT_WINDOW_STREAM
841 #endif // wxHAS_TEXT_WINDOW_STREAM
843 // stream-like insertion operators: these are always available, whether we
844 // were, or not, compiled with streambuf support
845 wxTextCtrl
& operator<<(const wxString
& s
);
846 wxTextCtrl
& operator<<(int i
);
847 wxTextCtrl
& operator<<(long i
);
848 wxTextCtrl
& operator<<(float f
);
849 wxTextCtrl
& operator<<(double d
);
850 wxTextCtrl
& operator<<(const wxChar c
);
853 void wxSearchCtrl::DoSetValue(const wxString
& value
, int flags
)
855 m_text
->DoSetValue(value
, flags
);
858 bool wxSearchCtrl::DoLoadFile(const wxString
& file
, int fileType
)
860 return m_text
->DoLoadFile(file
, fileType
);
863 bool wxSearchCtrl::DoSaveFile(const wxString
& file
, int fileType
)
865 return m_text
->DoSaveFile(file
, fileType
);
868 // do the window-specific processing after processing the update event
869 void wxSearchCtrl::DoUpdateWindowUI(wxUpdateUIEvent
& event
)
871 wxSearchCtrlBase::DoUpdateWindowUI(event
);
874 bool wxSearchCtrl::ShouldInheritColours() const
879 // icons are rendered at 3-8 times larger than necessary and downscaled for
881 static int GetMultiplier()
884 // speed up bitmap generation by using a small bitmap
887 int depth
= ::wxDisplayDepth();
897 wxBitmap
wxSearchCtrl::RenderSearchBitmap( int x
, int y
, bool renderDrop
)
899 wxColour bg
= GetBackgroundColour();
900 wxColour fg
= GetForegroundColour().ChangeLightness(LIGHT_STEP
-20);
902 //===============================================================================
903 // begin drawing code
904 //===============================================================================
907 // force width:height ratio
919 // glass 11x11, top left corner
920 // handle (9,9)-(13,13)
921 // drop (13,16)-(19,6)-(16,9)
923 int multiplier
= GetMultiplier();
924 int penWidth
= multiplier
* 2;
926 penWidth
= penWidth
* x
/ 20;
928 wxBitmap
bitmap( multiplier
*x
, multiplier
*y
);
930 mem
.SelectObject(bitmap
);
933 mem
.SetBrush( wxBrush(bg
) );
934 mem
.SetPen( wxPen(bg
) );
935 mem
.DrawRectangle(0,0,bitmap
.GetWidth(),bitmap
.GetHeight());
938 mem
.SetBrush( wxBrush(fg
) );
939 mem
.SetPen( wxPen(fg
) );
940 int glassBase
= 5 * x
/ 20;
941 int glassFactor
= 2*glassBase
+ 1;
942 int radius
= multiplier
*glassFactor
/2;
943 mem
.DrawCircle(radius
,radius
,radius
);
944 mem
.SetBrush( wxBrush(bg
) );
945 mem
.SetPen( wxPen(bg
) );
946 mem
.DrawCircle(radius
,radius
,radius
-penWidth
);
949 int lineStart
= radius
+ (radius
-penWidth
/2) * 707 / 1000; // 707 / 1000 = 0.707 = 1/sqrt(2);
951 mem
.SetPen( wxPen(fg
) );
952 mem
.SetBrush( wxBrush(fg
) );
953 int handleCornerShift
= penWidth
* 707 / 1000 / 2; // 707 / 1000 = 0.707 = 1/sqrt(2);
954 handleCornerShift
= WXMAX( handleCornerShift
, 1 );
955 int handleBase
= 4 * x
/ 20;
956 int handleLength
= 2*handleBase
+1;
957 wxPoint handlePolygon
[] =
959 wxPoint(-handleCornerShift
,+handleCornerShift
),
960 wxPoint(+handleCornerShift
,-handleCornerShift
),
961 wxPoint(multiplier
*handleLength
/2+handleCornerShift
,multiplier
*handleLength
/2-handleCornerShift
),
962 wxPoint(multiplier
*handleLength
/2-handleCornerShift
,multiplier
*handleLength
/2+handleCornerShift
),
964 mem
.DrawPolygon(WXSIZEOF(handlePolygon
),handlePolygon
,lineStart
,lineStart
);
966 // draw drop triangle
967 int triangleX
= 13 * x
/ 20;
968 int triangleY
= 5 * x
/ 20;
969 int triangleBase
= 3 * x
/ 20;
970 int triangleFactor
= triangleBase
*2+1;
973 wxPoint dropPolygon
[] =
975 wxPoint(multiplier
*0,multiplier
*0), // triangle left
976 wxPoint(multiplier
*triangleFactor
-1,multiplier
*0), // triangle right
977 wxPoint(multiplier
*triangleFactor
/2,multiplier
*triangleFactor
/2), // triangle bottom
979 mem
.DrawPolygon(WXSIZEOF(dropPolygon
),dropPolygon
,multiplier
*triangleX
,multiplier
*triangleY
);
981 mem
.SelectObject(wxNullBitmap
);
983 //===============================================================================
985 //===============================================================================
987 if ( multiplier
!= 1 )
989 wxImage image
= bitmap
.ConvertToImage();
991 bitmap
= wxBitmap( image
);
995 // Trim the edge where the arrow would have gone
996 bitmap
= bitmap
.GetSubBitmap(wxRect(0,0, y
,y
));
1002 wxBitmap
wxSearchCtrl::RenderCancelBitmap( int x
, int y
)
1004 wxColour bg
= GetBackgroundColour();
1005 wxColour fg
= GetForegroundColour().ChangeLightness(LIGHT_STEP
);
1007 //===============================================================================
1008 // begin drawing code
1009 //===============================================================================
1026 // cross line starts (4,4)-(10,10)
1027 // drop (13,16)-(19,6)-(16,9)
1029 int multiplier
= GetMultiplier();
1031 int penWidth
= multiplier
* x
/ 14;
1033 wxBitmap
bitmap( multiplier
*x
, multiplier
*y
);
1035 mem
.SelectObject(bitmap
);
1038 mem
.SetBrush( wxBrush(bg
) );
1039 mem
.SetPen( wxPen(bg
) );
1040 mem
.DrawRectangle(0,0,bitmap
.GetWidth(),bitmap
.GetHeight());
1043 mem
.SetBrush( wxBrush(fg
) );
1044 mem
.SetPen( wxPen(fg
) );
1045 int radius
= multiplier
*x
/2;
1046 mem
.DrawCircle(radius
,radius
,radius
);
1049 int lineStartBase
= 4 * x
/ 14;
1050 int lineLength
= x
- 2*lineStartBase
;
1052 mem
.SetPen( wxPen(bg
) );
1053 mem
.SetBrush( wxBrush(bg
) );
1054 int handleCornerShift
= penWidth
/2;
1055 handleCornerShift
= WXMAX( handleCornerShift
, 1 );
1056 wxPoint handlePolygon
[] =
1058 wxPoint(-handleCornerShift
,+handleCornerShift
),
1059 wxPoint(+handleCornerShift
,-handleCornerShift
),
1060 wxPoint(multiplier
*lineLength
+handleCornerShift
,multiplier
*lineLength
-handleCornerShift
),
1061 wxPoint(multiplier
*lineLength
-handleCornerShift
,multiplier
*lineLength
+handleCornerShift
),
1063 mem
.DrawPolygon(WXSIZEOF(handlePolygon
),handlePolygon
,multiplier
*lineStartBase
,multiplier
*lineStartBase
);
1064 wxPoint handlePolygon2
[] =
1066 wxPoint(+handleCornerShift
,+handleCornerShift
),
1067 wxPoint(-handleCornerShift
,-handleCornerShift
),
1068 wxPoint(multiplier
*lineLength
-handleCornerShift
,-multiplier
*lineLength
-handleCornerShift
),
1069 wxPoint(multiplier
*lineLength
+handleCornerShift
,-multiplier
*lineLength
+handleCornerShift
),
1071 mem
.DrawPolygon(WXSIZEOF(handlePolygon2
),handlePolygon2
,multiplier
*lineStartBase
,multiplier
*(x
-lineStartBase
));
1073 //===============================================================================
1075 //===============================================================================
1077 if ( multiplier
!= 1 )
1079 wxImage image
= bitmap
.ConvertToImage();
1081 bitmap
= wxBitmap( image
);
1087 void wxSearchCtrl::RecalcBitmaps()
1093 wxSize sizeText
= m_text
->GetBestSize();
1095 int bitmapHeight
= sizeText
.y
- 2 * ICON_MARGIN
;
1096 int bitmapWidth
= sizeText
.y
* 20 / 14;
1098 if ( !m_searchBitmapUser
)
1101 !m_searchBitmap
.IsOk() ||
1102 m_searchBitmap
.GetHeight() != bitmapHeight
||
1103 m_searchBitmap
.GetWidth() != bitmapWidth
1106 m_searchBitmap
= RenderSearchBitmap(bitmapWidth
,bitmapHeight
,false);
1109 m_searchButton
->SetBitmapLabel(m_searchBitmap
);
1112 // else this bitmap was set by user, don't alter
1116 if ( !m_searchMenuBitmapUser
)
1119 !m_searchMenuBitmap
.IsOk() ||
1120 m_searchMenuBitmap
.GetHeight() != bitmapHeight
||
1121 m_searchMenuBitmap
.GetWidth() != bitmapWidth
1124 m_searchMenuBitmap
= RenderSearchBitmap(bitmapWidth
,bitmapHeight
,true);
1127 m_searchButton
->SetBitmapLabel(m_searchMenuBitmap
);
1130 // else this bitmap was set by user, don't alter
1132 #endif // wxUSE_MENUS
1134 if ( !m_cancelBitmapUser
)
1137 !m_cancelBitmap
.IsOk() ||
1138 m_cancelBitmap
.GetHeight() != bitmapHeight
||
1139 m_cancelBitmap
.GetWidth() != bitmapHeight
1142 m_cancelBitmap
= RenderCancelBitmap(bitmapHeight
-BORDER
-1,bitmapHeight
-BORDER
-1); // square
1143 m_cancelButton
->SetBitmapLabel(m_cancelBitmap
);
1145 // else this bitmap was set by user, don't alter
1149 void wxSearchCtrl::OnSearchButton( wxCommandEvent
& event
)
1154 void wxSearchCtrl::OnSetFocus( wxFocusEvent
& /*event*/ )
1162 void wxSearchCtrl::OnSize( wxSizeEvent
& WXUNUSED(event
) )
1165 GetSize(&width
, &height
);
1166 LayoutControls(0, 0, width
, height
);
1171 void wxSearchCtrl::PopupSearchMenu()
1175 wxSize size
= GetSize();
1176 PopupMenu( m_menu
, 0, size
.y
);
1180 #endif // wxUSE_MENUS
1182 #endif // !wxUSE_NATIVE_SEARCH_CONTROL
1184 #endif // wxUSE_SEARCHCTRL