/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/srchctlg.cpp
ViewVC logotype

Annotation of /branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/srchctlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22