]> git.saurik.com Git - wxWidgets.git/blame - src/common/rearrangectrl.cpp
allow the user to pass NULL for the status widths; this was a feature supported by...
[wxWidgets.git] / src / common / rearrangectrl.cpp
CommitLineData
af67f39d
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/common/rearrangectrl.cpp
3// Purpose: implementation of classes in wx/rearrangectrl.h
4// Author: Vadim Zeitlin
5// Created: 2008-12-15
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
3a492e5c 27 #include "wx/button.h"
627e6ccd 28 #include "wx/stattext.h"
3a492e5c 29 #include "wx/sizer.h"
af67f39d
VZ
30#endif // WX_PRECOMP
31
32#include "wx/rearrangectrl.h"
33
34// ============================================================================
35// wxRearrangeList implementation
36// ============================================================================
37
38extern
39WXDLLIMPEXP_DATA_CORE(const char) wxRearrangeListNameStr[] = "wxRearrangeList";
40
41BEGIN_EVENT_TABLE(wxRearrangeList, wxCheckListBox)
42 EVT_CHECKLISTBOX(wxID_ANY, wxRearrangeList::OnCheck)
43END_EVENT_TABLE()
44
45bool wxRearrangeList::Create(wxWindow *parent,
46 wxWindowID id,
47 const wxPoint& pos,
48 const wxSize& size,
49 const wxArrayInt& order,
50 const wxArrayString& items,
51 long style,
52 const wxValidator& validator,
53 const wxString& name)
54{
55 // construct the array of items in the order in which they should appear in
56 // the control
57 const size_t count = items.size();
58 wxCHECK_MSG( order.size() == count, false, "arrays not in sync" );
59
60 wxArrayString itemsInOrder;
61 itemsInOrder.reserve(count);
62 size_t n;
63 for ( n = 0; n < count; n++ )
64 {
65 int idx = order[n];
66 if ( idx < 0 )
67 idx = -idx - 1;
68 itemsInOrder.push_back(items[idx]);
69 }
70
71 // do create the real control
72 if ( !wxCheckListBox::Create(parent, id, pos, size, itemsInOrder,
73 style, validator, name) )
74 return false;
75
76 // and now check all the items which should be initially checked
77 for ( n = 0; n < count; n++ )
78 {
79 if ( order[n] >= 0 )
80 Check(n);
81 }
82
83 m_order = order;
84
85 return true;
86}
87
88bool wxRearrangeList::CanMoveCurrentUp() const
89{
90 const int sel = GetSelection();
91 return sel != wxNOT_FOUND && sel != 0;
92}
93
94bool wxRearrangeList::CanMoveCurrentDown() const
95{
96 const int sel = GetSelection();
97 return sel != wxNOT_FOUND && static_cast<unsigned>(sel) != GetCount() - 1;
98}
99
100bool wxRearrangeList::MoveCurrentUp()
101{
102 const int sel = GetSelection();
103 if ( sel == wxNOT_FOUND || sel == 0 )
104 return false;
105
106 Swap(sel, sel - 1);
107 SetSelection(sel - 1);
108
109 return true;
110}
111
112bool wxRearrangeList::MoveCurrentDown()
113{
114 const int sel = GetSelection();
115 if ( sel == wxNOT_FOUND || static_cast<unsigned>(sel) == GetCount() - 1 )
116 return false;
117
118 Swap(sel, sel + 1);
119 SetSelection(sel + 1);
120
121 return true;
122}
123
124void wxRearrangeList::Swap(int pos1, int pos2)
125{
126 wxSwap(m_order[pos1], m_order[pos2]);
127
128 const wxString stringTmp = GetString(pos1);
129 const bool checkedTmp = IsChecked(pos1);
130
131 SetString(pos1, GetString(pos2));
132 Check(pos1, IsChecked(pos2));
133
134 SetString(pos2, stringTmp);
135 Check(pos2, checkedTmp);
136}
137
138void wxRearrangeList::OnCheck(wxCommandEvent& event)
139{
140 // update the internal state to match the new item state
141 const int n = event.GetInt();
142
af67f39d 143 m_order[n] = ~m_order[n];
d169fa6a
VZ
144
145 wxASSERT_MSG( (m_order[n] >= 0) == IsChecked(n),
146 "discrepancy between internal state and GUI" );
af67f39d
VZ
147}
148
149// ============================================================================
150// wxRearrangeCtrl implementation
151// ============================================================================
152
153BEGIN_EVENT_TABLE(wxRearrangeCtrl, wxPanel)
154 EVT_UPDATE_UI(wxID_UP, wxRearrangeCtrl::OnUpdateButtonUI)
155 EVT_UPDATE_UI(wxID_DOWN, wxRearrangeCtrl::OnUpdateButtonUI)
156
157 EVT_BUTTON(wxID_UP, wxRearrangeCtrl::OnButton)
158 EVT_BUTTON(wxID_DOWN, wxRearrangeCtrl::OnButton)
159END_EVENT_TABLE()
160
161void wxRearrangeCtrl::Init()
162{
163 m_list = NULL;
164}
165
166bool
167wxRearrangeCtrl::Create(wxWindow *parent,
168 wxWindowID id,
169 const wxPoint& pos,
170 const wxSize& size,
171 const wxArrayInt& order,
172 const wxArrayString& items,
173 long style,
174 const wxValidator& validator,
175 const wxString& name)
176{
177 // create all the windows
178 if ( !wxPanel::Create(parent, id, pos, size, wxTAB_TRAVERSAL, name) )
179 return false;
180
181 m_list = new wxRearrangeList(this, wxID_ANY,
182 wxDefaultPosition, wxDefaultSize,
183 order, items,
184 style, validator);
185 wxButton * const btnUp = new wxButton(this, wxID_UP);
186 wxButton * const btnDown = new wxButton(this, wxID_DOWN);
187
188 // arrange them in a sizer
189 wxSizer * const sizerBtns = new wxBoxSizer(wxVERTICAL);
190 sizerBtns->Add(btnUp, wxSizerFlags().Centre().Border(wxBOTTOM));
191 sizerBtns->Add(btnDown, wxSizerFlags().Centre().Border(wxTOP));
192
193 wxSizer * const sizerTop = new wxBoxSizer(wxHORIZONTAL);
194 sizerTop->Add(m_list, wxSizerFlags(1).Expand().Border(wxRIGHT));
195 sizerTop->Add(sizerBtns, wxSizerFlags(0).Centre().Border(wxLEFT));
196 SetSizer(sizerTop);
197
198 m_list->SetFocus();
199
200 return true;
201}
202
203void wxRearrangeCtrl::OnUpdateButtonUI(wxUpdateUIEvent& event)
204{
205 event.Enable( event.GetId() == wxID_UP ? m_list->CanMoveCurrentUp()
206 : m_list->CanMoveCurrentDown() );
207}
208
209void wxRearrangeCtrl::OnButton(wxCommandEvent& event)
210{
211 if ( event.GetId() == wxID_UP )
212 m_list->MoveCurrentUp();
213 else
214 m_list->MoveCurrentDown();
215}
216
217// ============================================================================
218// wxRearrangeDialog implementation
219// ============================================================================
220
221extern
222WXDLLIMPEXP_DATA_CORE(const char) wxRearrangeDialogNameStr[] = "wxRearrangeDlg";
223
5a5f305a 224namespace
af67f39d 225{
5a5f305a
VZ
226
227enum wxRearrangeDialogSizerPositions
228{
229 Pos_Label,
230 Pos_Ctrl,
231 Pos_Buttons,
232 Pos_Max
233};
234
235} // anonymous namespace
236
237bool wxRearrangeDialog::Create(wxWindow *parent,
238 const wxString& message,
239 const wxString& title,
240 const wxArrayInt& order,
241 const wxArrayString& items,
242 const wxPoint& pos,
243 const wxString& name)
244{
245 if ( !wxDialog::Create(parent, wxID_ANY, title,
246 pos, wxDefaultSize,
247 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER,
248 name) )
249 return false;
250
af67f39d
VZ
251 m_ctrl = new wxRearrangeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
252 order, items);
253
5a5f305a
VZ
254 // notice that the items in this sizer should be inserted accordingly to
255 // wxRearrangeDialogSizerPositions order
af67f39d
VZ
256 wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
257 sizerTop->Add(new wxStaticText(this, wxID_ANY, message),
5a5f305a 258 wxSizerFlags().Border());
af67f39d
VZ
259 sizerTop->Add(m_ctrl,
260 wxSizerFlags(1).Expand().Border());
261 sizerTop->Add(CreateSeparatedButtonSizer(wxOK | wxCANCEL),
262 wxSizerFlags().Expand().Border());
263 SetSizerAndFit(sizerTop);
5a5f305a
VZ
264
265 return true;
266}
267
268void wxRearrangeDialog::AddExtraControls(wxWindow *win)
269{
270 wxSizer * const sizer = GetSizer();
271 wxCHECK_RET( sizer, "the dialog must be created first" );
272
273 wxASSERT_MSG( sizer->GetChildren().GetCount() == Pos_Max,
274 "calling AddExtraControls() twice?" );
275
276 sizer->Insert(Pos_Buttons, win, wxSizerFlags().Expand().Border());
277
278 win->MoveAfterInTabOrder(m_ctrl);
279
280 // we need to update the initial/minimal window size
281 sizer->SetSizeHints(this);
282}
283
284wxRearrangeList *wxRearrangeDialog::GetList() const
285{
286 wxCHECK_MSG( m_ctrl, NULL, "the dialog must be created first" );
287
288 return m_ctrl->GetList();
289}
290
291wxArrayInt wxRearrangeDialog::GetOrder() const
292{
293 wxCHECK_MSG( m_ctrl, wxArrayInt(), "the dialog must be created first" );
294
295 return m_ctrl->GetList()->GetCurrentOrder();
af67f39d 296}