Fix build on systems that have a separate libintl library
[centerim5.git] / cppconsui / ComboBox.cpp
blobbd684b9cff39d0873dcea5da9debbc788d5624b9
1 // Copyright (C) 2007 Mark Pustjens <pustjens@dds.nl>
2 // Copyright (C) 2010-2015 Petr Pavlu <setup@dagobah.cz>
3 //
4 // This file is part of CenterIM.
5 //
6 // CenterIM is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // CenterIM is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
19 /// @file
20 /// ComboBox class implementation.
21 ///
22 /// @ingroup cppconsui
24 #include "ComboBox.h"
26 #include <cassert>
27 #include <cstring>
29 namespace CppConsUI {
31 ComboBox::ComboBox(int w, int h, const char *text)
32 : Button(w, h, text, FLAG_VALUE), dropdown_(nullptr), selected_entry_(0),
33 max_option_width_(0)
35 signal_activate.connect(sigc::mem_fun(this, &ComboBox::onDropDown));
38 ComboBox::ComboBox(const char *text)
39 : Button(text, FLAG_VALUE), dropdown_(nullptr), selected_entry_(0),
40 max_option_width_(0)
42 signal_activate.connect(sigc::mem_fun(this, &ComboBox::onDropDown));
45 ComboBox::~ComboBox()
47 clearOptions();
48 if (dropdown_ != nullptr)
49 dropdown_->close();
52 void ComboBox::clearOptions()
54 for (ComboBoxEntry &entry : options_)
55 delete[] entry.title;
57 options_.clear();
58 selected_entry_ = 0;
59 max_option_width_ = 0;
62 int ComboBox::addOption(const char *text, intptr_t data)
64 std::size_t size = 1;
65 if (text != nullptr)
66 size += std::strlen(text);
67 ComboBoxEntry e;
68 e.title = new char[size];
69 if (text != nullptr)
70 std::strcpy(e.title, text);
71 else
72 e.title[0] = '\0';
73 e.data = data;
75 int w = Curses::onScreenWidth(e.title);
76 if (w > max_option_width_)
77 max_option_width_ = w;
79 // Set this option as selected if it is the first one.
80 if (options_.empty()) {
81 selected_entry_ = 0;
82 setValue(text);
85 options_.push_back(e);
86 return options_.size() - 1;
89 const char *ComboBox::getSelectedTitle() const
91 if (options_.empty())
92 return nullptr;
94 return getTitle(selected_entry_);
97 intptr_t ComboBox::getSelectedData() const
99 if (options_.empty())
100 return 0;
102 return getData(selected_entry_);
105 void *ComboBox::getSelectedDataPtr() const
107 return reinterpret_cast<void *>(getSelectedData());
110 const char *ComboBox::getTitle(int entry) const
112 assert(entry >= 0);
113 assert(static_cast<std::size_t>(entry) < options_.size());
115 return options_[entry].title;
118 intptr_t ComboBox::getData(int entry) const
120 assert(entry >= 0);
121 assert(static_cast<std::size_t>(entry) < options_.size());
123 return options_[entry].data;
126 void ComboBox::setSelected(int new_entry)
128 assert(new_entry >= 0);
129 assert(static_cast<std::size_t>(new_entry) < options_.size());
131 // Selected option did not change.
132 if (new_entry == selected_entry_)
133 return;
135 selected_entry_ = new_entry;
136 ComboBoxEntry e = options_[new_entry];
137 setValue(e.title);
138 signal_selection_changed(*this, new_entry, e.title, e.data);
141 void ComboBox::setSelectedByData(intptr_t data)
143 int i = 0;
144 for (ComboBoxEntry &entry : options_) {
145 if (entry.data == data) {
146 setSelected(i);
147 break;
149 ++i;
153 void ComboBox::onDropDown(Button & /*activator*/)
155 if (options_.empty())
156 return;
158 dropdown_ = new MenuWindow(*this, max_option_width_ + 2, AUTOSIZE);
159 dropdown_->signal_close.connect(
160 sigc::mem_fun(this, &ComboBox::dropDownClose));
162 int i = 0;
163 for (ComboBoxEntry &entry : options_) {
164 Button *b = dropdown_->appendItem(
165 entry.title, sigc::bind(sigc::mem_fun(this, &ComboBox::dropDownOk), i));
166 if (i == selected_entry_)
167 b->grabFocus();
168 ++i;
171 dropdown_->show();
174 void ComboBox::dropDownOk(Button & /*activator*/, int new_entry)
176 dropdown_->close();
178 setSelected(new_entry);
181 void ComboBox::dropDownClose(Window & /*window*/)
183 dropdown_ = nullptr;
186 } // namespace CppConsUI
188 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: