NCBI C++ ToolKit
growable_list.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: growable_list.cpp 40968 2018-05-04 16:42:02Z katargir $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Igor Filippov
27  */
28 
29 
30 #include <ncbi_pch.hpp>
33 #include <wx/statline.h>
34 #include "growable_list.hpp"
35 
37 
38 /*!
39  * CGrowableListCtrl type definition
40  */
41 
42 IMPLEMENT_DYNAMIC_CLASS( CGrowableListCtrl, wxPanel )
43 
44 
45 /*!
46  * CGrowableListCtrl event table definition
47  */
48 
49 BEGIN_EVENT_TABLE( CGrowableListCtrl, wxPanel )
50 
51 ////@begin CGrowableListCtrl event table entries
52 
53 ////@end CGrowableListCtrl event table entries
54 
56  EVT_COMMAND(wxID_ANY, wxEVT_SPIN_CTRL_EVENT, CGrowableListCtrl::OnSpinCtrl)
57 
59 
61 
62 /*!
63  * CGrowableListCtrl constructors
64  */
65 
67 {
68  Init();
69 }
70 
71 CGrowableListCtrl::CGrowableListCtrl( wxWindow* parent, const wxArrayString &items,
72  wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
73  : m_Items(items)
74 {
75  if (m_Items.IsEmpty())
76  m_Items.Add(wxEmptyString);
77  for (size_t i = 0; i < m_Items.GetCount(); i++)
78  {
79  SIntData intData;
80  intData.m_Item = m_Items[i];
81  intData.m_Empty = false;
82  if (intData.m_Item.IsEmpty())
83  intData.m_Empty = true;
84  m_Data.push_back(intData);
85  }
86  Init();
87  Create(parent, id, pos, size, style);
88 }
89 
90 
91 /*!
92  * CGrowableListCtrl creator
93  */
94 
95 bool CGrowableListCtrl::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
96 {
97 ////@begin CGrowableListCtrl creation
98  wxPanel::Create( parent, id, pos, size, style );
99 
100  CreateControls();
101  if (GetSizer())
102  {
103  GetSizer()->SetSizeHints(this);
104  }
105  Centre();
106 ////@end CGrowableListCtrl creation
107  return true;
108 }
109 
110 
111 /*!
112  * CGrowableListCtrl destructor
113  */
114 
116 {
117 ////@begin CGrowableListCtrl destruction
118 ////@end CGrowableListCtrl destruction
119 }
120 
121 
122 /*!
123  * Member initialisation
124  */
125 
127 {
128 ////@begin CGrowableListCtrl member initialisation
130 ////@end CGrowableListCtrl member initialisation
131  m_Sizer = NULL;
132 }
133 
134 
135 /*!
136  * Control creation for CGrowableListCtrl
137  */
138 
140 {
141 ////@begin CGrowableListCtrl content construction
142  CGrowableListCtrl* itemPanel1 = this;
143 
144  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
145  itemPanel1->SetSizer(itemBoxSizer2);
146 
147  wxPanel* itemPanel3 = new wxPanel( itemPanel1, ID_CGROWABLELISTCTRL_PANEL1, wxDefaultPosition, wxSize(-1,100), wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
148  itemBoxSizer2->Add(itemPanel3, 1, wxGROW|wxALL, 0);
149 
150  wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxVERTICAL);
151  itemPanel3->SetSizer(itemBoxSizer4);
152 
153  m_ScrolledWindow = new wxScrolledWindow( itemPanel3, ID_CGROWABLELISTCTRL_SCROLLEDWINDOW1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
154  itemBoxSizer4->Add(m_ScrolledWindow, 1, wxGROW|wxTOP|wxBOTTOM, 0);
155  m_ScrolledWindow->SetScrollbars(1, 1, 0, 0);
156 
157 
158  ////@end CGrowableListCtrl content construction
159 
160  m_Sizer = new wxFlexGridSizer(0, kCtrlColNum, 0, 0);
161  m_ScrolledWindow->SetSizer(m_Sizer);
162  m_ScrolledWindow->FitInside();
163 
164  //m_AddIntHyperlink->SetVisitedColour(m_AddIntHyperlink->GetNormalColour());
165  m_ScrolledWindow->SetScrollRate(0, 5);
166 
167  vector<SIntData>::const_iterator it;
168  for (it = m_Data.begin(); it != m_Data.end(); ++it) {
169  if (it->m_Empty) {
170  x_AddEmptyRow ();
171  } else {
172  x_AddRow(it->m_Item);
173  }
174  }
175  m_ScrolledWindow->FitInside();
176 }
177 
178 
179 void CGrowableListCtrl::AddRow(const wxString& item)
180 {
181 
182  SIntData intData;
183  intData.m_Item = item;
184  intData.m_Empty = false;
185  m_Data.push_back(intData);
186 }
187 
189 {
190  SIntData intData;
191  intData.m_Empty = true;
192  m_Data.push_back(intData);
193 }
194 
196 {
197  m_Data.clear();
198  m_Sizer->Clear(true);
199 }
200 
201 static void s_DeleteRow(wxSizerItemList::iterator row, wxSizerItemList& itemList)
202 {
203  wxSizerItemList::iterator node = row;
204  for (int i = 0; node != itemList.end() && i < kCtrlColNum; ++i) {
205  (**node).DeleteWindows();
206  node = itemList.erase(node);
207  }
208 }
209 
210 static wxSizerItemList::iterator s_FindRow(wxWindow* wnd, wxSizerItemList& itemList)
211 {
212  if (NULL == wnd)
213  return itemList.end();
214 
215  wxSizerItemList::iterator row, it = itemList.begin();
216 
217  for(int index = 0; it != itemList.end(); ++it, --index) {
218  if (index == 0) {
219  row = it;
220  index = kCtrlColNum;
221  }
222 
223  wxSizer* sizer = (**it).GetSizer();
224  if (sizer && sizer->GetItem(wnd))
225  return row;
226  else if ((**it).GetWindow() == wnd)
227  return row;
228  }
229 
230  return it;
231 }
232 
233 static wxSizerItemList::iterator s_NextRow(wxSizerItemList::iterator row, wxSizerItemList& itemList)
234 {
235  wxSizerItemList::iterator it = row;
236  for (int i = 0; i < kCtrlColNum; ++i, ++it) {
237  if (it == itemList.end())
238  return itemList.end();
239  }
240  return it;
241 }
242 
243 static wxSizerItemList::iterator s_PrevRow(wxSizerItemList::iterator row, wxSizerItemList& itemList)
244 {
245  wxSizerItemList::iterator it = row;
246  for (int i = 0; i < kCtrlColNum; ++i, --it) {
247  if (it == itemList.begin())
248  return itemList.end();
249  }
250  return it;
251 }
252 
253 static void s_SwapRows(wxSizerItemList::iterator row1,
254  wxSizerItemList::iterator row2,
255  wxSizerItemList& itemList)
256 {
257  for (int i = 0; i < 4; ++i) {
258  if (row1 == itemList.end() || row2 == itemList.end())
259  break;
260  swap(*row1++, *row2++);
261  }
262 }
263 
264 static void s_GetRowData(wxSizerItemList::iterator row, wxSizerItemList& itemList,
265  wxString& item)
266 {
267  wxSizerItemList::iterator node = row;
268 
269  if (node == itemList.end())return;
270 
271  wxComboBox* combo = (wxComboBox*)(**node).GetWindow();
272  item = combo->GetValue();
273 }
274 
275 void CGrowableListCtrl::OnDelete (wxHyperlinkEvent& event)
276 {
277  wxSizerItemList& itemList = m_Sizer->GetChildren();
278  wxSizerItemList::iterator row = s_FindRow((wxWindow*)event.GetEventObject(), itemList);
279  s_DeleteRow(row, itemList);
280  if (m_Sizer->GetChildren().size() == 0) {
281  x_AddEmptyRow();
282  }
283  m_ScrolledWindow->FitInside();
284 }
285 
286 void CGrowableListCtrl::OnSpinCtrl ( wxCommandEvent& evt )
287 {
288  wxWindow* spnCtrl = (wxWindow*)evt.GetEventObject();
289 
290  wxSizerItemList& itemList = m_Sizer->GetChildren();
291  wxSizerItemList::iterator row = s_FindRow(spnCtrl, itemList);
292  if (row == itemList.end())
293  return;
294 
295  wxSizerItemList::iterator row2;
296 
297  switch (evt.GetId()) {
299  row2 = s_PrevRow(row, itemList);
300  s_SwapRows(row, row2, itemList);
301  m_Sizer->Layout();
302  m_ScrolledWindow->Refresh();
303  break;
305  row2 = s_NextRow(row, itemList);
306  s_SwapRows(row, row2, itemList);
307  m_Sizer->Layout();
308  m_ScrolledWindow->Refresh();
309  break;
310  case 2 + CSpinControl::kBtnUp:
311  {{
312  size_t rowPos = itemList.IndexOf(*row);
313  wxString item;
314  s_GetRowData(row, itemList, item);
315 
316 #if 1
317  x_AddEmptyRow(rowPos);
318 #else
319  x_AddRow(item, rowPos);
320 #endif
321  m_Sizer->Layout();
322  m_ScrolledWindow->FitInside();
323  m_ScrolledWindow->Refresh();
324  }}
325  break;
326  case 2 + CSpinControl::kBtnDn:
327  {{
328  wxString item;
329  s_GetRowData(row, itemList, item);
330 
331  row = s_NextRow(row, itemList);
332  size_t rowPos = (row == itemList.end()) ? (size_t)-1 : itemList.IndexOf(*row);
333 #if 1
334  x_AddEmptyRow(rowPos);
335 #else
336  x_AddRow(item, rowPos);
337 #endif
338  m_Sizer->Layout();
339  m_ScrolledWindow->FitInside();
340  m_ScrolledWindow->Refresh();
341  }}
342  break;
343  }
344 }
345 
346 
347 void CGrowableListCtrl::x_AddRow(const wxString& item, size_t rowPos)
348 {
349  wxComboBox *combo = new wxComboBox(m_ScrolledWindow, wxID_ANY, item,
350  wxDefaultPosition,
351  wxSize(m_ScrolledWindow->ConvertDialogToPixels(wxSize(65, -1)).x, -1),
352  m_Items);
353  if (rowPos == (size_t)-1)
354  m_Sizer->Add(combo, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
355  else
356  m_Sizer->Insert(rowPos++, combo, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
357 
358  wxBoxSizer* controlsSizer = new wxBoxSizer(wxHORIZONTAL);
359  if (rowPos == (size_t)-1)
360  m_Sizer->Add(controlsSizer);
361  else
362  m_Sizer->Insert(rowPos++, controlsSizer);
363 
364  wxHyperlinkCtrl* itemHyperLink = new CHyperlink(m_ScrolledWindow, wxID_ANY, wxT("Delete"), wxT(""));
365  itemHyperLink->SetVisitedColour(itemHyperLink->GetNormalColour());
366  controlsSizer->Add(itemHyperLink, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 0);
367 
368  CSpinControl* spinCtrl = new CSpinControl(m_ScrolledWindow, wxID_ANY, wxDefaultPosition);
369  spinCtrl->SetToolTip(_("Use arrow controls to reorder list"));
370  controlsSizer->Add(spinCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 0);
371 
372  spinCtrl = new CSpinControl(m_ScrolledWindow, wxID_ANY, wxDefaultPosition);
373  spinCtrl->SetToolTip(_("Use plus/plus controls to insert blank elements"));
374  spinCtrl->UseImageSet(1);
375  controlsSizer->Add(spinCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 0);
376 }
377 
379 {
380 
381  wxComboBox *combo = new wxComboBox(m_ScrolledWindow, wxID_ANY, wxT(""),
382  wxDefaultPosition,
383  wxSize(m_ScrolledWindow->ConvertDialogToPixels(wxSize(65, -1)).x, -1),
384  m_Items);
385  if (rowPos == (size_t)-1)
386  m_Sizer->Add(combo, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
387  else
388  m_Sizer->Insert(rowPos++, combo, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
389 
390  wxBoxSizer* controlsSizer = new wxBoxSizer(wxHORIZONTAL);
391  if (rowPos == (size_t)-1)
392  m_Sizer->Add(controlsSizer);
393  else
394  m_Sizer->Insert(rowPos++, controlsSizer);
395 
396  wxHyperlinkCtrl* itemHyperLink = new CHyperlink(m_ScrolledWindow, wxID_ANY, wxT("Delete"), wxT(""));
397  itemHyperLink->SetVisitedColour(itemHyperLink->GetNormalColour());
398  controlsSizer->Add(itemHyperLink, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 0);
399 
400  CSpinControl* spinCtrl = new CSpinControl(m_ScrolledWindow, wxID_ANY, wxDefaultPosition);
401  controlsSizer->Add(spinCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 0);
402 
403  spinCtrl = new CSpinControl(m_ScrolledWindow, wxID_ANY, wxDefaultPosition);
404  spinCtrl->UseImageSet(1);
405  controlsSizer->Add(spinCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 0);
406 
407 }
408 
409 
411 {
412  if (!wxPanel::TransferDataToWindow())
413  return false;
414 
415  wxSizerItemList& children = m_Sizer->GetChildren();
416  wxSizerItemList::iterator node = children.begin();
417  for (; node != children.end(); ++node)
418  (**node).DeleteWindows();
419  children.clear();
420 
421  vector<SIntData>::const_iterator it;
422  for (it = m_Data.begin(); it != m_Data.end(); ++it) {
423  if (it->m_Empty) {
424  x_AddEmptyRow ();
425  } else {
426  x_AddRow(it->m_Item);
427  }
428  }
429 
430  m_ScrolledWindow->FitInside();
431  return true;
432 }
433 
434 void CGrowableListCtrl::GetItems(vector<string> &items)
435 {
436  wxSizerItemList& children = m_Sizer->GetChildren();
437  for (wxSizerItemList::iterator node = children.begin(); node != children.end(); ++node)
438  {
439 
440  wxComboBox* item_combo = (wxComboBox*)(**node).GetWindow();
441  if (item_combo && !item_combo->IsTextEmpty())
442  {
443  items.push_back(item_combo->GetValue().ToStdString());
444  }
445  }
446 }
447 
449 {
450  if (!wxPanel::TransferDataFromWindow())
451  return false;
452 
453  m_Data.clear();
454 
455  wxSizerItemList& children = m_Sizer->GetChildren();
456 
457  for ( wxSizerItemList::iterator node = children.begin(); node != children.end(); ++node)
458  {
459  SIntData intData;
460 
461  wxComboBox* item_combo = (wxComboBox*)(**node).GetWindow();
462  if (!item_combo)
463  continue;
464 
465  if (item_combo->IsTextEmpty())
466  {
467  intData.m_Empty = true;
468  }
469  else
470  {
471  intData.m_Item = item_combo->GetValue();
472  intData.m_Empty = false;
473  }
474  m_Data.push_back(intData);
475  }
476  return true;
477 }
478 
479 
480 /*!
481  * Should we show tooltips?
482  */
483 
485 {
486  return true;
487 }
488 
489 /*!
490  * Get bitmap resources
491  */
492 
493 wxBitmap CGrowableListCtrl::GetBitmapResource( const wxString& name )
494 {
495  // Bitmap retrieval
496 ////@begin CGrowableListCtrl bitmap retrieval
497  wxUnusedVar(name);
498  return wxNullBitmap;
499 ////@end CGrowableListCtrl bitmap retrieval
500 }
501 
502 /*!
503  * Get icon resources
504  */
505 
506 wxIcon CGrowableListCtrl::GetIconResource( const wxString& name )
507 {
508  // Icon retrieval
509 ////@begin CGrowableListCtrl icon retrieval
510  wxUnusedVar(name);
511  return wxNullIcon;
512 ////@end CGrowableListCtrl icon retrieval
513 }
514 
515 
516 void CGrowableListCtrl::SetItems( const wxArrayString &items)
517 {
518  m_Items = items;
519  if (m_Items.IsEmpty())
520  m_Items.Add(wxEmptyString);
521  m_Data.clear();
522  for (size_t i = 0; i < m_Items.GetCount(); i++)
523  {
524  SIntData intData;
525  intData.m_Item = m_Items[i];
526  intData.m_Empty = false;
527  if (intData.m_Item.IsEmpty())
528  intData.m_Empty = true;
529  m_Data.push_back(intData);
530  }
532  Refresh();
533 }
534 
void Init()
Initialises member variables.
virtual bool TransferDataToWindow()
wxArrayString m_Items
void GetItems(vector< string > &items)
wxScrolledWindow * m_ScrolledWindow
void x_AddRow(const wxString &item, size_t rowPos=-1)
void x_AddEmptyRow(size_t rowPos=-1)
void OnDelete(wxHyperlinkEvent &event)
void AddRow(const wxString &item)
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
wxFlexGridSizer * m_Sizer
vector< SIntData > m_Data
virtual bool TransferDataFromWindow()
void SetItems(const wxArrayString &items)
bool Create(wxWindow *parent, wxWindowID id=ID_CGROWABLELISTCTRL, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1, 200), long style=wxSUNKEN_BORDER|wxTAB_TRAVERSAL)
Creation.
void CreateControls()
Creates the controls and sizers.
static bool ShowToolTips()
Should we show tooltips?
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
void OnSpinCtrl(wxCommandEvent &evt)
~CGrowableListCtrl()
Destructor.
CGrowableListCtrl()
Constructors.
void UseImageSet(int set)
Definition: spin_ctrl.cpp:72
#define _(proto)
Definition: ct_nlmzip_i.h:78
static void Init(void)
Definition: cursor6.c:76
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NULL
Definition: ncbistd.hpp:225
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static wxSizerItemList::iterator s_NextRow(wxSizerItemList::iterator row, wxSizerItemList &itemList)
static void s_SwapRows(wxSizerItemList::iterator row1, wxSizerItemList::iterator row2, wxSizerItemList &itemList)
static wxSizerItemList::iterator s_PrevRow(wxSizerItemList::iterator row, wxSizerItemList &itemList)
static void s_GetRowData(wxSizerItemList::iterator row, wxSizerItemList &itemList, wxString &item)
static wxSizerItemList::iterator s_FindRow(wxWindow *wnd, wxSizerItemList &itemList)
const int kCtrlColNum
static void s_DeleteRow(wxSizerItemList::iterator row, wxSizerItemList &itemList)
END_EVENT_TABLE()
int i
#define wxT(x)
Definition: muParser.cpp:41
const struct ncbi::grid::netcache::search::fields::SIZE size
static static static wxID_ANY
#define row(bind, expected)
Definition: string_bind.c:73
#define const
Definition: zconf.h:232
Modified on Mon Jul 22 05:05:44 2024 by modify_doxy.py rev. 669887