]> git.saurik.com Git - wxWidgets.git/blob - src/msw/headerctrl.cpp
6330b225e1e9f3e0efc8434df9ca9e74ce3aaa6e
[wxWidgets.git] / src / msw / headerctrl.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/headerctrl.cpp
3 // Purpose: implementation of wxHeaderCtrl for wxMSW
4 // Author: Vadim Zeitlin
5 // Created: 2008-12-01
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/log.h"
28 #endif // WX_PRECOMP
29
30 #include "wx/headerctrl.h"
31 #include "wx/imaglist.h"
32
33 #include "wx/msw/wrapcctl.h"
34 #include "wx/msw/private.h"
35
36 // ============================================================================
37 // wxHeaderCtrl implementation
38 // ============================================================================
39
40 // ----------------------------------------------------------------------------
41 // wxHeaderCtrl construction/destruction
42 // ----------------------------------------------------------------------------
43
44 void wxHeaderCtrl::Init()
45 {
46 m_imageList = NULL;
47 }
48
49 bool wxHeaderCtrl::Create(wxWindow *parent,
50 wxWindowID id,
51 const wxPoint& pos,
52 const wxSize& size,
53 long style,
54 const wxString& name)
55 {
56 // notice that we don't need InitCommonControlsEx(ICC_LISTVIEW_CLASSES)
57 // here as we already call InitCommonControls() in wxApp initialization
58 // code which covers this
59
60 if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
61 return false;
62
63 if ( !MSWCreateControl(WC_HEADER, _T(""), pos, size) )
64 return false;
65
66 return true;
67 }
68
69 WXDWORD wxHeaderCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
70 {
71 WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
72
73 if ( style & wxHD_DRAGDROP )
74 msStyle |= HDS_DRAGDROP;
75
76 // the control looks nicer with these styles and there doesn't seem to be
77 // any reason to not use them so we always do (as for HDS_HORZ it is 0
78 // anyhow but include it for clarity)
79 msStyle |= HDS_HORZ | HDS_BUTTONS | HDS_FLAT | HDS_FULLDRAG | HDS_HOTTRACK;
80
81 return msStyle;
82 }
83
84 wxHeaderCtrl::~wxHeaderCtrl()
85 {
86 delete m_imageList;
87 }
88
89 // ----------------------------------------------------------------------------
90 // wxHeaderCtrl scrolling
91 // ----------------------------------------------------------------------------
92
93 // as the native control doesn't support offsetting its contents, we use a hack
94 // here to make it appear correctly when the parent is scrolled: instead of
95 // scrolling or repainting we simply move the control window itself
96 void wxHeaderCtrl::ScrollWindow(int dx,
97 int WXUNUSED_UNLESS_DEBUG(dy),
98 const wxRect * WXUNUSED_UNLESS_DEBUG(rect))
99 {
100 // this doesn't make sense at all
101 wxASSERT_MSG( !dy, "header window can't be scrolled vertically" );
102
103 // this would actually be nice to support for "frozen" headers
104 wxASSERT_MSG( !rect, "header window can't be scrolled partially" );
105
106 // offset the window by the scroll increment to the left and increment its
107 // width to still extend to the right boundary to compensate for it (notice
108 // that dx is negative when scrolling to the right)
109 SetSize(GetPosition().x + dx, -1, GetSize().x - dx, -1, wxSIZE_USE_EXISTING);
110 }
111
112 // ----------------------------------------------------------------------------
113 // wxHeaderCtrl geometry calculation
114 // ----------------------------------------------------------------------------
115
116 wxSize wxHeaderCtrl::DoGetBestSize() const
117 {
118 RECT rc = wxGetClientRect(GetHwndOf(GetParent()));
119 WINDOWPOS wpos;
120 HDLAYOUT layout = { &rc, &wpos };
121 if ( !Header_Layout(GetHwnd(), &layout) )
122 {
123 wxLogLastError(_T("Header_Layout"));
124 return wxControl::DoGetBestSize();
125 }
126
127 return wxSize(wpos.cx, wpos.cy);
128 }
129
130 // ----------------------------------------------------------------------------
131 // wxHeaderCtrl columns managements
132 // ----------------------------------------------------------------------------
133
134 unsigned int wxHeaderCtrl::DoGetCount() const
135 {
136 return Header_GetItemCount(GetHwnd());
137 }
138
139 void wxHeaderCtrl::DoInsert(const wxHeaderColumn& col, unsigned int idx)
140 {
141 // copy the HDITEM because we may modify it below
142 HDITEM hdi = col.GetHDI();
143
144 const wxBitmap bmp = col.GetBitmap();
145 if ( bmp.IsOk() )
146 {
147 const int bmpWidth = bmp.GetWidth(),
148 bmpHeight = bmp.GetHeight();
149
150 if ( !m_imageList )
151 {
152 m_imageList = new wxImageList(bmpWidth, bmpHeight);
153 Header_SetImageList(GetHwnd(), GetHimagelistOf(m_imageList));
154 }
155 else // already have an image list
156 {
157 // check that all bitmaps we use have the same size
158 int imageWidth,
159 imageHeight;
160 m_imageList->GetSize(0, imageWidth, imageHeight);
161
162 wxASSERT_MSG( imageWidth == bmpWidth && imageHeight == bmpHeight,
163 "all column bitmaps must have the same size" );
164 }
165
166 m_imageList->Add(bmp);
167 hdi.mask |= HDI_IMAGE;
168 hdi.iImage = m_imageList->GetImageCount() - 1;
169 }
170
171 if ( col.IsHidden() )
172 {
173 hdi.mask |= HDI_WIDTH;
174 hdi.cxy = 0;
175 }
176
177 if ( Header_InsertItem(GetHwnd(), idx, &hdi) == -1 )
178 {
179 wxLogLastError(_T("Header_InsertItem"));
180 }
181 }
182
183 void wxHeaderCtrl::DoDelete(unsigned int idx)
184 {
185 if ( !Header_DeleteItem(GetHwnd(), idx) )
186 {
187 wxLogLastError(_T("Header_DeleteItem"));
188 }
189 }
190
191 // ----------------------------------------------------------------------------
192 // wxHeaderCtrl columns attributes
193 // ----------------------------------------------------------------------------
194
195 void wxHeaderCtrl::DoShowColumn(unsigned int idx, bool show)
196 {
197 wxHDITEM hdi;
198 hdi.mask = HDI_WIDTH;
199
200 if ( !Header_GetItem(GetHwnd(), idx, &hdi) )
201 {
202 wxLogLastError(_T("Header_GetItem(HDI_WIDTH)"));
203 return;
204 }
205
206 if ( show )
207 hdi.cxy = 80; // FIXME: we don't have the column width here any more
208 else
209 hdi.cxy = 0;
210
211 if ( !Header_SetItem(GetHwnd(), idx, &hdi) )
212 {
213 wxLogLastError(_T("Header_SetItem(HDI_WIDTH)"));
214 return;
215 }
216 }
217
218 void wxHeaderCtrl::DoShowSortIndicator(unsigned int idx, int sortOrder)
219 {
220 wxHDITEM hdi;
221 hdi.mask = HDI_FORMAT;
222
223 if ( !Header_GetItem(GetHwnd(), idx, &hdi) )
224 {
225 wxLogLastError(_T("Header_GetItem(HDI_FORMAT)"));
226 return;
227 }
228
229 if ( sortOrder == -1 )
230 hdi.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
231 else
232 hdi.fmt |= sortOrder ? HDF_SORTUP : HDF_SORTDOWN;
233
234 if ( !Header_SetItem(GetHwnd(), idx, &hdi) )
235 {
236 wxLogLastError(_T("Header_SetItem(HDI_FORMAT)"));
237 }
238 }
239