1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2
3 #include "smcomboboxoperator.hh"
4
5 #include <assert.h>
6
7 using namespace SpectMorph;
8
9 using std::string;
10 using std::vector;
11
12 #define OPERATOR_TEXT_NONE "<none>"
13
ComboBoxOperator(Widget * parent,MorphPlan * morph_plan,const OperatorFilter & operator_filter)14 ComboBoxOperator::ComboBoxOperator (Widget *parent, MorphPlan *morph_plan, const OperatorFilter& operator_filter) :
15 Widget (parent),
16 morph_plan (morph_plan),
17 op_filter (operator_filter),
18 op (NULL)
19 {
20 combobox = new ComboBox (this);
21
22 on_update_combobox_geometry();
23 connect (signal_width_changed, this, &ComboBoxOperator::on_update_combobox_geometry);
24 connect (signal_height_changed, this, &ComboBoxOperator::on_update_combobox_geometry);
25
26 none_ok = true;
27
28 on_operators_changed();
29
30 connect (combobox->signal_item_changed, this, &ComboBoxOperator::on_combobox_changed);
31 connect (morph_plan->signal_plan_changed, this, &ComboBoxOperator::on_operators_changed);
32 }
33
34 void
on_update_combobox_geometry()35 ComboBoxOperator::on_update_combobox_geometry()
36 {
37 combobox->set_x (0);
38 combobox->set_y (0);
39 combobox->set_width (width());
40 combobox->set_height (height());
41 }
42
43 void
on_operators_changed()44 ComboBoxOperator::on_operators_changed()
45 {
46 combobox->clear();
47
48 if (none_ok)
49 combobox->add_item (OPERATOR_TEXT_NONE);
50
51 for (auto item : str_items)
52 {
53 if (item.headline)
54 combobox->add_item (ComboBoxItem (item.text, true));
55 else
56 combobox->add_item (item.text);
57 }
58
59 bool add_op_headline = (op_headline != "");
60 for (MorphOperator *morph_op : morph_plan->operators())
61 {
62 if (op_filter (morph_op))
63 {
64 if (add_op_headline)
65 {
66 // if we find any matches, add op_headline once
67 combobox->add_item (ComboBoxItem (op_headline, true));
68 add_op_headline = false;
69 }
70 combobox->add_item (morph_op->name());
71 }
72 }
73
74 // update selected item
75 string active_name = OPERATOR_TEXT_NONE;
76 if (op)
77 active_name = op->name();
78 if (str_choice != "")
79 active_name = str_choice;
80
81 combobox->set_text (active_name);
82 }
83
84 void
on_combobox_changed()85 ComboBoxOperator::on_combobox_changed()
86 {
87 string active_text = combobox->text();
88
89 op = NULL;
90 str_choice = "";
91
92 for (MorphOperator *morph_op : morph_plan->operators())
93 {
94 if (morph_op->name() == active_text)
95 {
96 op = morph_op;
97 str_choice = "";
98 }
99 }
100 for (auto item : str_items)
101 {
102 if (!item.headline && item.text == active_text)
103 {
104 op = NULL;
105 str_choice = item.text;
106 }
107 }
108 signal_item_changed();
109 }
110
111 void
set_active(MorphOperator * new_op)112 ComboBoxOperator::set_active (MorphOperator *new_op)
113 {
114 op = new_op;
115 str_choice = "";
116
117 on_operators_changed();
118 }
119
120 MorphOperator *
active()121 ComboBoxOperator::active()
122 {
123 return op;
124 }
125
126 void
set_op_headline(const std::string & headline)127 ComboBoxOperator::set_op_headline (const std::string& headline)
128 {
129 op_headline = headline;
130 }
131
132 void
add_str_choice(const string & str)133 ComboBoxOperator::add_str_choice (const string& str)
134 {
135 str_items.push_back (StrItem {false, str});
136
137 on_operators_changed();
138 }
139
140 void
add_str_headline(const std::string & str)141 ComboBoxOperator::add_str_headline (const std::string& str)
142 {
143 str_items.push_back (StrItem {true, str});
144
145 on_operators_changed();
146 }
147
148 void
clear_str_choices()149 ComboBoxOperator::clear_str_choices()
150 {
151 str_items.clear();
152 str_choice = "";
153
154 on_operators_changed();
155 }
156
157 string
active_str_choice()158 ComboBoxOperator::active_str_choice()
159 {
160 return str_choice;
161 }
162
163 void
set_active_str_choice(const string & new_str)164 ComboBoxOperator::set_active_str_choice (const string& new_str)
165 {
166 for (auto item : str_items)
167 {
168 if (new_str == item.text)
169 {
170 op = NULL;
171 str_choice = item.text;
172
173 on_operators_changed();
174
175 return;
176 }
177 }
178 fprintf (stderr, "ComboBoxOperator::set_active_str_choice (%s) failed\n", new_str.c_str());
179
180 str_choice = "";
181 on_operators_changed();
182 }
183
184 void
set_none_ok(bool new_none_ok)185 ComboBoxOperator::set_none_ok (bool new_none_ok)
186 {
187 none_ok = new_none_ok;
188
189 on_operators_changed();
190 }
191