DebugDrawerViewerWidgetController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * \package RobotAPI::gui-plugins::DebugDrawerViewerWidgetController
17 * \author Mirko Waechter ( mirko dot waechter at kit dot edu )
18 * \date 2016
19 * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
23
24#include <RobotAPI/gui-plugins/DebugDrawerViewer/ui_DebugDrawerViewerWidget.h>
25
26#include <string>
27
28#include <QTimer>
29
30#include <SimoxUtility/algorithm/string/string_tools.h>
31
33
34namespace armarx
35{
37
39 {
40 rootVisu = nullptr;
41 widget = std::make_unique<Ui::DebugDrawerViewerWidget>();
42 widget->setupUi(getWidget());
43
44 QTimer* timer = new QTimer(this);
45 connect(timer, SIGNAL(timeout()), this, SLOT(updateComboClearLayer()));
46 timer->start(100);
47 }
48
49 void
51 {
52 (void)settings; // unused
53 }
54
55 void
57 {
58 (void)settings; // unused
59 }
60
61 void
63 {
64 rootVisu = new SoSeparator;
65 rootVisu->ref();
66
67
69 connect(widget->btnClearAll,
70 SIGNAL(clicked()),
71 this,
72 SLOT(on_btnClearAll_clicked()),
73 Qt::UniqueConnection);
74 connect(widget->btnClearLayer,
75 SIGNAL(clicked()),
76 this,
77 SLOT(on_btnClearLayer_clicked()),
78 Qt::UniqueConnection);
79 }
80
81 void
83 {
84 // create the debugdrawer component
85 std::string debugDrawerComponentName = "GUIDebugDrawer_" + getName();
86 ARMARX_INFO << "Creating component " << debugDrawerComponentName;
87 debugDrawer =
89
90 if (mutex3D)
91 {
92 //ARMARX_IMPORTANT << "mutex3d:" << mutex3D.get();
93 debugDrawer->setMutex(mutex3D);
94 }
95 else
96 {
97 ARMARX_ERROR << " No 3d mutex available...";
98 }
99
101 m->addObject(debugDrawer, false);
102
103 {
104 std::unique_lock lock(*mutex3D);
105 rootVisu->addChild(debugDrawer->getVisualization());
106 }
108 }
109
110 void
112 {
113 if (rootVisu)
114 {
115 rootVisu->removeAllChildren();
116 rootVisu->unref();
117 rootVisu = nullptr;
118 }
119 }
120
121 SoNode*
123 {
124 return rootVisu;
125 }
126
127 void
128 armarx::DebugDrawerViewerWidgetController::on_btnClearAll_clicked()
129 {
130 if (debugDrawer)
131 {
132 ARMARX_INFO << "Clearing all visualization layers";
133 debugDrawer->clearAll();
134 }
135 }
136
137 void
138 DebugDrawerViewerWidgetController::on_btnClearLayer_clicked()
139 {
140 if (debugDrawer)
141 {
142 int index = widget->comboClearLayer->currentIndex();
143 std::string layerName =
144 widget->comboClearLayer->itemData(index).toString().toStdString();
145
146 if (!layerName.empty())
147 {
148 ARMARX_INFO << "Clearing layer: '" << layerName << "'";
149 debugDrawer->clearLayer(layerName);
150 }
151 }
152 }
153
154 void
155 DebugDrawerViewerWidgetController::updateComboClearLayer()
156 {
157 QComboBox* combo = widget->comboClearLayer;
158
159 auto setItalic = [combo](bool italic)
160 {
161 QFont font = combo->font();
162 font.setItalic(italic);
163 combo->setFont(font);
164 };
165
166 auto disableButton = [combo, this, &setItalic](const std::string& hint)
167 {
168 QString itemText(hint.c_str());
169 QString itemData("");
170 setItalic(true);
171
172 if (combo->count() != 1)
173 {
174 combo->clear();
175 combo->insertItem(0, itemText, itemData);
176 }
177 else
178 {
179 combo->setItemText(0, itemText);
180 combo->setItemData(0, itemData);
181 }
182
183 this->widget->btnClearLayer->setEnabled(false);
184 };
185
186 if (!debugDrawer)
187 {
188 disableButton("not connected");
189 return;
190 }
191
192 // fetch layer information
193 LayerInformationSequence layers = debugDrawer->layerInformation();
194
195 if (layers.empty())
196 {
197 disableButton("no layers");
198 return;
199 }
200 else
201 {
202 setItalic(false);
203 this->widget->btnClearLayer->setEnabled(true);
204 }
205
206 // sort the layers by name
207 std::sort(layers.begin(),
208 layers.end(),
209 [](const LayerInformation& lhs, const LayerInformation& rhs)
210 {
211 // compare case insensitively
212 for (std::size_t i = 0; i < lhs.layerName.size() && i < lhs.layerName.size();
213 ++i)
214 {
215 auto lhsLow = std::tolower(lhs.layerName[i]);
216 auto rhsLow = std::tolower(rhs.layerName[i]);
217 if (lhsLow < rhsLow)
218 {
219 return true;
220 }
221 else if (lhsLow > rhsLow)
222 {
223 return false;
224 }
225 }
226 // if one is a prefix of the other, the shorter one "smaller"
227 return lhs.layerName.size() < rhs.layerName.size();
228 });
229
230
231 const int numLayers = static_cast<int>(layers.size());
232
233 for (int i = 0; i < numLayers; ++i)
234 {
235 const LayerInformation& layer = layers[static_cast<std::size_t>(i)];
236
237 QString layerName(layer.layerName.c_str());
238
239 if (i < combo->count()) // in range
240 {
241 QString itemData = combo->itemData(i).toString();
242
243 // remove deleted layers
244 while (itemData.size() != 0 && itemData < layerName)
245 {
246 // item layer is smaller than next layer
247 // => item layer was deleted
248 combo->removeItem(i);
249 itemData = i < combo->count() ? combo->itemData(i).toString() : "";
250 }
251
252 // update existing layer
253 if (itemData == layerName)
254 {
255 combo->setItemText(i, makeLayerItemText(layer));
256 }
257 else // (itemData > layerName)
258 {
259 // item layer is further down than current layer
260 // => insert current layer here
261 combo->insertItem(i, makeLayerItemText(layer), layerName);
262 }
263 }
264 else // out of range
265 {
266 combo->insertItem(i, makeLayerItemText(layer), layerName);
267 }
268
269 // check invariant
270 ARMARX_CHECK_EQUAL(combo->itemData(i).toString(), layerName);
271 }
272
273 // remove excessive items
274 while (combo->count() > numLayers)
275 {
276 combo->removeItem(combo->count() - 1);
277 }
278 }
279
280 QString
281 DebugDrawerViewerWidgetController::makeLayerItemText(const LayerInformation& layer)
282 {
283 std::vector<std::string> annotations;
284 if (layer.elementCount == 0)
285 {
286 annotations.push_back("empty");
287 }
288 else
289 {
290 annotations.push_back(std::to_string(layer.elementCount));
291 }
292 if (!layer.visible)
293 {
294 annotations.push_back("hidden");
295 }
296
297 if (annotations.empty())
298 {
299 return {layer.layerName.c_str()};
300 }
301 else
302 {
303 std::stringstream itemText;
304 itemText << layer.layerName << " (" << simox::alg::join(annotations, ", ") << ")";
305 return {itemText.str().c_str()};
306 }
307 }
308} // namespace armarx
uint8_t index
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
std::shared_ptr< std::recursive_mutex > mutex3D
void enableMainWidgetAsync(bool enable)
This function enables/disables the main widget asynchronously (if called from a non qt thread).
static TPtr create(Ice::PropertiesPtr properties=Ice::createProperties(), const std::string &configName="", const std::string &configDomain="ArmarX")
Factory method for a component.
Definition Component.h:116
SoNode * getScene() override
Reimplementing this function and returning a SoNode* will show this SoNode in the 3DViewerWidget,...
virtual ~DebugDrawerViewerWidgetController() override
Controller destructor.
std::string getName() const
Retrieve name of object.
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:179
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:194
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< ArmarXManager > ArmarXManagerPtr