PCH-less compilation fix
[wxWidgets.git] / src / common / rearrangectrl.cpp
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
27 #include "wx/button.h"
28 #include "wx/sizer.h"
29 #endif // WX_PRECOMP
30
31 #include "wx/rearrangectrl.h"
32
33 // ============================================================================
34 // wxRearrangeList implementation
35 // ============================================================================
36
37 extern
38 WXDLLIMPEXP_DATA_CORE(const char) wxRearrangeListNameStr[] = "wxRearrangeList";
39
40 BEGIN_EVENT_TABLE(wxRearrangeList, wxCheckListBox)
41 EVT_CHECKLISTBOX(wxID_ANY, wxRearrangeList::OnCheck)
42 END_EVENT_TABLE()
43
44 bool wxRearrangeList::Create(wxWindow *parent,
45 wxWindowID id,
46 const wxPoint& pos,
47 const wxSize& size,
48 const wxArrayInt& order,
49 const wxArrayString& items,
50 long style,
51 const wxValidator& validator,
52 const wxString& name)
53 {
54 // construct the array of items in the order in which they should appear in
55 // the control
56 const size_t count = items.size();
57 wxCHECK_MSG( order.size() == count, false, "arrays not in sync" );
58
59 wxArrayString itemsInOrder;
60 itemsInOrder.reserve(count);
61 size_t n;
62 for ( n = 0; n < count; n++ )
63 {
64 int idx = order[n];
65 if ( idx < 0 )
66 idx = -idx - 1;
67 itemsInOrder.push_back(items[idx]);
68 }
69
70 // do create the real control
71 if ( !wxCheckListBox::Create(parent, id, pos, size, itemsInOrder,
72 style, validator, name) )
73 return false;
74
75 // and now check all the items which should be initially checked
76 for ( n = 0; n < count; n++ )
77 {
78 if ( order[n] >= 0 )
79 Check(n);
80 }
81
82 m_order = order;
83
84 return true;
85 }
86
87 bool wxRearrangeList::CanMoveCurrentUp() const
88 {
89 const int sel = GetSelection();
90 return sel != wxNOT_FOUND && sel != 0;
91 }
92
93 bool wxRearrangeList::CanMoveCurrentDown() const
94 {
95 const int sel = GetSelection();
96 return sel != wxNOT_FOUND && static_cast<unsigned>(sel) != GetCount() - 1;
97 }
98
99 bool wxRearrangeList::MoveCurrentUp()
100 {
101 const int sel = GetSelection();
102 if ( sel == wxNOT_FOUND || sel == 0 )
103 return false;
104
105 Swap(sel, sel - 1);
106 SetSelection(sel - 1);
107
108 return true;
109 }
110
111 bool wxRearrangeList::MoveCurrentDown()
112 {
113 const int sel = GetSelection();
114 if ( sel == wxNOT_FOUND || static_cast<unsigned>(sel) == GetCount() - 1 )
115 return false;
116
117 Swap(sel, sel + 1);
118 SetSelection(sel + 1);
119
120 return true;
121 }
122
123 void wxRearrangeList::Swap(int pos1, int pos2)
124 {
125 wxSwap(m_order[pos1], m_order[pos2]);
126
127 const wxString stringTmp = GetString(pos1);
128 const bool checkedTmp = IsChecked(pos1);
129
130 SetString(pos1, GetString(pos2));
131 Check(pos1, IsChecked(pos2));
132
133 SetString(pos2, stringTmp);
134 Check(pos2, checkedTmp);
135 }
136
137 void wxRearrangeList::OnCheck(wxCommandEvent& event)
138 {
139 // update the internal state to match the new item state
140 const int n = event.GetInt();
141
142 const bool checked = IsChecked(n);
143 wxASSERT_MSG( (m_order[n] >= 0) == !checked,
144 "discrepancy between internal state and GUI" );
145
146 m_order[n] = ~m_order[n];
147 }
148
149 // ============================================================================
150 // wxRearrangeCtrl implementation
151 // ============================================================================
152
153 BEGIN_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)
159 END_EVENT_TABLE()
160
161 void wxRearrangeCtrl::Init()
162 {
163 m_list = NULL;
164 }
165
166 bool
167 wxRearrangeCtrl::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
203 void wxRearrangeCtrl::OnUpdateButtonUI(wxUpdateUIEvent& event)
204 {
205 event.Enable( event.GetId() == wxID_UP ? m_list->CanMoveCurrentUp()
206 : m_list->CanMoveCurrentDown() );
207 }
208
209 void 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
221 extern
222 WXDLLIMPEXP_DATA_CORE(const char) wxRearrangeDialogNameStr[] = "wxRearrangeDlg";
223
224 wxRearrangeDialog::wxRearrangeDialog(wxWindow *parent,
225 const wxString& message,
226 const wxString& title,
227 const wxArrayInt& order,
228 const wxArrayString& items,
229 const wxPoint& pos,
230 const wxString& name)
231 : wxDialog(parent, wxID_ANY, title,
232 pos, wxDefaultSize,
233 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER,
234 name)
235 {
236 m_ctrl = new wxRearrangeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
237 order, items);
238
239 wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
240 sizerTop->Add(new wxStaticText(this, wxID_ANY, message),
241 wxSizerFlags().DoubleBorder());
242 sizerTop->Add(m_ctrl,
243 wxSizerFlags(1).Expand().Border());
244 sizerTop->Add(CreateSeparatedButtonSizer(wxOK | wxCANCEL),
245 wxSizerFlags().Expand().Border());
246 SetSizerAndFit(sizerTop);
247 }