1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/rearrangectrl.cpp
3 // Purpose: implementation of classes in wx/rearrangectrl.h
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #if wxUSE_REARRANGECTRL
29 #include "wx/button.h"
30 #include "wx/stattext.h"
34 #include "wx/rearrangectrl.h"
36 // ============================================================================
37 // wxRearrangeList implementation
38 // ============================================================================
41 WXDLLIMPEXP_DATA_CORE(const char) wxRearrangeListNameStr
[] = "wxRearrangeList";
43 BEGIN_EVENT_TABLE(wxRearrangeList
, wxCheckListBox
)
44 EVT_CHECKLISTBOX(wxID_ANY
, wxRearrangeList::OnCheck
)
47 bool wxRearrangeList::Create(wxWindow
*parent
,
51 const wxArrayInt
& order
,
52 const wxArrayString
& items
,
54 const wxValidator
& validator
,
57 // construct the array of items in the order in which they should appear in
59 const size_t count
= items
.size();
60 wxCHECK_MSG( order
.size() == count
, false, "arrays not in sync" );
62 wxArrayString itemsInOrder
;
63 itemsInOrder
.reserve(count
);
65 for ( n
= 0; n
< count
; n
++ )
70 itemsInOrder
.push_back(items
[idx
]);
73 // do create the real control
74 if ( !wxCheckListBox::Create(parent
, id
, pos
, size
, itemsInOrder
,
75 style
, validator
, name
) )
78 // and now check all the items which should be initially checked
79 for ( n
= 0; n
< count
; n
++ )
90 bool wxRearrangeList::CanMoveCurrentUp() const
92 const int sel
= GetSelection();
93 return sel
!= wxNOT_FOUND
&& sel
!= 0;
96 bool wxRearrangeList::CanMoveCurrentDown() const
98 const int sel
= GetSelection();
99 return sel
!= wxNOT_FOUND
&& static_cast<unsigned>(sel
) != GetCount() - 1;
102 bool wxRearrangeList::MoveCurrentUp()
104 const int sel
= GetSelection();
105 if ( sel
== wxNOT_FOUND
|| sel
== 0 )
109 SetSelection(sel
- 1);
114 bool wxRearrangeList::MoveCurrentDown()
116 const int sel
= GetSelection();
117 if ( sel
== wxNOT_FOUND
|| static_cast<unsigned>(sel
) == GetCount() - 1 )
121 SetSelection(sel
+ 1);
126 void wxRearrangeList::Swap(int pos1
, int pos2
)
128 wxSwap(m_order
[pos1
], m_order
[pos2
]);
130 const wxString stringTmp
= GetString(pos1
);
131 const bool checkedTmp
= IsChecked(pos1
);
133 SetString(pos1
, GetString(pos2
));
134 Check(pos1
, IsChecked(pos2
));
136 SetString(pos2
, stringTmp
);
137 Check(pos2
, checkedTmp
);
140 void wxRearrangeList::OnCheck(wxCommandEvent
& event
)
142 // update the internal state to match the new item state
143 const int n
= event
.GetInt();
145 m_order
[n
] = ~m_order
[n
];
147 wxASSERT_MSG( (m_order
[n
] >= 0) == IsChecked(n
),
148 "discrepancy between internal state and GUI" );
151 // ============================================================================
152 // wxRearrangeCtrl implementation
153 // ============================================================================
155 BEGIN_EVENT_TABLE(wxRearrangeCtrl
, wxPanel
)
156 EVT_UPDATE_UI(wxID_UP
, wxRearrangeCtrl::OnUpdateButtonUI
)
157 EVT_UPDATE_UI(wxID_DOWN
, wxRearrangeCtrl::OnUpdateButtonUI
)
159 EVT_BUTTON(wxID_UP
, wxRearrangeCtrl::OnButton
)
160 EVT_BUTTON(wxID_DOWN
, wxRearrangeCtrl::OnButton
)
163 void wxRearrangeCtrl::Init()
169 wxRearrangeCtrl::Create(wxWindow
*parent
,
173 const wxArrayInt
& order
,
174 const wxArrayString
& items
,
176 const wxValidator
& validator
,
177 const wxString
& name
)
179 // create all the windows
180 if ( !wxPanel::Create(parent
, id
, pos
, size
, wxTAB_TRAVERSAL
, name
) )
183 m_list
= new wxRearrangeList(this, wxID_ANY
,
184 wxDefaultPosition
, wxDefaultSize
,
187 wxButton
* const btnUp
= new wxButton(this, wxID_UP
);
188 wxButton
* const btnDown
= new wxButton(this, wxID_DOWN
);
190 // arrange them in a sizer
191 wxSizer
* const sizerBtns
= new wxBoxSizer(wxVERTICAL
);
192 sizerBtns
->Add(btnUp
, wxSizerFlags().Centre().Border(wxBOTTOM
));
193 sizerBtns
->Add(btnDown
, wxSizerFlags().Centre().Border(wxTOP
));
195 wxSizer
* const sizerTop
= new wxBoxSizer(wxHORIZONTAL
);
196 sizerTop
->Add(m_list
, wxSizerFlags(1).Expand().Border(wxRIGHT
));
197 sizerTop
->Add(sizerBtns
, wxSizerFlags(0).Centre().Border(wxLEFT
));
205 void wxRearrangeCtrl::OnUpdateButtonUI(wxUpdateUIEvent
& event
)
207 event
.Enable( event
.GetId() == wxID_UP
? m_list
->CanMoveCurrentUp()
208 : m_list
->CanMoveCurrentDown() );
211 void wxRearrangeCtrl::OnButton(wxCommandEvent
& event
)
213 if ( event
.GetId() == wxID_UP
)
214 m_list
->MoveCurrentUp();
216 m_list
->MoveCurrentDown();
219 // ============================================================================
220 // wxRearrangeDialog implementation
221 // ============================================================================
224 WXDLLIMPEXP_DATA_CORE(const char) wxRearrangeDialogNameStr
[] = "wxRearrangeDlg";
229 enum wxRearrangeDialogSizerPositions
237 } // anonymous namespace
239 bool wxRearrangeDialog::Create(wxWindow
*parent
,
240 const wxString
& message
,
241 const wxString
& title
,
242 const wxArrayInt
& order
,
243 const wxArrayString
& items
,
245 const wxString
& name
)
247 if ( !wxDialog::Create(parent
, wxID_ANY
, title
,
249 wxDEFAULT_DIALOG_STYLE
| wxRESIZE_BORDER
,
253 m_ctrl
= new wxRearrangeCtrl(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
256 // notice that the items in this sizer should be inserted accordingly to
257 // wxRearrangeDialogSizerPositions order
258 wxSizer
* const sizerTop
= new wxBoxSizer(wxVERTICAL
);
259 sizerTop
->Add(new wxStaticText(this, wxID_ANY
, message
),
260 wxSizerFlags().Border());
261 sizerTop
->Add(m_ctrl
,
262 wxSizerFlags(1).Expand().Border());
263 sizerTop
->Add(CreateSeparatedButtonSizer(wxOK
| wxCANCEL
),
264 wxSizerFlags().Expand().Border());
265 SetSizerAndFit(sizerTop
);
270 void wxRearrangeDialog::AddExtraControls(wxWindow
*win
)
272 wxSizer
* const sizer
= GetSizer();
273 wxCHECK_RET( sizer
, "the dialog must be created first" );
275 wxASSERT_MSG( sizer
->GetChildren().GetCount() == Pos_Max
,
276 "calling AddExtraControls() twice?" );
278 sizer
->Insert(Pos_Buttons
, win
, wxSizerFlags().Expand().Border());
280 win
->MoveAfterInTabOrder(m_ctrl
);
282 // we need to update the initial/minimal window size
283 sizer
->SetSizeHints(this);
286 wxRearrangeList
*wxRearrangeDialog::GetList() const
288 wxCHECK_MSG( m_ctrl
, NULL
, "the dialog must be created first" );
290 return m_ctrl
->GetList();
293 wxArrayInt
wxRearrangeDialog::GetOrder() const
295 wxCHECK_MSG( m_ctrl
, wxArrayInt(), "the dialog must be created first" );
297 return m_ctrl
->GetList()->GetCurrentOrder();
300 #endif // wxUSE_REARRANGECTRL