CMS 3D CMS Logo

FWGUIValidatingTextEntry.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Core
4 // Class : FWGUIValidatingTextEntry
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Fri Aug 22 18:13:39 EDT 2008
11 //
12 
13 // system include files
14 #include <iostream>
15 #include "TGComboBox.h"
16 #include "KeySymbols.h"
17 #include "TTimer.h"
18 #include "TGWindow.h"
19 #include "TVirtualX.h"
20 
21 // user include files
24 
25 //
26 // constants, enums and typedefs
27 //
28 
29 //
30 // static data member definitions
31 //
32 
33 //
34 // constructors and destructor
35 //
36 FWGUIValidatingTextEntry::FWGUIValidatingTextEntry(const TGWindow* parent, const char* text, Int_t id)
37  : TGTextEntry(parent, text, id), m_popup(nullptr), m_list(nullptr), m_validator(nullptr), m_listHeight(100) {
38  m_popup = new TGComboBoxPopup(fClient->GetDefaultRoot(), 100, 100, kVerticalFrame);
39  m_list = new TGListBox(m_popup, 1 /*widget id*/, kChildFrame);
40  m_list->Resize(100, m_listHeight);
41  m_list->Associate(this);
42  m_list->GetScrollBar()->GrabPointer(kFALSE);
43  m_popup->AddFrame(m_list, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
44  m_popup->MapSubwindows();
45  m_popup->Resize(m_popup->GetDefaultSize());
46  m_list->GetContainer()->AddInput(kButtonPressMask | kButtonReleaseMask | kPointerMotionMask);
47  m_list->SetEditDisabled(kEditDisable);
48  m_list->GetContainer()->Connect("KeyPressed(TGFrame*,UInt_t,UInt_t)",
49  "FWGUIValidatingTextEntry",
50  this,
51  "keyPressedInPopup(TGFrame*,UInt_t,UInt_t)");
52  m_list->GetContainer()->SetEditDisabled(kEditDisable);
53  Connect("TabPressed()", "FWGUIValidatingTextEntry", this, "showOptions()");
54 }
55 
56 // FWGUIValidatingTextEntry::FWGUIValidatingTextEntry(const FWGUIValidatingTextEntry& rhs)
57 // {
58 // // do actual copying here;
59 // }
60 
62 
63 //
64 // assignment operators
65 //
66 // const FWGUIValidatingTextEntry& FWGUIValidatingTextEntry::operator=(const FWGUIValidatingTextEntry& rhs)
67 // {
68 // //An exception safe implementation is
69 // FWGUIValidatingTextEntry temp(rhs);
70 // swap(rhs);
71 //
72 // return *this;
73 // }
74 
75 //
76 // member functions
77 //
79 
80 Bool_t FWGUIValidatingTextEntry::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) {
81  //STOLEN FROM TGComboBox.cxx
82  switch (GET_MSG(msg)) {
83  case kC_COMMAND:
84  switch (GET_SUBMSG(msg)) {
85  case kCM_LISTBOX:
86  RequestFocus();
87  insertTextOption(m_options[m_list->GetSelected()].second);
88  hideOptions();
89  break;
90  }
91  break;
92 
93  default:
94  break;
95  }
96  return kTRUE;
97 }
98 
99 void FWGUIValidatingTextEntry::keyPressedInPopup(TGFrame* f, UInt_t keysym, UInt_t mask) {
100  switch (keysym) {
101  case kKey_Tab:
102  case kKey_Escape:
103  RequestFocus();
104  hideOptions();
105  break;
106  case kKey_Return:
107  RequestFocus();
108  //NOTE: If chosen from the keyboard, m_list->GetSelected() does not work, however
109  // m_list->GetSelectedEntries does work
110 
111  //AMT NOTE: TGListEntry does not select entry on key return event, it has to be selected here.
112  // Code stolen from TGComboBox::KeyPressed
113 
114  const TGLBEntry* entry = dynamic_cast<TGLBEntry*>(f);
115  if (entry) {
116  insertTextOption(m_options[entry->EntryId()].second);
117  m_list->Selected(entry->EntryId());
118  }
119  hideOptions();
120  break;
121  }
122 }
123 
124 namespace {
125  class ChangeFocusTimer : public TTimer {
126  public:
127  ChangeFocusTimer(TGWindow* iWindow) : TTimer(100), m_window(iWindow) {}
128  Bool_t Notify() override {
129  TurnOff();
130  m_window->RequestFocus();
131  return kTRUE;
132  }
133 
134  private:
135  TGWindow* m_window;
136  };
137 } // namespace
138 
140  if (nullptr != m_validator) {
141  const char* text = GetText();
142  std::string subText(text, text + GetCursorPosition());
143  //std::cout <<subText<<std::endl;
144 
145  typedef std::vector<std::pair<std::shared_ptr<std::string>, std::string> > Options;
146  m_validator->fillOptions(text, text + GetCursorPosition(), m_options);
147  if (m_options.empty()) {
148  return;
149  }
150  if (m_options.size() == 1) {
151  insertTextOption(m_options.front().second);
152  return;
153  }
154  m_list->RemoveAll();
155  int index = 0;
156  for (Options::iterator it = m_options.begin(), itEnd = m_options.end(); it != itEnd; ++it, ++index) {
157  m_list->AddEntry(it->first->c_str(), index);
158  }
159  {
160  unsigned int h = m_list->GetNumberOfEntries() * m_list->GetItemVsize();
161  if (h && (h < m_listHeight)) {
162  m_list->Resize(m_list->GetWidth(), h);
163  } else {
164  m_list->Resize(m_list->GetWidth(), m_listHeight);
165  }
166  }
167  m_list->Select(0, kTRUE);
168 
169  int ax, ay;
170  Window_t wdummy;
171  gVirtualX->TranslateCoordinates(GetId(), m_popup->GetParent()->GetId(), 0, GetHeight(), ax, ay, wdummy);
172 
173  //Wait to change focus for when the popup has already openned
174  std::unique_ptr<TTimer> timer(new ChangeFocusTimer(m_list->GetContainer()));
175  timer->TurnOn();
176  //NOTE: this call has its own internal GUI event loop and will not return
177  // until the popup has been shut down
178  m_popup->PlacePopup(ax, ay, GetWidth() - 2, m_popup->GetDefaultHeight());
179  }
180 }
181 
183  m_popup->EndPopup();
184  fClient->NeedRedraw(this);
185 }
186 
188  long pos = GetCursorPosition();
189  InsertText(iOption.c_str(), pos);
190  SetCursorPosition(pos + iOption.size());
191 }
192 
193 //
194 // const member functions
195 //
196 
197 //
198 // static member functions
199 //
virtual void fillOptions(const char *iBegin, const char *iEnd, std::vector< std::pair< std::shared_ptr< std::string >, std::string > > &oOptions) const =0
std::vector< std::pair< std::shared_ptr< std::string >, std::string > > m_options
FWGUIValidatingTextEntry(const TGWindow *parent=nullptr, const char *text=nullptr, Int_t id=-1)
void insertTextOption(const std::string &)
void setValidator(FWValidatorBase *)
std::vector< std::shared_ptr< fireworks::OptionNode > > Options
double f[11][100]
tuple msg
Definition: mps_check.py:286
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) override
void keyPressedInPopup(TGFrame *, UInt_t keysym, UInt_t mask)