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