NCBI C++ ToolKit
sel_list_controller.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef GUI_WIDGETS_ALNMULTI___SEL_LIST_CONTROLLER__HPP
2 #define GUI_WIDGETS_ALNMULTI___SEL_LIST_CONTROLLER__HPP
3 
4 /* $Id: sel_list_controller.hpp 47374 2023-02-23 00:42:16Z evgeniev $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Andrey Yazhuk
30  *
31  * File Description:
32  *
33  */
34 #include <corelib/ncbistl.hpp>
35 
39 
40 
42 
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 /// class CSelListController
46 template <class Item> class CSelListController :
47  public IGlEventHandler
48 {
49 public:
50  typedef Item TItem;
52 
54  virtual ~CSelListController();
55 
56 protected:
57  // specialized event handlers
58  virtual void x_OnLeftDown(wxMouseEvent& event);
59  virtual void x_OnLeftUp(wxMouseEvent& event);
60  virtual void x_OnMotion(wxMouseEvent& event);
61  virtual void x_OnKeyDown(wxKeyEvent& event);
62 
63  // functions to be overriden in the inherited class
64  virtual TSelListModel* SLC_GetModel() = 0;
65  virtual int SLC_GetLineByWindowY(int WinY, bool b_clip = false) = 0;
66  virtual int SLC_GetHeight() = 0; // view size in pixels
67  virtual void SLC_VertScrollToMakeVisible(int index) = 0;
68 
69  void x_MoveSelectionBy(int Shift, bool bShift, bool bCtrl);
70  void x_MoveSelLineByPage(bool bDown, bool bShift, bool bCtrl);
71  void x_SelectTo(int index, bool bShift, bool bCtrl);
72  void x_SelectFocusedItem(bool bDeselectEn);
73 
74 protected:
76  wxPoint m_MouseDownPos;
77 };
78 
79 
80 template<class Item>
82 : m_ProcessMouseUp(false)
83 {
84 }
85 template<class Item>
87 {
88 }
89 
90 template<class Item>
91  void CSelListController<Item>::x_OnLeftDown(wxMouseEvent& event)
92 {
93  m_ProcessMouseUp = false;
94  wxPoint ms_pos = event.GetPosition();
95  m_MouseDownPos = ms_pos;
96 
97  TSelListModel* model = SLC_GetModel();
98 
99  if(model) {
100  int index = SLC_GetLineByWindowY(ms_pos.y, true);
102 
103  if(index == -1) {
104  m_ProcessMouseUp = true;
105  } else {
106  switch(state) {
108  m_ProcessMouseUp = model->SLM_IsItemSelected(index);
109  if(m_ProcessMouseUp) {
110  model->SLM_FocusItem(index); // change focus, selection will be changed on MouseUp
111  } else {
112  model->SLM_SelectSingleItem(index);
113  }
114  break;
115  }
117  model->SLM_SelectTo(index);
118  break;
120  m_ProcessMouseUp = true;
121  break;
122  default: break;
123  }
124  }
125  }
126  }
127 }
128 
129 
130 // Small kDragThreshold Value occasionally sets m_ProcessMouseUp to false
131 // when user is fast-clicking through a number of rows and holding ctrl key
132 // Setting m_ProcessMouseUp to false makes it skip Ctrl+click event
133 // which is not what user expects. Perhaps, x_OnMotion shouldn't be processed
134 // at all if Ctrl is down?
135 const static int kDragThreshold = 10; //TODO
136 
137 template<class Item>
138  void CSelListController<Item>::x_OnMotion(wxMouseEvent& event)
139 {
140  if(event.Dragging()) {
141  wxPoint pos = event.GetPosition();
142  m_ProcessMouseUp = abs(pos.x - m_MouseDownPos.x) < kDragThreshold
143  && abs(pos.y - m_MouseDownPos.y) < kDragThreshold;
144  }
145 }
146 
147 
148 template<class Item>
149  void CSelListController<Item>::x_OnLeftUp(wxMouseEvent& event)
150 {
151  TSelListModel* model = SLC_GetModel();
152 
153  if(model && m_ProcessMouseUp) {
154  wxPoint pos = event.GetPosition();
155  int index = SLC_GetLineByWindowY(pos.y, true);
156 
158 
159  if(index == -1) {
160  model->SLM_SelectAll(false);
161  } else {
163  model->SLM_InvertSingleItem(index);
164  } else if(state == CGUIEvent::eSelectState) {
165  //|| (Btn == FL_RIGHT_MOUSE && state == CGUIEvent::eSelectExtState)) {
166  model->SLM_SelectSingleItem(index);
167  }
168  }
169  }
170  m_ProcessMouseUp = false;
171 }
172 
173 
174 template<class Item>
176 {
177  TSelListModel* model = SLC_GetModel();
178 
179  if(model) {
180  int key = event.GetKeyCode();
182  bool b_shift = (state == CGUIEvent::eSelectExtState);
183  bool b_ctrl = (state == CGUIEvent::eSelectIncState);
184 
185  switch(key) {
186  case WXK_HOME:
187  case WXK_NUMPAD_HOME:
188  x_SelectTo(0, b_shift, b_ctrl);
189  break;
190  case WXK_END:
191  case WXK_NUMPAD_END:
192  x_SelectTo(model->SLM_GetItemsCount()-1, b_shift, b_ctrl);
193  break;
194  case WXK_DOWN:
195  case WXK_NUMPAD_DOWN:
196  x_MoveSelectionBy(1, b_shift, b_ctrl);
197  break;
198  case WXK_UP:
199  case WXK_NUMPAD_UP:
200  x_MoveSelectionBy(-1, b_shift, b_ctrl);
201  break;
202  case WXK_PAGEUP:
203  case WXK_NUMPAD_PAGEUP:
204  x_MoveSelLineByPage(false, b_shift, b_ctrl);
205  break;
206  case WXK_PAGEDOWN:
207  case WXK_NUMPAD_PAGEDOWN:
208  x_MoveSelLineByPage(true, b_shift, b_ctrl);
209  break;
210  case ' ':
211  x_SelectFocusedItem(b_ctrl);
212  break;
213  case 'a':
214  case 'A':
215  if(b_ctrl)
216  model->SLM_SelectAll(true);
217  break;
218  default:
219  event.Skip();
220  }
221  }
222 }
223 
224 
225 template<class Item>
226  void CSelListController<Item>::x_MoveSelectionBy(int Shift, bool b_shift, bool b_ctrl)
227 {
228  TSelListModel* model = SLC_GetModel();
229 
230  if(model) {
231  int N = model->SLM_GetItemsCount();
232  if(N > 0) {
233  int iFocused = model->SLM_GetFocusedItemIndex();
234  iFocused = max(iFocused, 0);
235 
236  iFocused += Shift;
237 
238  iFocused = max(iFocused, 0);
239  iFocused = min(iFocused, N - 1);
240 
241  x_SelectTo(iFocused, b_shift, b_ctrl);
242  }
243  }
244 }
245 
246 template<class Item>
247  void CSelListController<Item>::x_SelectTo(int index, bool b_shift, bool b_ctrl)
248 {
249  TSelListModel* model = SLC_GetModel();
250  if(model) {
251  if(b_shift) {
252  model->SLM_SelectTo(index);
253  } else {
254  if(b_ctrl) {
255  model->SLM_FocusItem(index);
256  } else {
257  model->SLM_SelectSingleItem(index);
258  }
259  }
260  SLC_VertScrollToMakeVisible(index);
261  }
262 }
263 
264 template<class Item>
265  void CSelListController<Item>::x_MoveSelLineByPage(bool bDown, bool b_shift, bool b_ctrl)
266 {
267  TSelListModel* model = SLC_GetModel();
268  if(model) {
269  if(bDown) { // page Down
270  int PosY = SLC_GetHeight();
271  int iBottom = SLC_GetLineByWindowY(PosY);
272  int iFocused = model->SLM_GetFocusedItemIndex();
273 
274  if(iFocused == iBottom) { // page down
275  PosY += PosY;
276  iBottom = SLC_GetLineByWindowY(PosY);
277  }
278  if(iBottom == -1)
279  iBottom = model->SLM_GetItemsCount()-1;
280 
281  x_SelectTo(iBottom, b_shift, b_ctrl);
282  } else { // page Up
283  int iTop = SLC_GetLineByWindowY(0);
284  int iFocused = model->SLM_GetFocusedItemIndex();
285 
286  if(iFocused == iTop) { // page down
287  int PosY = SLC_GetHeight();
288  iTop = SLC_GetLineByWindowY(PosY);
289  }
290  if(iTop == -1)
291  iTop = min(0, model->SLM_GetItemsCount()-1);
292  if(iTop > -1)
293  x_SelectTo(iTop, b_shift, b_ctrl);
294  }
295  }
296 }
297 
298 template<class Item>
300 {
301  TSelListModel* model = SLC_GetModel();
302  if(model) {
303  int iFocused = model->SLM_GetFocusedItemIndex();
304  if(iFocused != -1) {
305  bool bSel = model->SLM_IsItemSelected(iFocused);
306  if( ! bSel || (bSel && bDeselectEn))
307  model->SLM_InvertSingleItem(iFocused);
308  }
309  }
310 }
311 
312 
314 
315 
316 #endif // GUI_WIDGETS_ALNMULTI___SEL_LIST_CONTROLLER__HPP
static EGUIState wxGetSelectState(const wxMouseEvent &event)
Definition: gui_event.cpp:42
@ eSelectExtState
Definition: gui_event.hpp:110
@ eSelectIncState
Definition: gui_event.hpp:109
class CSelListController
ISelListModel< Item > TSelListModel
virtual void SLC_VertScrollToMakeVisible(int index)=0
virtual void x_OnLeftDown(wxMouseEvent &event)
virtual int SLC_GetHeight()=0
virtual void x_OnMotion(wxMouseEvent &event)
virtual void x_OnLeftUp(wxMouseEvent &event)
void x_SelectFocusedItem(bool bDeselectEn)
virtual TSelListModel * SLC_GetModel()=0
void x_MoveSelLineByPage(bool bDown, bool bShift, bool bCtrl)
virtual void x_OnKeyDown(wxKeyEvent &event)
void x_MoveSelectionBy(int Shift, bool bShift, bool bCtrl)
void x_SelectTo(int index, bool bShift, bool bCtrl)
virtual int SLC_GetLineByWindowY(int WinY, bool b_clip=false)=0
IGlEventHandler.
interface ISelListModel
Definition: list_mvc.hpp:45
virtual void SLM_InvertSingleItem(TIndex index)=0
virtual TIndex SLM_GetFocusedItemIndex() const =0
virtual void SLM_SelectAll(bool bSelect=true)=0
virtual TIndex SLM_GetItemsCount() const =0
virtual void SLM_SelectTo(TIndex index)=0
virtual bool SLM_IsItemSelected(TIndex index) const =0
virtual void SLM_FocusItem(TIndex index)=0
virtual void SLM_SelectSingleItem(TIndex index)=0
#define false
Definition: bool.h:36
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
const struct ncbi::grid::netcache::search::fields::KEY key
#define abs(a)
Definition: ncbi_heapmgr.c:130
The NCBI C++/STL use hints.
T max(T x_, T y_)
T min(T x_, T y_)
static const int kDragThreshold
#define N
Definition: crc32.c:57
Modified on Fri Sep 20 14:57:06 2024 by modify_doxy.py rev. 669887