]> git.saurik.com Git - wxWidgets.git/blame - src/generic/vlbox.cpp
corrected error in last fix for insert items
[wxWidgets.git] / src / generic / vlbox.cpp
CommitLineData
e0c6027b
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: generic/vlbox.cpp
3// Purpose: implementation of wxVListBox
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 31.05.03
7// RCS-ID: $Id$
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/settings.h"
bb178b29 29 #include "wx/dcclient.h"
e0c6027b
VZ
30#endif //WX_PRECOMP
31
32#include "wx/vlbox.h"
33
34// ----------------------------------------------------------------------------
35// event tables
36// ----------------------------------------------------------------------------
37
38BEGIN_EVENT_TABLE(wxVListBox, wxVScrolledWindow)
39 EVT_PAINT(wxVListBox::OnPaint)
40
41 EVT_KEY_DOWN(wxVListBox::OnKeyDown)
42 EVT_LEFT_DOWN(wxVListBox::OnLeftDown)
43 EVT_LEFT_DCLICK(wxVListBox::OnLeftDClick)
44END_EVENT_TABLE()
45
46// ============================================================================
47// implementation
48// ============================================================================
49
50// ----------------------------------------------------------------------------
51// wxVListBox creation
52// ----------------------------------------------------------------------------
53
54void wxVListBox::Init()
55{
56 m_selection = -1;
57}
58
59bool wxVListBox::Create(wxWindow *parent,
60 wxWindowID id,
61 const wxPoint& pos,
62 const wxSize& size,
63 size_t countItems,
64 long style,
65 const wxString& name)
66{
67 if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) )
68 return false;
69
70 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX));
71
72 SetItemCount(countItems);
73
74 return true;
75}
76
77// ----------------------------------------------------------------------------
78// selection handling
79// ----------------------------------------------------------------------------
80
81void wxVListBox::DoSetSelection(int selection, bool sendEvent)
82{
83 if ( selection == m_selection )
84 {
85 // nothing to do
86 return;
87 }
88
89 if ( m_selection != -1 )
90 RefreshLine(m_selection);
91
92 m_selection = selection;
93
94 if ( m_selection != -1 )
95 {
96 // if the line is not visible at all, we scroll it into view but we
97 // don't need to refresh it -- it will be redrawn anyhow
98 if ( !IsVisible(m_selection) )
99 {
100 ScrollToLine(m_selection);
101 }
102 else // line is at least partly visible
103 {
104 // it is, indeed, only partly visible, so scroll it into view to
105 // make it entirely visible
106 if ( (size_t)m_selection == GetLastVisibleLine() )
107 {
108 ScrollToLine(m_selection);
109 }
110
111 // but in any case refresh it as even if it was only partly visible
112 // before we need to redraw it entirely as its background changed
113 RefreshLine(m_selection);
114 }
115
116 // send a notification event if we were not called directly by user
117 if ( sendEvent )
118 {
119 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
120 event.SetEventObject(this);
121 event.m_commandInt = selection;
122
123 (void)GetEventHandler()->ProcessEvent(event);
124 }
125 }
126}
127
128// ----------------------------------------------------------------------------
129// wxVListBox painting
130// ----------------------------------------------------------------------------
131
132void wxVListBox::SetMargins(const wxPoint& pt)
133{
134 if ( pt != m_ptMargins )
135 {
136 m_ptMargins = pt;
137
138 Refresh();
139 }
140}
141
142wxCoord wxVListBox::OnGetLineHeight(size_t line) const
143{
144 return OnMeasureItem(line) + 2*m_ptMargins.y;
145}
146
147void wxVListBox::OnDrawSeparator(wxDC& WXUNUSED(dc),
148 wxRect& WXUNUSED(rect),
149 size_t WXUNUSED(n)) const
150{
151}
152
153void wxVListBox::OnPaint(wxPaintEvent& event)
154{
155 wxPaintDC dc(this);
156
157 // the update rectangle
158 wxRect rectUpdate = GetUpdateClientRect();
159
160 // the bounding rectangle of the current line
161 wxRect rectLine;
162 rectLine.width = GetClientSize().x;
163
164 // iterate over all visible lines
165 const size_t lineMax = GetLastVisibleLine();
166 for ( size_t line = GetFirstVisibleLine(); line <= lineMax; line++ )
167 {
168 const wxCoord hLine = OnGetLineHeight(line);
169
170 rectLine.height = hLine;
171
172 // and draw the ones which intersect the update rect
173 if ( rectLine.Intersects(rectUpdate) )
174 {
175 // don't allow drawing outside of the lines rectangle
176 wxDCClipper clip(dc, rectLine);
177
178 if ( IsSelected(line) )
179 {
180 wxBrush brush(wxSystemSettings::
181 GetColour(wxSYS_COLOUR_HIGHLIGHT),
182 wxSOLID);
183 dc.SetBrush(brush);
184 dc.SetPen(*wxTRANSPARENT_PEN);
185 dc.DrawRectangle(rectLine);
186 }
187
188 wxRect rect = rectLine;
189 OnDrawSeparator(dc, rect, line);
190
191 rect.Deflate(m_ptMargins.x, m_ptMargins.y);
192 OnDrawItem(dc, rect, line);
193 }
194 else // no intersection
195 {
196 if ( rectLine.GetTop() > rectUpdate.GetBottom() )
197 {
198 // we are already below the update rect, no need to continue
199 // further
200 break;
201 }
202 //else: the next line may intersect the update rect
203 }
204
205 rectLine.y += hLine;
206 }
207}
208
209// ----------------------------------------------------------------------------
210// wxVListBox keyboard handling
211// ----------------------------------------------------------------------------
212
213void wxVListBox::OnKeyDown(wxKeyEvent& event)
214{
215 int selection = 0; // just to silent the stupid compiler warnings
216 switch ( event.GetKeyCode() )
217 {
218 case WXK_HOME:
219 selection = 0;
220 break;
221
222 case WXK_END:
223 selection = GetLineCount() - 1;
224 break;
225
226 case WXK_DOWN:
227 if ( m_selection == (int)GetLineCount() - 1 )
228 return;
229
230 selection = m_selection + 1;
231 break;
232
233 case WXK_UP:
234 if ( m_selection == -1 )
235 selection = GetLineCount() - 1;
236 else if ( m_selection != 0 )
237 selection = m_selection - 1;
238 else // m_selection == 0
239 return;
240 break;
241
242 case WXK_PAGEDOWN:
243 case WXK_NEXT:
244 PageDown();
245 selection = GetFirstVisibleLine();
246 break;
247
248 case WXK_PAGEUP:
249 case WXK_PRIOR:
250 if ( m_selection == (int)GetFirstVisibleLine() )
251 {
252 PageUp();
253 }
254
255 selection = GetFirstVisibleLine();
256 break;
257
258 default:
259 event.Skip();
260 return;
261 }
262
263 DoSetSelection(selection);
264}
265
266// ----------------------------------------------------------------------------
267// wxVListBox mouse handling
268// ----------------------------------------------------------------------------
269
270void wxVListBox::OnLeftDown(wxMouseEvent& event)
271{
272 int item = HitTest(event.GetPosition());
273
274 DoSetSelection(item);
275}
276
277void wxVListBox::OnLeftDClick(wxMouseEvent& event)
278{
279 int item = HitTest(event.GetPosition());
280 if ( item != -1 )
281 {
282 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, GetId());
283 event.SetEventObject(this);
284 event.m_commandInt = item;
285
286 (void)GetEventHandler()->ProcessEvent(event);
287 }
288}
289