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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (hide annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (10 years ago) by william
File size: 18887 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 william 31 ///////////////////////////////////////////////////////////////////////////////
2     // Name: generic/htmllbox.cpp
3     // Purpose: implementation of wxHtmlListBox
4     // Author: Vadim Zeitlin
5     // Modified by:
6     // Created: 31.05.03
7     // RCS-ID: $Id: htmllbox.cpp 44026 2006-12-21 18:24:27Z VS $
8     // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9     // License: wxWindows license
10     ///////////////////////////////////////////////////////////////////////////////
11    
12     // ============================================================================
13     // declarations
14     // ============================================================================
15    
16     // ----------------------------------------------------------------------------
17     // headers
18     // ----------------------------------------------------------------------------
19    
20     // For compilers that support precompilation, includes "wx.h".
21     #include "wx/wxprec.h"
22    
23     #ifdef __BORLANDC__
24     #pragma hdrstop
25     #endif
26    
27     #ifndef WX_PRECOMP
28     #include "wx/dcclient.h"
29     #endif //WX_PRECOMP
30    
31     #if wxUSE_HTML
32    
33     #include "wx/htmllbox.h"
34    
35     #include "wx/html/htmlcell.h"
36     #include "wx/html/winpars.h"
37    
38     // this hack forces the linker to always link in m_* files
39     #include "wx/html/forcelnk.h"
40     FORCE_WXHTML_MODULES()
41    
42     // ----------------------------------------------------------------------------
43     // constants
44     // ----------------------------------------------------------------------------
45    
46     // small border always added to the cells:
47     static const wxCoord CELL_BORDER = 2;
48    
49     const wxChar wxHtmlListBoxNameStr[] = wxT("htmlListBox");
50     const wxChar wxSimpleHtmlListBoxNameStr[] = wxT("simpleHtmlListBox");
51    
52     // ============================================================================
53     // private classes
54     // ============================================================================
55    
56     // ----------------------------------------------------------------------------
57     // wxHtmlListBoxCache
58     // ----------------------------------------------------------------------------
59    
60     // this class is used by wxHtmlListBox to cache the parsed representation of
61     // the items to avoid doing it anew each time an item must be drawn
62     class wxHtmlListBoxCache
63     {
64     private:
65     // invalidate a single item, used by Clear() and InvalidateRange()
66     void InvalidateItem(size_t n)
67     {
68     m_items[n] = (size_t)-1;
69     delete m_cells[n];
70     m_cells[n] = NULL;
71     }
72    
73     public:
74     wxHtmlListBoxCache()
75     {
76     for ( size_t n = 0; n < SIZE; n++ )
77     {
78     m_items[n] = (size_t)-1;
79     m_cells[n] = NULL;
80     }
81    
82     m_next = 0;
83     }
84    
85     ~wxHtmlListBoxCache()
86     {
87     for ( size_t n = 0; n < SIZE; n++ )
88     {
89     delete m_cells[n];
90     }
91     }
92    
93     // completely invalidate the cache
94     void Clear()
95     {
96     for ( size_t n = 0; n < SIZE; n++ )
97     {
98     InvalidateItem(n);
99     }
100     }
101    
102     // return the cached cell for this index or NULL if none
103     wxHtmlCell *Get(size_t item) const
104     {
105     for ( size_t n = 0; n < SIZE; n++ )
106     {
107     if ( m_items[n] == item )
108     return m_cells[n];
109     }
110    
111     return NULL;
112     }
113    
114     // returns true if we already have this item cached
115     bool Has(size_t item) const { return Get(item) != NULL; }
116    
117     // ensure that the item is cached
118     void Store(size_t item, wxHtmlCell *cell)
119     {
120     delete m_cells[m_next];
121     m_cells[m_next] = cell;
122     m_items[m_next] = item;
123    
124     // advance to the next item wrapping around if there are no more
125     if ( ++m_next == SIZE )
126     m_next = 0;
127     }
128    
129     // forget the cached value of the item(s) between the given ones (inclusive)
130     void InvalidateRange(size_t from, size_t to)
131     {
132     for ( size_t n = 0; n < SIZE; n++ )
133     {
134     if ( m_items[n] >= from && m_items[n] <= to )
135     {
136     InvalidateItem(n);
137     }
138     }
139     }
140    
141     private:
142     // the max number of the items we cache
143     enum { SIZE = 50 };
144    
145     // the index of the LRU (oldest) cell
146     size_t m_next;
147    
148     // the parsed representation of the cached item or NULL
149     wxHtmlCell *m_cells[SIZE];
150    
151     // the index of the currently cached item (only valid if m_cells != NULL)
152     size_t m_items[SIZE];
153     };
154    
155     // ----------------------------------------------------------------------------
156     // wxHtmlListBoxStyle
157     // ----------------------------------------------------------------------------
158    
159     // just forward wxDefaultHtmlRenderingStyle callbacks to the main class so that
160     // they could be overridden by the user code
161     class wxHtmlListBoxStyle : public wxDefaultHtmlRenderingStyle
162     {
163     public:
164     wxHtmlListBoxStyle(const wxHtmlListBox& hlbox) : m_hlbox(hlbox) { }
165    
166     virtual wxColour GetSelectedTextColour(const wxColour& colFg)
167     {
168     return m_hlbox.GetSelectedTextColour(colFg);
169     }
170    
171     virtual wxColour GetSelectedTextBgColour(const wxColour& colBg)
172     {
173     return m_hlbox.GetSelectedTextBgColour(colBg);
174     }
175    
176     private:
177     const wxHtmlListBox& m_hlbox;
178    
179     DECLARE_NO_COPY_CLASS(wxHtmlListBoxStyle)
180     };
181    
182     // ----------------------------------------------------------------------------
183     // event tables
184     // ----------------------------------------------------------------------------
185    
186     BEGIN_EVENT_TABLE(wxHtmlListBox, wxVListBox)
187     EVT_SIZE(wxHtmlListBox::OnSize)
188     EVT_MOTION(wxHtmlListBox::OnMouseMove)
189     EVT_LEFT_DOWN(wxHtmlListBox::OnLeftDown)
190     END_EVENT_TABLE()
191    
192     // ============================================================================
193     // implementation
194     // ============================================================================
195    
196     IMPLEMENT_ABSTRACT_CLASS(wxHtmlListBox, wxVListBox)
197    
198    
199     // ----------------------------------------------------------------------------
200     // wxHtmlListBox creation
201     // ----------------------------------------------------------------------------
202    
203     wxHtmlListBox::wxHtmlListBox()
204     : wxHtmlWindowMouseHelper(this)
205     {
206     Init();
207     }
208    
209     // normal constructor which calls Create() internally
210     wxHtmlListBox::wxHtmlListBox(wxWindow *parent,
211     wxWindowID id,
212     const wxPoint& pos,
213     const wxSize& size,
214     long style,
215     const wxString& name)
216     : wxHtmlWindowMouseHelper(this)
217     {
218     Init();
219    
220     (void)Create(parent, id, pos, size, style, name);
221     }
222    
223     void wxHtmlListBox::Init()
224     {
225     m_htmlParser = NULL;
226     m_htmlRendStyle = new wxHtmlListBoxStyle(*this);
227     m_cache = new wxHtmlListBoxCache;
228     }
229    
230     bool wxHtmlListBox::Create(wxWindow *parent,
231     wxWindowID id,
232     const wxPoint& pos,
233     const wxSize& size,
234     long style,
235     const wxString& name)
236     {
237     return wxVListBox::Create(parent, id, pos, size, style, name);
238     }
239    
240     wxHtmlListBox::~wxHtmlListBox()
241     {
242     delete m_cache;
243    
244     if ( m_htmlParser )
245     {
246     delete m_htmlParser->GetDC();
247     delete m_htmlParser;
248     }
249    
250     delete m_htmlRendStyle;
251     }
252    
253     // ----------------------------------------------------------------------------
254     // wxHtmlListBox appearance
255     // ----------------------------------------------------------------------------
256    
257     wxColour wxHtmlListBox::GetSelectedTextColour(const wxColour& colFg) const
258     {
259     return m_htmlRendStyle->
260     wxDefaultHtmlRenderingStyle::GetSelectedTextColour(colFg);
261     }
262    
263     wxColour
264     wxHtmlListBox::GetSelectedTextBgColour(const wxColour& WXUNUSED(colBg)) const
265     {
266     return GetSelectionBackground();
267     }
268    
269     // ----------------------------------------------------------------------------
270     // wxHtmlListBox items markup
271     // ----------------------------------------------------------------------------
272    
273     wxString wxHtmlListBox::OnGetItemMarkup(size_t n) const
274     {
275     // we don't even need to wrap the value returned by OnGetItem() inside
276     // "<html><body>" and "</body></html>" because wxHTML can parse it even
277     // without these tags
278     return OnGetItem(n);
279     }
280    
281     // ----------------------------------------------------------------------------
282     // wxHtmlListBox cache handling
283     // ----------------------------------------------------------------------------
284    
285     void wxHtmlListBox::CacheItem(size_t n) const
286     {
287     if ( !m_cache->Has(n) )
288     {
289     if ( !m_htmlParser )
290     {
291     wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox);
292    
293     self->m_htmlParser = new wxHtmlWinParser(self);
294     m_htmlParser->SetDC(new wxClientDC(self));
295     m_htmlParser->SetFS(&self->m_filesystem);
296     #if !wxUSE_UNICODE
297     if (GetFont().Ok())
298     m_htmlParser->SetInputEncoding(GetFont().GetEncoding());
299     #endif
300     // use system's default GUI font by default:
301     m_htmlParser->SetStandardFonts();
302     }
303    
304     wxHtmlContainerCell *cell = (wxHtmlContainerCell *)m_htmlParser->
305     Parse(OnGetItemMarkup(n));
306     wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") );
307    
308     // set the cell's ID to item's index so that CellCoordsToPhysical()
309     // can quickly find the item:
310     cell->SetId(wxString::Format(_T("%lu"), (unsigned long)n));
311    
312     cell->Layout(GetClientSize().x - 2*GetMargins().x);
313    
314     m_cache->Store(n, cell);
315     }
316     }
317    
318     void wxHtmlListBox::OnSize(wxSizeEvent& event)
319     {
320     // we need to relayout all the cached cells
321     m_cache->Clear();
322    
323     event.Skip();
324     }
325    
326     void wxHtmlListBox::RefreshLine(size_t line)
327     {
328     m_cache->InvalidateRange(line, line);
329    
330     wxVListBox::RefreshLine(line);
331     }
332    
333     void wxHtmlListBox::RefreshLines(size_t from, size_t to)
334     {
335     m_cache->InvalidateRange(from, to);
336    
337     wxVListBox::RefreshLines(from, to);
338     }
339    
340     void wxHtmlListBox::RefreshAll()
341     {
342     m_cache->Clear();
343    
344     wxVListBox::RefreshAll();
345     }
346    
347     void wxHtmlListBox::SetItemCount(size_t count)
348     {
349     // the items are going to change, forget the old ones
350     m_cache->Clear();
351    
352     wxVListBox::SetItemCount(count);
353     }
354    
355     // ----------------------------------------------------------------------------
356     // wxHtmlListBox implementation of wxVListBox pure virtuals
357     // ----------------------------------------------------------------------------
358    
359     void wxHtmlListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
360     {
361     CacheItem(n);
362    
363     wxHtmlCell *cell = m_cache->Get(n);
364     wxCHECK_RET( cell, _T("this cell should be cached!") );
365    
366     wxHtmlRenderingInfo htmlRendInfo;
367    
368     // draw the selected cell in selected state
369     if ( IsSelected(n) )
370     {
371     wxHtmlSelection htmlSel;
372     htmlSel.Set(wxPoint(0,0), cell, wxPoint(INT_MAX, INT_MAX), cell);
373     htmlRendInfo.SetSelection(&htmlSel);
374     if ( m_htmlRendStyle )
375     htmlRendInfo.SetStyle(m_htmlRendStyle);
376     htmlRendInfo.GetState().SetSelectionState(wxHTML_SEL_IN);
377     }
378    
379     // note that we can't stop drawing exactly at the window boundary as then
380     // even the visible cells part could be not drawn, so always draw the
381     // entire cell
382     cell->Draw(dc,
383     rect.x + CELL_BORDER, rect.y + CELL_BORDER,
384     0, INT_MAX, htmlRendInfo);
385     }
386    
387     wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
388     {
389     CacheItem(n);
390    
391     wxHtmlCell *cell = m_cache->Get(n);
392     wxCHECK_MSG( cell, 0, _T("this cell should be cached!") );
393    
394     return cell->GetHeight() + cell->GetDescent() + 4;
395     }
396    
397     // ----------------------------------------------------------------------------
398     // wxHtmlListBox implementation of wxHtmlListBoxWinInterface
399     // ----------------------------------------------------------------------------
400    
401     void wxHtmlListBox::SetHTMLWindowTitle(const wxString& WXUNUSED(title))
402     {
403     // nothing to do
404     }
405    
406     void wxHtmlListBox::OnHTMLLinkClicked(const wxHtmlLinkInfo& link)
407     {
408     OnLinkClicked(GetItemForCell(link.GetHtmlCell()), link);
409     }
410    
411     void wxHtmlListBox::OnLinkClicked(size_t WXUNUSED(n),
412     const wxHtmlLinkInfo& link)
413     {
414     wxHtmlLinkEvent event(GetId(), link);
415     GetEventHandler()->ProcessEvent(event);
416     }
417    
418     wxHtmlOpeningStatus
419     wxHtmlListBox::OnHTMLOpeningURL(wxHtmlURLType WXUNUSED(type),
420     const wxString& WXUNUSED(url),
421     wxString *WXUNUSED(redirect)) const
422     {
423     return wxHTML_OPEN;
424     }
425    
426     wxPoint wxHtmlListBox::HTMLCoordsToWindow(wxHtmlCell *cell,
427     const wxPoint& pos) const
428     {
429     return CellCoordsToPhysical(pos, cell);
430     }
431    
432     wxWindow* wxHtmlListBox::GetHTMLWindow() { return this; }
433    
434     wxColour wxHtmlListBox::GetHTMLBackgroundColour() const
435     {
436     return GetBackgroundColour();
437     }
438    
439     void wxHtmlListBox::SetHTMLBackgroundColour(const wxColour& WXUNUSED(clr))
440     {
441     // nothing to do
442     }
443    
444     void wxHtmlListBox::SetHTMLBackgroundImage(const wxBitmap& WXUNUSED(bmpBg))
445     {
446     // nothing to do
447     }
448    
449     void wxHtmlListBox::SetHTMLStatusText(const wxString& WXUNUSED(text))
450     {
451     // nothing to do
452     }
453    
454     wxCursor wxHtmlListBox::GetHTMLCursor(HTMLCursor type) const
455     {
456     // we don't want to show text selection cursor in listboxes
457     if (type == HTMLCursor_Text)
458     return wxHtmlWindow::GetDefaultHTMLCursor(HTMLCursor_Default);
459    
460     // in all other cases, use the same cursor as wxHtmlWindow:
461     return wxHtmlWindow::GetDefaultHTMLCursor(type);
462     }
463    
464     // ----------------------------------------------------------------------------
465     // wxHtmlListBox handling of HTML links
466     // ----------------------------------------------------------------------------
467    
468     wxPoint wxHtmlListBox::GetRootCellCoords(size_t n) const
469     {
470     wxPoint pos(CELL_BORDER, CELL_BORDER);
471     pos += GetMargins();
472     pos.y += GetLinesHeight(GetFirstVisibleLine(), n);
473     return pos;
474     }
475    
476     bool wxHtmlListBox::PhysicalCoordsToCell(wxPoint& pos, wxHtmlCell*& cell) const
477     {
478     int n = HitTest(pos);
479     if ( n == wxNOT_FOUND )
480     return false;
481    
482     // convert mouse coordinates to coords relative to item's wxHtmlCell:
483     pos -= GetRootCellCoords(n);
484    
485     CacheItem(n);
486     cell = m_cache->Get(n);
487    
488     return true;
489     }
490    
491     size_t wxHtmlListBox::GetItemForCell(const wxHtmlCell *cell) const
492     {
493     wxCHECK_MSG( cell, 0, _T("no cell") );
494    
495     cell = cell->GetRootCell();
496    
497     wxCHECK_MSG( cell, 0, _T("no root cell") );
498    
499     // the cell's ID contains item index, see CacheItem():
500     unsigned long n;
501     if ( !cell->GetId().ToULong(&n) )
502     {
503     wxFAIL_MSG( _T("unexpected root cell's ID") );
504     return 0;
505     }
506    
507     return n;
508     }
509    
510     wxPoint
511     wxHtmlListBox::CellCoordsToPhysical(const wxPoint& pos, wxHtmlCell *cell) const
512     {
513     return pos + GetRootCellCoords(GetItemForCell(cell));
514     }
515    
516     void wxHtmlListBox::OnInternalIdle()
517     {
518     wxVListBox::OnInternalIdle();
519    
520     if ( wxHtmlWindowMouseHelper::DidMouseMove() )
521     {
522     wxPoint pos = ScreenToClient(wxGetMousePosition());
523     wxHtmlCell *cell;
524    
525     if ( !PhysicalCoordsToCell(pos, cell) )
526     return;
527    
528     wxHtmlWindowMouseHelper::HandleIdle(cell, pos);
529     }
530     }
531    
532     void wxHtmlListBox::OnMouseMove(wxMouseEvent& event)
533     {
534     wxHtmlWindowMouseHelper::HandleMouseMoved();
535     event.Skip();
536     }
537    
538     void wxHtmlListBox::OnLeftDown(wxMouseEvent& event)
539     {
540     wxPoint pos = event.GetPosition();
541     wxHtmlCell *cell;
542    
543     if ( !PhysicalCoordsToCell(pos, cell) )
544     {
545     event.Skip();
546     return;
547     }
548    
549     if ( !wxHtmlWindowMouseHelper::HandleMouseClick(cell, pos, event) )
550     {
551     // no link was clicked, so let the listbox code handle the click (e.g.
552     // by selecting another item in the list):
553     event.Skip();
554     }
555     }
556    
557    
558     // ----------------------------------------------------------------------------
559     // wxSimpleHtmlListBox
560     // ----------------------------------------------------------------------------
561    
562     bool wxSimpleHtmlListBox::Create(wxWindow *parent, wxWindowID id,
563     const wxPoint& pos,
564     const wxSize& size,
565     int n, const wxString choices[],
566     long style,
567     const wxValidator& validator,
568     const wxString& name)
569     {
570     if (!wxHtmlListBox::Create(parent, id, pos, size, style, name))
571     return false;
572    
573     #if wxUSE_VALIDATORS
574     SetValidator(validator);
575     #endif
576     for (int i=0; i<n; i++)
577     Append(choices[i]);
578    
579     return true;
580     }
581    
582     bool wxSimpleHtmlListBox::Create(wxWindow *parent, wxWindowID id,
583     const wxPoint& pos,
584     const wxSize& size,
585     const wxArrayString& choices,
586     long style,
587     const wxValidator& validator,
588     const wxString& name)
589     {
590     if (!wxHtmlListBox::Create(parent, id, pos, size, style, name))
591     return false;
592    
593     #if wxUSE_VALIDATORS
594     SetValidator(validator);
595     #endif
596     Append(choices);
597    
598     return true;
599     }
600    
601     wxSimpleHtmlListBox::~wxSimpleHtmlListBox()
602     {
603     wxASSERT(m_items.GetCount() == m_HTMLclientData.GetCount());
604     if (HasClientObjectData())
605     {
606     // clear the array of client data objects
607     for (size_t i=0; i<m_items.GetCount(); i++)
608     delete DoGetItemClientObject(i);
609     }
610    
611     m_items.Clear();
612     m_HTMLclientData.Clear();
613     }
614    
615     void wxSimpleHtmlListBox::Clear()
616     {
617     m_items.Clear();
618     m_HTMLclientData.Clear();
619     UpdateCount();
620     }
621    
622     void wxSimpleHtmlListBox::Delete(unsigned int n)
623     {
624     m_items.RemoveAt(n);
625     m_HTMLclientData.RemoveAt(n);
626     UpdateCount();
627     }
628    
629     void wxSimpleHtmlListBox::Append(const wxArrayString& strings)
630     {
631     // append all given items at once
632     WX_APPEND_ARRAY(m_items, strings);
633     m_HTMLclientData.Add(NULL, strings.GetCount());
634     UpdateCount();
635     }
636    
637     int wxSimpleHtmlListBox::DoAppend(const wxString& item)
638     {
639     m_items.Add(item);
640     m_HTMLclientData.Add(NULL);
641     UpdateCount();
642     return GetCount()-1;
643     }
644    
645     int wxSimpleHtmlListBox::DoInsert(const wxString& item, unsigned int pos)
646     {
647     m_items.Insert(item, pos);
648     m_HTMLclientData.Insert(NULL, pos);
649     UpdateCount();
650     return pos;
651     }
652    
653     void wxSimpleHtmlListBox::SetString(unsigned int n, const wxString& s)
654     {
655     wxCHECK_RET( IsValid(n),
656     wxT("invalid index in wxSimpleHtmlListBox::SetString") );
657    
658     m_items[n]=s;
659     RefreshLine(n);
660     }
661    
662     wxString wxSimpleHtmlListBox::GetString(unsigned int n) const
663     {
664     wxCHECK_MSG( IsValid(n), wxEmptyString,
665     wxT("invalid index in wxSimpleHtmlListBox::GetString") );
666    
667     return m_items[n];
668     }
669    
670     void wxSimpleHtmlListBox::UpdateCount()
671     {
672     wxASSERT(m_items.GetCount() == m_HTMLclientData.GetCount());
673     wxHtmlListBox::SetItemCount(m_items.GetCount());
674    
675     // very small optimization: if you need to add lot of items to
676     // a wxSimpleHtmlListBox be sure to use the
677     // wxSimpleHtmlListBox::Append(const wxArrayString&) method instead!
678     if (!this->IsFrozen())
679     RefreshAll();
680     }
681    
682     #endif // wxUSE_HTML

  ViewVC Help
Powered by ViewVC 1.1.22