Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:15

0001 // -*- C++ -*-
0002 //
0003 // Package:     Core
0004 // Class  :     FWGUIValidatingTextEntry
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Fri Aug 22 18:13:39 EDT 2008
0011 //
0012 
0013 // system include files
0014 #include <iostream>
0015 #include "TGComboBox.h"
0016 #include "KeySymbols.h"
0017 #include "TTimer.h"
0018 #include "TGWindow.h"
0019 #include "TVirtualX.h"
0020 
0021 // user include files
0022 #include "Fireworks/Core/src/FWGUIValidatingTextEntry.h"
0023 #include "Fireworks/Core/src/FWExpressionValidator.h"
0024 
0025 //
0026 // constants, enums and typedefs
0027 //
0028 
0029 //
0030 // static data member definitions
0031 //
0032 
0033 //
0034 // constructors and destructor
0035 //
0036 FWGUIValidatingTextEntry::FWGUIValidatingTextEntry(const TGWindow* parent, const char* text, Int_t id)
0037     : TGTextEntry(parent, text, id), m_popup(nullptr), m_list(nullptr), m_validator(nullptr), m_listHeight(100) {
0038   m_popup = new TGComboBoxPopup(fClient->GetDefaultRoot(), 100, 100, kVerticalFrame);
0039   m_list = new TGListBox(m_popup, 1 /*widget id*/, kChildFrame);
0040   m_list->Resize(100, m_listHeight);
0041   m_list->Associate(this);
0042   m_list->GetScrollBar()->GrabPointer(kFALSE);
0043   m_popup->AddFrame(m_list, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
0044   m_popup->MapSubwindows();
0045   m_popup->Resize(m_popup->GetDefaultSize());
0046   m_list->GetContainer()->AddInput(kButtonPressMask | kButtonReleaseMask | kPointerMotionMask);
0047   m_list->SetEditDisabled(kEditDisable);
0048   m_list->GetContainer()->Connect("KeyPressed(TGFrame*,UInt_t,UInt_t)",
0049                                   "FWGUIValidatingTextEntry",
0050                                   this,
0051                                   "keyPressedInPopup(TGFrame*,UInt_t,UInt_t)");
0052   m_list->GetContainer()->SetEditDisabled(kEditDisable);
0053   Connect("TabPressed()", "FWGUIValidatingTextEntry", this, "showOptions()");
0054 }
0055 
0056 // FWGUIValidatingTextEntry::FWGUIValidatingTextEntry(const FWGUIValidatingTextEntry& rhs)
0057 // {
0058 //    // do actual copying here;
0059 // }
0060 
0061 FWGUIValidatingTextEntry::~FWGUIValidatingTextEntry() {}
0062 
0063 //
0064 // assignment operators
0065 //
0066 // const FWGUIValidatingTextEntry& FWGUIValidatingTextEntry::operator=(const FWGUIValidatingTextEntry& rhs)
0067 // {
0068 //   //An exception safe implementation is
0069 //   FWGUIValidatingTextEntry temp(rhs);
0070 //   swap(rhs);
0071 //
0072 //   return *this;
0073 // }
0074 
0075 //
0076 // member functions
0077 //
0078 void FWGUIValidatingTextEntry::setValidator(FWValidatorBase* iValidator) { m_validator = iValidator; }
0079 
0080 Bool_t FWGUIValidatingTextEntry::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) {
0081   //STOLEN FROM TGComboBox.cxx
0082   switch (GET_MSG(msg)) {
0083     case kC_COMMAND:
0084       switch (GET_SUBMSG(msg)) {
0085         case kCM_LISTBOX:
0086           RequestFocus();
0087           insertTextOption(m_options[m_list->GetSelected()].second);
0088           hideOptions();
0089           break;
0090       }
0091       break;
0092 
0093     default:
0094       break;
0095   }
0096   return kTRUE;
0097 }
0098 
0099 void FWGUIValidatingTextEntry::keyPressedInPopup(TGFrame* f, UInt_t keysym, UInt_t mask) {
0100   switch (keysym) {
0101     case kKey_Tab:
0102     case kKey_Escape:
0103       RequestFocus();
0104       hideOptions();
0105       break;
0106     case kKey_Return:
0107       RequestFocus();
0108       //NOTE: If chosen from the keyboard, m_list->GetSelected() does not work, however
0109       // m_list->GetSelectedEntries does work
0110 
0111       //AMT NOTE: TGListEntry does not select entry on key return event, it has to be selected here.
0112       //          Code stolen from TGComboBox::KeyPressed
0113 
0114       const TGLBEntry* entry = dynamic_cast<TGLBEntry*>(f);
0115       if (entry) {
0116         insertTextOption(m_options[entry->EntryId()].second);
0117         m_list->Selected(entry->EntryId());
0118       }
0119       hideOptions();
0120       break;
0121   }
0122 }
0123 
0124 namespace {
0125   class ChangeFocusTimer : public TTimer {
0126   public:
0127     ChangeFocusTimer(TGWindow* iWindow) : TTimer(100), m_window(iWindow) {}
0128     Bool_t Notify() override {
0129       TurnOff();
0130       m_window->RequestFocus();
0131       return kTRUE;
0132     }
0133 
0134   private:
0135     TGWindow* m_window;
0136   };
0137 }  // namespace
0138 
0139 void FWGUIValidatingTextEntry::showOptions() {
0140   if (nullptr != m_validator) {
0141     const char* text = GetText();
0142     std::string subText(text, text + GetCursorPosition());
0143     //std::cout <<subText<<std::endl;
0144 
0145     typedef std::vector<std::pair<std::shared_ptr<std::string>, std::string> > Options;
0146     m_validator->fillOptions(text, text + GetCursorPosition(), m_options);
0147     if (m_options.empty()) {
0148       return;
0149     }
0150     if (m_options.size() == 1) {
0151       insertTextOption(m_options.front().second);
0152       return;
0153     }
0154     m_list->RemoveAll();
0155     int index = 0;
0156     for (Options::iterator it = m_options.begin(), itEnd = m_options.end(); it != itEnd; ++it, ++index) {
0157       m_list->AddEntry(it->first->c_str(), index);
0158     }
0159     {
0160       unsigned int h = m_list->GetNumberOfEntries() * m_list->GetItemVsize();
0161       if (h && (h < m_listHeight)) {
0162         m_list->Resize(m_list->GetWidth(), h);
0163       } else {
0164         m_list->Resize(m_list->GetWidth(), m_listHeight);
0165       }
0166     }
0167     m_list->Select(0, kTRUE);
0168 
0169     int ax, ay;
0170     Window_t wdummy;
0171     gVirtualX->TranslateCoordinates(GetId(), m_popup->GetParent()->GetId(), 0, GetHeight(), ax, ay, wdummy);
0172 
0173     //Wait to change focus for when the popup has already openned
0174     std::unique_ptr<TTimer> timer(new ChangeFocusTimer(m_list->GetContainer()));
0175     timer->TurnOn();
0176     //NOTE: this call has its own internal GUI event loop and will not return
0177     // until the popup has been shut down
0178     m_popup->PlacePopup(ax, ay, GetWidth() - 2, m_popup->GetDefaultHeight());
0179   }
0180 }
0181 
0182 void FWGUIValidatingTextEntry::hideOptions() {
0183   m_popup->EndPopup();
0184   fClient->NeedRedraw(this);
0185 }
0186 
0187 void FWGUIValidatingTextEntry::insertTextOption(const std::string& iOption) {
0188   long pos = GetCursorPosition();
0189   InsertText(iOption.c_str(), pos);
0190   SetCursorPosition(pos + iOption.size());
0191 }
0192 
0193 //
0194 // const member functions
0195 //
0196 
0197 //
0198 // static member functions
0199 //