diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt index 5efc2fb1a..548f5a5fe 100644 --- a/Source/CursesDialog/CMakeLists.txt +++ b/Source/CursesDialog/CMakeLists.txt @@ -11,6 +11,7 @@ #============================================================================= set( CURSES_SRCS + CursesDialog/cmCursesOptionsWidget CursesDialog/cmCursesBoolWidget CursesDialog/cmCursesCacheEntryComposite CursesDialog/cmCursesDummyWidget diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index c58d037f0..249137f52 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -10,6 +10,7 @@ See the License for more information. ============================================================================*/ #include "cmCursesCacheEntryComposite.h" +#include "cmCursesOptionsWidget.h" #include "cmCursesStringWidget.h" #include "cmCursesLabelWidget.h" #include "cmCursesBoolWidget.h" @@ -69,9 +70,27 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( it.GetValue()); break; case cmCacheManager::STRING: - this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1); - static_cast(this->Entry)->SetString( - it.GetValue()); + if(it.PropertyExists("STRINGS")) + { + cmCursesOptionsWidget* ow = + new cmCursesOptionsWidget(this->EntryWidth, 1, 1, 1); + this->Entry = ow; + std::vector options; + cmSystemTools::ExpandListArgument( + std::string(it.GetProperty("STRINGS")), options); + for(std::vector::iterator + si = options.begin(); si != options.end(); ++si) + { + ow->AddOption(*si); + } + ow->SetOption(it.GetValue()); + } + else + { + this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1); + static_cast(this->Entry)->SetString( + it.GetValue()); + } break; case cmCacheManager::UNINITIALIZED: cmSystemTools::Error("Found an undefined variable: ", it.GetName()); diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx new file mode 100644 index 000000000..652b2df7a --- /dev/null +++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx @@ -0,0 +1,106 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmCursesOptionsWidget.h" +#include "cmCursesMainForm.h" + +inline int ctrl(int z) +{ + return (z&037); +} + +cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height, + int left, int top) : + cmCursesWidget(width, height, left, top) +{ + this->Type = cmCacheManager::BOOL; // this is a bit of a hack + // there is no option type, and string type causes ccmake to cast + // the widget into a string widget at some point. BOOL is safe for + // now. + set_field_fore(this->Field, A_NORMAL); + set_field_back(this->Field, A_STANDOUT); + field_opts_off(this->Field, O_STATIC); +} + +bool cmCursesOptionsWidget::HandleInput(int& key, cmCursesMainForm*, WINDOW* w) +{ + + // 10 == enter + if (key == 10 || key == KEY_ENTER) + { + this->NextOption(); + touchwin(w); + wrefresh(w); + return true; + } + else if (key == KEY_LEFT || key == ctrl('b')) + { + touchwin(w); + wrefresh(w); + this->PreviousOption(); + return true; + } + else if (key == KEY_RIGHT || key == ctrl('f')) + { + this->NextOption(); + touchwin(w); + wrefresh(w); + return true; + } + else + { + return false; + } + return false; +} + +void cmCursesOptionsWidget::AddOption(std::string const & option ) +{ + this->Options.push_back(option); +} + +void cmCursesOptionsWidget::NextOption() +{ + this->CurrentOption++; + if(this->CurrentOption > this->Options.size()-1) + { + this->CurrentOption = 0; + } + this->SetValue(this->Options[this->CurrentOption].c_str()); +} +void cmCursesOptionsWidget::PreviousOption() +{ + if(this->CurrentOption == 0) + { + this->CurrentOption = this->Options.size()-1; + } + else + { + this->CurrentOption--; + } + this->SetValue(this->Options[this->CurrentOption].c_str()); +} + +void cmCursesOptionsWidget::SetOption(const char* value) +{ + this->CurrentOption = 0; // default to 0 index + this->SetValue(value); + int index = 0; + for(std::vector::iterator i = this->Options.begin(); + i != this->Options.end(); ++i) + { + if(*i == value) + { + this->CurrentOption = index; + } + index++; + } +} diff --git a/Source/CursesDialog/cmCursesOptionsWidget.h b/Source/CursesDialog/cmCursesOptionsWidget.h new file mode 100644 index 000000000..b52ac9de9 --- /dev/null +++ b/Source/CursesDialog/cmCursesOptionsWidget.h @@ -0,0 +1,39 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef __cmCursesOptionsWidget_h +#define __cmCursesOptionsWidget_h + +#include "cmCursesWidget.h" +class cmCursesMainForm; + +class cmCursesOptionsWidget : public cmCursesWidget +{ +public: + cmCursesOptionsWidget(int width, int height, int left, int top); + + // Description: + // Handle user input. Called by the container of this widget + // when this widget has focus. Returns true if the input was + // handled. + virtual bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w); + void SetOption(const char*); + void AddOption(std::string const &); + void NextOption(); + void PreviousOption(); +protected: + cmCursesOptionsWidget(const cmCursesOptionsWidget& from); + void operator=(const cmCursesOptionsWidget&); + std::vector Options; + std::vector::size_type CurrentOption; +}; + +#endif // __cmCursesOptionsWidget_h