]> git.saurik.com Git - wxWidgets.git/blame - src/generic/srchctlg.cpp
reSWIGged
[wxWidgets.git] / src / generic / srchctlg.cpp
CommitLineData
3f7f284d
RD
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/generic/srchctlg.cpp
3// Purpose: implements wxSearchCtrl as a composite control
4// Author: Vince Harron
3f7f284d 5// Created: 2006-02-19
8bc333d7 6// RCS-ID: $Id$
3f7f284d
RD
7// Copyright: Vince Harron
8// License: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
3f7f284d
RD
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
09d93215
PC
18#if wxUSE_SEARCHCTRL
19
20#include "wx/srchctrl.h"
21
3f7f284d
RD
22#ifndef WX_PRECOMP
23 #include "wx/button.h"
38f74dff
CE
24 #include "wx/dcclient.h"
25 #include "wx/menu.h"
26 #include "wx/dcmemory.h"
3f7f284d
RD
27#endif //WX_PRECOMP
28
5b43c75c 29#if !wxUSE_NATIVE_SEARCH_CONTROL
3f7f284d
RD
30
31#include "wx/image.h"
32
09d93215 33#define WXMAX(a,b) ((a)>(b)?(a):(b))
3f7f284d
RD
34
35// ----------------------------------------------------------------------------
36// constants
37// ----------------------------------------------------------------------------
38
39// the margin between the text control and the search/cancel buttons
40static const wxCoord MARGIN = 2;
41
42// border around all controls to compensate for wxSIMPLE_BORDER
43#if defined(__WXMSW__)
44static const wxCoord BORDER = 0;
45static const wxCoord ICON_MARGIN = 2;
46static const wxCoord ICON_OFFSET = 2;
47#else
48static const wxCoord BORDER = 2;
49static const wxCoord ICON_MARGIN = 0;
50static const wxCoord ICON_OFFSET = 0;
51#endif
52
53// ----------------------------------------------------------------------------
54// wxSearchTextCtrl: text control used by search control
55// ----------------------------------------------------------------------------
56
57class wxSearchTextCtrl : public wxTextCtrl
58{
59public:
60 wxSearchTextCtrl(wxSearchCtrl *search, const wxString& value, int style)
61 : wxTextCtrl(search, wxID_ANY, value, wxDefaultPosition, wxDefaultSize,
62 style | wxNO_BORDER)
63 {
64 m_search = search;
8bc333d7 65
3f7f284d
RD
66 // remove the default minsize, the searchctrl will have one instead
67 SetSizeHints(wxDefaultCoord,wxDefaultCoord);
68 }
69
70protected:
71 void OnText(wxCommandEvent& eventText)
72 {
73 wxCommandEvent event(eventText);
74 event.SetEventObject(m_search);
75 event.SetId(m_search->GetId());
76
77 m_search->GetEventHandler()->ProcessEvent(event);
78 }
79
80 void OnTextUrl(wxTextUrlEvent& eventText)
81 {
82 // copy constructor is disabled for some reason?
83 //wxTextUrlEvent event(eventText);
84 wxTextUrlEvent event(
8bc333d7 85 m_search->GetId(),
3f7f284d
RD
86 eventText.GetMouseEvent(),
87 eventText.GetURLStart(),
88 eventText.GetURLEnd()
89 );
90 event.SetEventObject(m_search);
91
92 m_search->GetEventHandler()->ProcessEvent(event);
93 }
94
95private:
96 wxSearchCtrl* m_search;
97
98 DECLARE_EVENT_TABLE()
99};
100
101BEGIN_EVENT_TABLE(wxSearchTextCtrl, wxTextCtrl)
102 EVT_TEXT(wxID_ANY, wxSearchTextCtrl::OnText)
103 EVT_TEXT_ENTER(wxID_ANY, wxSearchTextCtrl::OnText)
104 EVT_TEXT_URL(wxID_ANY, wxSearchTextCtrl::OnTextUrl)
105 EVT_TEXT_MAXLEN(wxID_ANY, wxSearchTextCtrl::OnText)
106END_EVENT_TABLE()
107
108// ----------------------------------------------------------------------------
109// wxSearchButton: search button used by search control
110// ----------------------------------------------------------------------------
111
112class wxSearchButton : public wxControl
113{
114public:
115 wxSearchButton(wxSearchCtrl *search, int eventType, const wxBitmap& bmp)
116 : wxControl(search, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER),
117 m_search(search),
118 m_eventType(eventType),
119 m_bmp(bmp)
120 { }
121
122 void SetBitmapLabel(const wxBitmap& label) { m_bmp = label; }
123
8bc333d7 124
3f7f284d
RD
125protected:
126 wxSize DoGetBestSize() const
127 {
128 return wxSize(m_bmp.GetWidth(), m_bmp.GetHeight());
129 }
8bc333d7 130
3f7f284d
RD
131 void OnLeftUp(wxMouseEvent&)
132 {
133 wxCommandEvent event(m_eventType, m_search->GetId());
134 event.SetEventObject(m_search);
135
136 GetEventHandler()->ProcessEvent(event);
137
138 m_search->SetFocus();
139
140 if ( m_eventType == wxEVT_COMMAND_SEARCHCTRL_SEARCH )
141 {
142 // this happens automatically, just like on Mac OS X
143 m_search->PopupSearchMenu();
144 }
145 }
146
147 void OnPaint(wxPaintEvent&)
148 {
149 wxPaintDC dc(this);
150 dc.DrawBitmap(m_bmp, 0,0, true);
151 }
152
8bc333d7 153
3f7f284d
RD
154private:
155 wxSearchCtrl *m_search;
156 wxEventType m_eventType;
157 wxBitmap m_bmp;
158
159 DECLARE_EVENT_TABLE()
160};
161
6f011faa 162BEGIN_EVENT_TABLE(wxSearchButton, wxControl)
3f7f284d
RD
163 EVT_LEFT_UP(wxSearchButton::OnLeftUp)
164 EVT_PAINT(wxSearchButton::OnPaint)
165END_EVENT_TABLE()
166
167BEGIN_EVENT_TABLE(wxSearchCtrl, wxSearchCtrlBase)
168 EVT_SEARCHCTRL_SEARCH(wxID_ANY, wxSearchCtrl::OnSearchButton)
169 EVT_SET_FOCUS(wxSearchCtrl::OnSetFocus)
170END_EVENT_TABLE()
171
172IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl, wxSearchCtrlBase)
173
174// ============================================================================
175// implementation
176// ============================================================================
177
178// ----------------------------------------------------------------------------
179// wxSearchCtrl creation
180// ----------------------------------------------------------------------------
181
182// creation
183// --------
184
185wxSearchCtrl::wxSearchCtrl()
8bc333d7 186{
3f7f284d
RD
187 Init();
188}
189
190wxSearchCtrl::wxSearchCtrl(wxWindow *parent, wxWindowID id,
191 const wxString& value,
192 const wxPoint& pos,
193 const wxSize& size,
194 long style,
195 const wxValidator& validator,
196 const wxString& name)
197{
198 Init();
199
200 Create(parent, id, value, pos, size, style, validator, name);
201}
202
203void wxSearchCtrl::Init()
204{
205 m_text = 0;
206 m_searchButton = 0;
207 m_cancelButton = 0;
208 m_menu = 0;
209
210 m_searchButtonVisible = true;
211 m_cancelButtonVisible = false;
212
213 m_searchMenuBitmapUser = false;
214 m_searchBitmapUser = false;
215 m_cancelBitmapUser = false;
216}
217
218bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id,
219 const wxString& value,
220 const wxPoint& pos,
221 const wxSize& size,
222 long style,
223 const wxValidator& validator,
224 const wxString& name)
225{
226 if ( !wxTextCtrlBase::Create(parent, id, pos, size, wxSIMPLE_BORDER | style, validator, name) )
227 {
228 return false;
229 }
230
231 m_text = new wxSearchTextCtrl(this, value, style & ~wxBORDER_MASK);
232
3f7f284d
RD
233 m_searchButton = new wxSearchButton(this,wxEVT_COMMAND_SEARCHCTRL_SEARCH,m_searchBitmap);
234 m_cancelButton = new wxSearchButton(this,wxEVT_COMMAND_SEARCHCTRL_CANCEL,m_cancelBitmap);
235
236 SetForegroundColour( m_text->GetForegroundColour() );
237 m_searchButton->SetForegroundColour( m_text->GetForegroundColour() );
238 m_cancelButton->SetForegroundColour( m_text->GetForegroundColour() );
239
240 SetBackgroundColour( m_text->GetBackgroundColour() );
241 m_searchButton->SetBackgroundColour( m_text->GetBackgroundColour() );
242 m_cancelButton->SetBackgroundColour( m_text->GetBackgroundColour() );
243
244 RecalcBitmaps();
245
246 SetInitialSize(size);
247 Move(pos);
248 return true;
249}
250
251wxSearchCtrl::~wxSearchCtrl()
252{
253 delete m_text;
254 delete m_searchButton;
255 delete m_cancelButton;
256 delete m_menu;
257}
258
259
260// search control specific interfaces
261void wxSearchCtrl::SetMenu( wxMenu* menu )
262{
263 if ( menu == m_menu )
264 {
265 // no change
266 return;
267 }
09d93215 268 bool hadMenu = (m_menu != NULL);
3f7f284d 269 delete m_menu;
3f7f284d
RD
270 m_menu = menu;
271
272 if ( m_menu && !hadMenu )
273 {
274 m_searchButton->SetBitmapLabel(m_searchMenuBitmap);
275 m_searchButton->Refresh();
276 if ( !m_searchButtonVisible )
277 {
278 // adding the menu will force the search button to be visible
279 wxRect rect = GetRect();
280 LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight());
281 }
282 }
283 else if ( !m_menu && hadMenu )
284 {
285 m_searchButton->SetBitmapLabel(m_searchBitmap);
286 if ( m_searchButtonVisible )
287 {
288 m_searchButton->Refresh();
289 }
290 else
291 {
292 wxRect rect = GetRect();
293 LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight());
294 }
295 }
296}
297
298wxMenu* wxSearchCtrl::GetMenu()
299{
300 return m_menu;
301}
302
ec184e32 303void wxSearchCtrl::ShowSearchButton( bool show )
3f7f284d
RD
304{
305 if ( m_searchButtonVisible == show )
306 {
307 // no change
308 return;
309 }
310 m_searchButtonVisible = show;
311 if ( m_searchButtonVisible )
312 {
313 RecalcBitmaps();
314 }
315
316 wxRect rect = GetRect();
317 LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight());
318}
319
ec184e32 320bool wxSearchCtrl::IsSearchButtonVisible() const
3f7f284d
RD
321{
322 return m_searchButtonVisible;
323}
324
325
ec184e32 326void wxSearchCtrl::ShowCancelButton( bool show )
3f7f284d
RD
327{
328 if ( m_cancelButtonVisible == show )
329 {
330 // no change
331 return;
332 }
333 m_cancelButtonVisible = show;
334
335 wxRect rect = GetRect();
336 LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight());
337}
338
ec184e32 339bool wxSearchCtrl::IsCancelButtonVisible() const
3f7f284d
RD
340{
341 return m_cancelButtonVisible;
342}
343
344
345// ----------------------------------------------------------------------------
346// geometry
347// ----------------------------------------------------------------------------
348
349wxSize wxSearchCtrl::DoGetBestSize() const
350{
351 wxSize sizeText = m_text->GetBestSize();
352 wxSize sizeSearch(0,0);
353 wxSize sizeCancel(0,0);
354 int searchMargin = 0;
355 int cancelMargin = 0;
356 if ( m_searchButtonVisible || m_menu )
357 {
358 sizeSearch = m_searchButton->GetBestSize();
359 searchMargin = MARGIN;
360 }
361 if ( m_cancelButtonVisible )
362 {
363 sizeCancel = m_cancelButton->GetBestSize();
364 cancelMargin = MARGIN;
365 }
366
367 int horizontalBorder = 1 + ( sizeText.y - sizeText.y * 14 / 21 ) / 2;
368
369 // buttons are square and equal to the height of the text control
370 int height = sizeText.y;
371 return wxSize(sizeSearch.x + searchMargin + sizeText.x + cancelMargin + sizeCancel.x + 2*horizontalBorder,
372 height + 2*BORDER);
373}
374
375void wxSearchCtrl::DoMoveWindow(int x, int y, int width, int height)
376{
377 wxSearchCtrlBase::DoMoveWindow(x, y, width, height);
378
379 LayoutControls(0, 0, width, height);
380}
381
382void wxSearchCtrl::LayoutControls(int x, int y, int width, int height)
383{
384 wxSize sizeText = m_text->GetBestSize();
385 // make room for the search menu & clear button
386 int horizontalBorder = 1 + ( sizeText.y - sizeText.y * 14 / 21 ) / 2;
387 x += horizontalBorder;
388 y += BORDER;
389 width -= horizontalBorder*2;
390 height -= BORDER*2;
391
392 wxSize sizeSearch(0,0);
393 wxSize sizeCancel(0,0);
394 int searchMargin = 0;
395 int cancelMargin = 0;
396 if ( m_searchButtonVisible || m_menu )
397 {
398 sizeSearch = m_searchButton->GetBestSize();
399 searchMargin = MARGIN;
400 }
401 if ( m_cancelButtonVisible )
402 {
403 sizeCancel = m_cancelButton->GetBestSize();
404 cancelMargin = MARGIN;
405 }
406 m_searchButton->Show( m_searchButtonVisible || m_menu );
407 m_cancelButton->Show( m_cancelButtonVisible );
408
409 if ( sizeSearch.x + sizeCancel.x > width )
410 {
411 sizeSearch.x = width/2;
412 sizeCancel.x = width/2;
413 searchMargin = 0;
414 cancelMargin = 0;
415 }
416 wxCoord textWidth = width - sizeSearch.x - sizeCancel.x - searchMargin - cancelMargin;
417
418 // position the subcontrols inside the client area
419
420 m_searchButton->SetSize(x, y + ICON_OFFSET, sizeSearch.x, height);
421 m_text->SetSize(x + sizeSearch.x + searchMargin, y + ICON_OFFSET, textWidth, height);
422 m_cancelButton->SetSize(x + sizeSearch.x + searchMargin + textWidth + cancelMargin,
423 y + ICON_OFFSET, sizeCancel.x, height);
424}
425
426
427// accessors
428// ---------
429
430wxString wxSearchCtrl::GetValue() const
431{
432 return m_text->GetValue();
433}
434void wxSearchCtrl::SetValue(const wxString& value)
435{
436 m_text->SetValue(value);
437}
438
439wxString wxSearchCtrl::GetRange(long from, long to) const
440{
441 return m_text->GetRange(from, to);
442}
443
444int wxSearchCtrl::GetLineLength(long lineNo) const
445{
446 return m_text->GetLineLength(lineNo);
447}
448wxString wxSearchCtrl::GetLineText(long lineNo) const
449{
450 return m_text->GetLineText(lineNo);
451}
452int wxSearchCtrl::GetNumberOfLines() const
453{
454 return m_text->GetNumberOfLines();
455}
456
457bool wxSearchCtrl::IsModified() const
458{
459 return m_text->IsModified();
460}
461bool wxSearchCtrl::IsEditable() const
462{
463 return m_text->IsEditable();
464}
465
466// more readable flag testing methods
467bool wxSearchCtrl::IsSingleLine() const
468{
469 return m_text->IsSingleLine();
470}
471bool wxSearchCtrl::IsMultiLine() const
472{
473 return m_text->IsMultiLine();
474}
475
476// If the return values from and to are the same, there is no selection.
477void wxSearchCtrl::GetSelection(long* from, long* to) const
478{
479 m_text->GetSelection(from, to);
480}
481
482wxString wxSearchCtrl::GetStringSelection() const
483{
484 return m_text->GetStringSelection();
485}
486
487// operations
488// ----------
489
490// editing
491void wxSearchCtrl::Clear()
492{
493 m_text->Clear();
494}
495void wxSearchCtrl::Replace(long from, long to, const wxString& value)
496{
497 m_text->Replace(from, to, value);
498}
499void wxSearchCtrl::Remove(long from, long to)
500{
501 m_text->Remove(from, to);
502}
503
504// load/save the controls contents from/to the file
505bool wxSearchCtrl::LoadFile(const wxString& file)
506{
507 return m_text->LoadFile(file);
508}
509bool wxSearchCtrl::SaveFile(const wxString& file)
510{
511 return m_text->SaveFile(file);
512}
513
514// sets/clears the dirty flag
515void wxSearchCtrl::MarkDirty()
516{
517 m_text->MarkDirty();
518}
519void wxSearchCtrl::DiscardEdits()
520{
521 m_text->DiscardEdits();
522}
523
524// set the max number of characters which may be entered in a single line
525// text control
526void wxSearchCtrl::SetMaxLength(unsigned long len)
527{
528 m_text->SetMaxLength(len);
529}
530
531// writing text inserts it at the current position, appending always
532// inserts it at the end
533void wxSearchCtrl::WriteText(const wxString& text)
534{
535 m_text->WriteText(text);
536}
537void wxSearchCtrl::AppendText(const wxString& text)
538{
539 m_text->AppendText(text);
540}
541
542// insert the character which would have resulted from this key event,
543// return true if anything has been inserted
544bool wxSearchCtrl::EmulateKeyPress(const wxKeyEvent& event)
545{
546 return m_text->EmulateKeyPress(event);
547}
548
549// text control under some platforms supports the text styles: these
550// methods allow to apply the given text style to the given selection or to
551// set/get the style which will be used for all appended text
552bool wxSearchCtrl::SetStyle(long start, long end, const wxTextAttr& style)
553{
554 return m_text->SetStyle(start, end, style);
555}
556bool wxSearchCtrl::GetStyle(long position, wxTextAttr& style)
557{
558 return m_text->GetStyle(position, style);
559}
560bool wxSearchCtrl::SetDefaultStyle(const wxTextAttr& style)
561{
562 return m_text->SetDefaultStyle(style);
563}
564const wxTextAttr& wxSearchCtrl::GetDefaultStyle() const
565{
566 return m_text->GetDefaultStyle();
567}
568
569// translate between the position (which is just an index in the text ctrl
570// considering all its contents as a single strings) and (x, y) coordinates
571// which represent column and line.
572long wxSearchCtrl::XYToPosition(long x, long y) const
573{
574 return m_text->XYToPosition(x, y);
575}
576bool wxSearchCtrl::PositionToXY(long pos, long *x, long *y) const
577{
578 return m_text->PositionToXY(pos, x, y);
579}
580
581void wxSearchCtrl::ShowPosition(long pos)
582{
583 m_text->ShowPosition(pos);
584}
585
586// find the character at position given in pixels
587//
588// NB: pt is in device coords (not adjusted for the client area origin nor
589// scrolling)
590wxTextCtrlHitTestResult wxSearchCtrl::HitTest(const wxPoint& pt, long *pos) const
591{
592 return m_text->HitTest(pt, pos);
593}
594wxTextCtrlHitTestResult wxSearchCtrl::HitTest(const wxPoint& pt,
595 wxTextCoord *col,
596 wxTextCoord *row) const
597{
598 return m_text->HitTest(pt, col, row);
599}
600
601// Clipboard operations
602void wxSearchCtrl::Copy()
603{
604 m_text->Copy();
605}
606void wxSearchCtrl::Cut()
607{
608 m_text->Cut();
609}
610void wxSearchCtrl::Paste()
611{
612 m_text->Paste();
613}
614
615bool wxSearchCtrl::CanCopy() const
616{
617 return m_text->CanCopy();
618}
619bool wxSearchCtrl::CanCut() const
620{
621 return m_text->CanCut();
622}
623bool wxSearchCtrl::CanPaste() const
624{
625 return m_text->CanPaste();
626}
627
628// Undo/redo
629void wxSearchCtrl::Undo()
630{
631 m_text->Undo();
632}
633void wxSearchCtrl::Redo()
634{
635 m_text->Redo();
636}
637
638bool wxSearchCtrl::CanUndo() const
639{
640 return m_text->CanUndo();
641}
642bool wxSearchCtrl::CanRedo() const
643{
644 return m_text->CanRedo();
645}
646
647// Insertion point
648void wxSearchCtrl::SetInsertionPoint(long pos)
649{
650 m_text->SetInsertionPoint(pos);
651}
652void wxSearchCtrl::SetInsertionPointEnd()
653{
654 m_text->SetInsertionPointEnd();
655}
656long wxSearchCtrl::GetInsertionPoint() const
657{
658 return m_text->GetInsertionPoint();
659}
660wxTextPos wxSearchCtrl::GetLastPosition() const
661{
662 return m_text->GetLastPosition();
663}
664
665void wxSearchCtrl::SetSelection(long from, long to)
666{
667 m_text->SetSelection(from, to);
668}
669void wxSearchCtrl::SelectAll()
670{
671 m_text->SelectAll();
672}
673
674void wxSearchCtrl::SetEditable(bool editable)
675{
676 m_text->SetEditable(editable);
677}
678
679bool wxSearchCtrl::SetFont(const wxFont& font)
680{
681 bool result = wxSearchCtrlBase::SetFont(font);
682 if ( result && m_text )
683 {
09d93215 684 result = m_text->SetFont(font);
3f7f284d
RD
685 }
686 RecalcBitmaps();
687 return result;
688}
689
690// search control generic only
691void wxSearchCtrl::SetSearchBitmap( const wxBitmap& bitmap )
692{
693 m_searchBitmap = bitmap;
694 m_searchBitmapUser = bitmap.Ok();
695 if ( m_searchBitmapUser )
696 {
697 if ( m_searchButton && !m_menu )
698 {
699 m_searchButton->SetBitmapLabel( m_searchBitmap );
700 }
701 }
702 else
703 {
704 // the user bitmap was just cleared, generate one
705 RecalcBitmaps();
706 }
707}
708
709void wxSearchCtrl::SetSearchMenuBitmap( const wxBitmap& bitmap )
710{
711 m_searchMenuBitmap = bitmap;
712 m_searchMenuBitmapUser = bitmap.Ok();
713 if ( m_searchMenuBitmapUser )
714 {
715 if ( m_searchButton && m_menu )
716 {
717 m_searchButton->SetBitmapLabel( m_searchMenuBitmap );
718 }
719 }
720 else
721 {
722 // the user bitmap was just cleared, generate one
723 RecalcBitmaps();
724 }
725}
726
727void wxSearchCtrl::SetCancelBitmap( const wxBitmap& bitmap )
728{
729 m_cancelBitmap = bitmap;
730 m_cancelBitmapUser = bitmap.Ok();
731 if ( m_cancelBitmapUser )
732 {
733 if ( m_cancelButton )
734 {
735 m_cancelButton->SetBitmapLabel( m_cancelBitmap );
736 }
737 }
738 else
739 {
740 // the user bitmap was just cleared, generate one
741 RecalcBitmaps();
742 }
743}
744
745#if 0
746
747// override streambuf method
748#if wxHAS_TEXT_WINDOW_STREAM
749int overflow(int i);
750#endif // wxHAS_TEXT_WINDOW_STREAM
751
752// stream-like insertion operators: these are always available, whether we
753// were, or not, compiled with streambuf support
754wxTextCtrl& operator<<(const wxString& s);
755wxTextCtrl& operator<<(int i);
756wxTextCtrl& operator<<(long i);
757wxTextCtrl& operator<<(float f);
758wxTextCtrl& operator<<(double d);
759wxTextCtrl& operator<<(const wxChar c);
760#endif
761
762void wxSearchCtrl::DoSetValue(const wxString& value, int flags)
763{
764 m_text->ChangeValue( value );
765 if ( flags & SetValue_SendEvent )
766 SendTextUpdatedEvent();
767}
768
769// do the window-specific processing after processing the update event
770void wxSearchCtrl::DoUpdateWindowUI(wxUpdateUIEvent& event)
771{
772 wxSearchCtrlBase::DoUpdateWindowUI(event);
773}
774
775bool wxSearchCtrl::ShouldInheritColours() const
776{
777 return true;
778}
779
780// icons are rendered at 3-8 times larger than necessary and downscaled for
781// antialiasing
782static int GetMultiplier()
783{
784#ifdef __WXWINCE__
785 // speed up bitmap generation by using a small bitmap
786 return 3;
787#else
788 int depth = ::wxDisplayDepth();
789
790 if ( depth >= 24 )
791 {
792 return 8;
793 }
794 return 6;
795#endif
796}
797
798wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop )
799{
800 wxColour bg = GetBackgroundColour();
801 wxColour fg = GetForegroundColour();
802
803 //===============================================================================
804 // begin drawing code
805 //===============================================================================
806 // image stats
807
808 // force width:height ratio
809 if ( 14*x > y*20 )
810 {
811 // x is too big
812 x = y*20/14;
813 }
814 else
815 {
816 // y is too big
817 y = x*14/20;
818 }
819
820 // glass 11x11, top left corner
821 // handle (9,9)-(13,13)
822 // drop (13,16)-(19,6)-(16,9)
823
824 int multiplier = GetMultiplier();
825 int penWidth = multiplier * 2;
826
827 penWidth = penWidth * x / 20;
828
829 wxBitmap bitmap( multiplier*x, multiplier*y );
830 wxMemoryDC mem;
831 mem.SelectObject(bitmap);
832
833 // clear background
834 mem.SetBrush( wxBrush(bg) );
835 mem.SetPen( wxPen(bg) );
836 mem.DrawRectangle(0,0,bitmap.GetWidth(),bitmap.GetHeight());
837
838 // draw drop glass
839 mem.SetBrush( wxBrush(fg) );
840 mem.SetPen( wxPen(fg) );
841 int glassBase = 5 * x / 20;
842 int glassFactor = 2*glassBase + 1;
843 int radius = multiplier*glassFactor/2;
844 mem.DrawCircle(radius,radius,radius);
845 mem.SetBrush( wxBrush(bg) );
846 mem.SetPen( wxPen(bg) );
847 mem.DrawCircle(radius,radius,radius-penWidth);
848
849 // draw handle
850 int lineStart = radius + (radius-penWidth/2) * 707 / 1000; // 707 / 1000 = 0.707 = 1/sqrt(2);
851
852 mem.SetPen( wxPen(fg) );
853 mem.SetBrush( wxBrush(fg) );
854 int handleCornerShift = penWidth * 707 / 1000 / 2; // 707 / 1000 = 0.707 = 1/sqrt(2);
855 handleCornerShift = WXMAX( handleCornerShift, 1 );
856 int handleBase = 4 * x / 20;
857 int handleLength = 2*handleBase+1;
858 wxPoint handlePolygon[] =
859 {
860 wxPoint(-handleCornerShift,+handleCornerShift),
861 wxPoint(+handleCornerShift,-handleCornerShift),
862 wxPoint(multiplier*handleLength/2+handleCornerShift,multiplier*handleLength/2-handleCornerShift),
863 wxPoint(multiplier*handleLength/2-handleCornerShift,multiplier*handleLength/2+handleCornerShift),
864 };
865 mem.DrawPolygon(WXSIZEOF(handlePolygon),handlePolygon,lineStart,lineStart);
866
867 // draw drop triangle
868 int triangleX = 13 * x / 20;
869 int triangleY = 5 * x / 20;
870 int triangleBase = 3 * x / 20;
871 int triangleFactor = triangleBase*2+1;
872 if ( renderDrop )
873 {
874 wxPoint dropPolygon[] =
875 {
876 wxPoint(multiplier*0,multiplier*0), // triangle left
877 wxPoint(multiplier*triangleFactor-1,multiplier*0), // triangle right
878 wxPoint(multiplier*triangleFactor/2,multiplier*triangleFactor/2), // triangle bottom
879 };
880 mem.DrawPolygon(WXSIZEOF(dropPolygon),dropPolygon,multiplier*triangleX,multiplier*triangleY);
881 }
882
883 //===============================================================================
884 // end drawing code
885 //===============================================================================
886
887 if ( multiplier != 1 )
888 {
889 wxImage image = bitmap.ConvertToImage();
890 image.Rescale(x,y);
891 bitmap = wxBitmap( image );
892 }
893
894 return bitmap;
895}
896
897wxBitmap wxSearchCtrl::RenderCancelBitmap( int x, int y )
898{
899 wxColour bg = GetBackgroundColour();
900 wxColour fg = GetForegroundColour();
901
902 //===============================================================================
903 // begin drawing code
904 //===============================================================================
905 // image stats
906
907 // total size 14x14
908 // force 1:1 ratio
909 if ( x > y )
910 {
911 // x is too big
912 x = y;
913 }
914 else
915 {
916 // y is too big
917 y = x;
918 }
919
920 // 14x14 circle
921 // cross line starts (4,4)-(10,10)
922 // drop (13,16)-(19,6)-(16,9)
923
924 int multiplier = GetMultiplier();
925
926 int penWidth = multiplier * x / 14;
927
928 wxBitmap bitmap( multiplier*x, multiplier*y );
929 wxMemoryDC mem;
930 mem.SelectObject(bitmap);
931
932 // clear background
933 mem.SetBrush( wxBrush(bg) );
934 mem.SetPen( wxPen(bg) );
935 mem.DrawRectangle(0,0,bitmap.GetWidth(),bitmap.GetHeight());
936
937 // draw drop glass
938 mem.SetBrush( wxBrush(fg) );
939 mem.SetPen( wxPen(fg) );
940 int radius = multiplier*x/2;
941 mem.DrawCircle(radius,radius,radius);
942
943 // draw cross
944 int lineStartBase = 4 * x / 14;
945 int lineLength = x - 2*lineStartBase;
946
947 mem.SetPen( wxPen(bg) );
948 mem.SetBrush( wxBrush(bg) );
949 int handleCornerShift = penWidth/2;
950 handleCornerShift = WXMAX( handleCornerShift, 1 );
951 wxPoint handlePolygon[] =
952 {
953 wxPoint(-handleCornerShift,+handleCornerShift),
954 wxPoint(+handleCornerShift,-handleCornerShift),
955 wxPoint(multiplier*lineLength+handleCornerShift,multiplier*lineLength-handleCornerShift),
956 wxPoint(multiplier*lineLength-handleCornerShift,multiplier*lineLength+handleCornerShift),
957 };
958 mem.DrawPolygon(WXSIZEOF(handlePolygon),handlePolygon,multiplier*lineStartBase,multiplier*lineStartBase);
959 wxPoint handlePolygon2[] =
960 {
961 wxPoint(+handleCornerShift,+handleCornerShift),
962 wxPoint(-handleCornerShift,-handleCornerShift),
963 wxPoint(multiplier*lineLength-handleCornerShift,-multiplier*lineLength-handleCornerShift),
964 wxPoint(multiplier*lineLength+handleCornerShift,-multiplier*lineLength+handleCornerShift),
965 };
966 mem.DrawPolygon(WXSIZEOF(handlePolygon2),handlePolygon2,multiplier*lineStartBase,multiplier*(x-lineStartBase));
967
968 //===============================================================================
969 // end drawing code
970 //===============================================================================
971
972 if ( multiplier != 1 )
973 {
974 wxImage image = bitmap.ConvertToImage();
975 image.Rescale(x,y);
976 bitmap = wxBitmap( image );
977 }
978
979 return bitmap;
980}
981
982void wxSearchCtrl::RecalcBitmaps()
983{
984 if ( !m_text )
985 {
986 return;
987 }
988 wxSize sizeText = m_text->GetBestSize();
989
990 int bitmapHeight = sizeText.y - 2 * ICON_MARGIN;
991 int bitmapWidth = sizeText.y * 20 / 14;
992
993 if ( !m_searchBitmapUser )
994 {
8bc333d7 995 if (
3f7f284d 996 !m_searchBitmap.Ok() ||
8bc333d7 997 m_searchBitmap.GetHeight() != bitmapHeight ||
3f7f284d
RD
998 m_searchBitmap.GetWidth() != bitmapWidth
999 )
1000 {
1001 m_searchBitmap = RenderSearchBitmap(bitmapWidth,bitmapHeight,false);
1002 if ( !m_menu )
1003 {
1004 m_searchButton->SetBitmapLabel(m_searchBitmap);
1005 }
1006 }
1007 // else this bitmap was set by user, don't alter
1008 }
1009
1010 if ( !m_searchMenuBitmapUser )
1011 {
8bc333d7 1012 if (
3f7f284d 1013 !m_searchMenuBitmap.Ok() ||
8bc333d7 1014 m_searchMenuBitmap.GetHeight() != bitmapHeight ||
3f7f284d
RD
1015 m_searchMenuBitmap.GetWidth() != bitmapWidth
1016 )
1017 {
1018 m_searchMenuBitmap = RenderSearchBitmap(bitmapWidth,bitmapHeight,true);
1019 if ( m_menu )
1020 {
1021 m_searchButton->SetBitmapLabel(m_searchMenuBitmap);
1022 }
1023 }
1024 // else this bitmap was set by user, don't alter
1025 }
1026
1027 if ( !m_cancelBitmapUser )
1028 {
8bc333d7 1029 if (
3f7f284d 1030 !m_cancelBitmap.Ok() ||
8bc333d7 1031 m_cancelBitmap.GetHeight() != bitmapHeight ||
3f7f284d
RD
1032 m_cancelBitmap.GetWidth() != bitmapHeight
1033 )
1034 {
1035 m_cancelBitmap = RenderCancelBitmap(bitmapHeight-BORDER,bitmapHeight-BORDER); // square
1036 m_cancelButton->SetBitmapLabel(m_cancelBitmap);
1037 }
1038 // else this bitmap was set by user, don't alter
1039 }
1040}
1041
1042void wxSearchCtrl::OnSearchButton( wxCommandEvent& event )
1043{
1044 event.Skip();
1045}
1046
1047void wxSearchCtrl::OnSetFocus( wxFocusEvent& /*event*/ )
1048{
1049 if ( m_text )
1050 {
1051 m_text->SetFocus();
1052 }
1053}
1054
1055void wxSearchCtrl::PopupSearchMenu()
1056{
1057 if ( m_menu )
1058 {
1059 wxSize size = GetSize();
1060 PopupMenu( m_menu, 0, size.y );
1061 }
1062}
1063
5b43c75c 1064#endif // !wxUSE_NATIVE_SEARCH_CONTROL
3f7f284d
RD
1065
1066#endif // wxUSE_SEARCHCTRL