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 <string>
25 
26 #include <QTimer>
27 
28 #include <SimoxUtility/algorithm/string/string_tools.h>
29 
31 
32 namespace armarx
33 {
35  {
36  rootVisu = nullptr;
37  widget.setupUi(getWidget());
38 
39  QTimer* timer = new QTimer(this);
40  connect(timer, SIGNAL(timeout()), this, SLOT(updateComboClearLayer()));
41  timer->start(100);
42  }
43 
44  void
46  {
47  (void)settings; // unused
48  }
49 
50  void
52  {
53  (void)settings; // unused
54  }
55 
56  void
58  {
59  rootVisu = new SoSeparator;
60  rootVisu->ref();
61 
62 
63  enableMainWidgetAsync(false);
64  connect(widget.btnClearAll,
65  SIGNAL(clicked()),
66  this,
67  SLOT(on_btnClearAll_clicked()),
68  Qt::UniqueConnection);
69  connect(widget.btnClearLayer,
70  SIGNAL(clicked()),
71  this,
72  SLOT(on_btnClearLayer_clicked()),
73  Qt::UniqueConnection);
74  }
75 
76  void
78  {
79  // create the debugdrawer component
80  std::string debugDrawerComponentName = "GUIDebugDrawer_" + getName();
81  ARMARX_INFO << "Creating component " << debugDrawerComponentName;
82  debugDrawer =
83  Component::create<DebugDrawerComponent>(getIceProperties(), debugDrawerComponentName);
84 
85  if (mutex3D)
86  {
87  //ARMARX_IMPORTANT << "mutex3d:" << mutex3D.get();
88  debugDrawer->setMutex(mutex3D);
89  }
90  else
91  {
92  ARMARX_ERROR << " No 3d mutex available...";
93  }
94 
96  m->addObject(debugDrawer, false);
97 
98  {
99  std::unique_lock lock(*mutex3D);
100  rootVisu->addChild(debugDrawer->getVisualization());
101  }
102  enableMainWidgetAsync(true);
103  }
104 
105  void
107  {
108  if (rootVisu)
109  {
110  rootVisu->removeAllChildren();
111  rootVisu->unref();
112  rootVisu = nullptr;
113  }
114  }
115 
116  SoNode*
118  {
119  return rootVisu;
120  }
121 
122  void
123  armarx::DebugDrawerViewerWidgetController::on_btnClearAll_clicked()
124  {
125  if (debugDrawer)
126  {
127  ARMARX_INFO << "Clearing all visualization layers";
128  debugDrawer->clearAll();
129  }
130  }
131 
132  void
133  DebugDrawerViewerWidgetController::on_btnClearLayer_clicked()
134  {
135  if (debugDrawer)
136  {
137  int index = widget.comboClearLayer->currentIndex();
138  std::string layerName =
139  widget.comboClearLayer->itemData(index).toString().toStdString();
140 
141  if (!layerName.empty())
142  {
143  ARMARX_INFO << "Clearing layer: '" << layerName << "'";
144  debugDrawer->clearLayer(layerName);
145  }
146  }
147  }
148 
149  void
150  DebugDrawerViewerWidgetController::updateComboClearLayer()
151  {
152  QComboBox* combo = widget.comboClearLayer;
153 
154  auto setItalic = [combo](bool italic)
155  {
156  QFont font = combo->font();
157  font.setItalic(italic);
158  combo->setFont(font);
159  };
160 
161  auto disableButton = [combo, this, &setItalic](const std::string& hint)
162  {
163  QString itemText(hint.c_str());
164  QString itemData("");
165  setItalic(true);
166 
167  if (combo->count() != 1)
168  {
169  combo->clear();
170  combo->insertItem(0, itemText, itemData);
171  }
172  else
173  {
174  combo->setItemText(0, itemText);
175  combo->setItemData(0, itemData);
176  }
177 
178  this->widget.btnClearLayer->setEnabled(false);
179  };
180 
181  if (!debugDrawer)
182  {
183  disableButton("not connected");
184  return;
185  }
186 
187  // fetch layer information
188  LayerInformationSequence layers = debugDrawer->layerInformation();
189 
190  if (layers.empty())
191  {
192  disableButton("no layers");
193  return;
194  }
195  else
196  {
197  setItalic(false);
198  this->widget.btnClearLayer->setEnabled(true);
199  }
200 
201  // sort the layers by name
202  std::sort(layers.begin(),
203  layers.end(),
204  [](const LayerInformation& lhs, const LayerInformation& rhs)
205  {
206  // compare case insensitively
207  for (std::size_t i = 0; i < lhs.layerName.size() && i < lhs.layerName.size();
208  ++i)
209  {
210  auto lhsLow = std::tolower(lhs.layerName[i]);
211  auto rhsLow = std::tolower(rhs.layerName[i]);
212  if (lhsLow < rhsLow)
213  {
214  return true;
215  }
216  else if (lhsLow > rhsLow)
217  {
218  return false;
219  }
220  }
221  // if one is a prefix of the other, the shorter one "smaller"
222  return lhs.layerName.size() < rhs.layerName.size();
223  });
224 
225 
226  const int numLayers = static_cast<int>(layers.size());
227 
228  for (int i = 0; i < numLayers; ++i)
229  {
230  const LayerInformation& layer = layers[static_cast<std::size_t>(i)];
231 
232  QString layerName(layer.layerName.c_str());
233 
234  if (i < combo->count()) // in range
235  {
236  QString itemData = combo->itemData(i).toString();
237 
238  // remove deleted layers
239  while (itemData.size() != 0 && itemData < layerName)
240  {
241  // item layer is smaller than next layer
242  // => item layer was deleted
243  combo->removeItem(i);
244  itemData = i < combo->count() ? combo->itemData(i).toString() : "";
245  }
246 
247  // update existing layer
248  if (itemData == layerName)
249  {
250  combo->setItemText(i, makeLayerItemText(layer));
251  }
252  else // (itemData > layerName)
253  {
254  // item layer is further down than current layer
255  // => insert current layer here
256  combo->insertItem(i, makeLayerItemText(layer), layerName);
257  }
258  }
259  else // out of range
260  {
261  combo->insertItem(i, makeLayerItemText(layer), layerName);
262  }
263 
264  // check invariant
265  ARMARX_CHECK_EQUAL(combo->itemData(i).toString(), layerName);
266  }
267 
268  // remove excessive items
269  while (combo->count() > numLayers)
270  {
271  combo->removeItem(combo->count() - 1);
272  }
273  }
274 
275  QString
276  DebugDrawerViewerWidgetController::makeLayerItemText(const LayerInformation& layer)
277  {
278  std::vector<std::string> annotations;
279  if (layer.elementCount == 0)
280  {
281  annotations.push_back("empty");
282  }
283  else
284  {
285  annotations.push_back(std::to_string(layer.elementCount));
286  }
287  if (!layer.visible)
288  {
289  annotations.push_back("hidden");
290  }
291 
292  if (annotations.empty())
293  {
294  return {layer.layerName.c_str()};
295  }
296  else
297  {
298  std::stringstream itemText;
299  itemText << layer.layerName << " (" << simox::alg::join(annotations, ", ") << ")";
300  return {itemText.str().c_str()};
301  }
302  }
303 } // namespace armarx
armarx::ArmarXWidgetController::mutex3D
std::shared_ptr< std::recursive_mutex > mutex3D
Definition: ArmarXWidgetController.h:309
armarx::DebugDrawerViewerWidgetController::onConnectComponent
void onConnectComponent() override
Definition: DebugDrawerViewerWidgetController.cpp:77
armarx::DebugDrawerViewerWidgetController::onInitComponent
void onInitComponent() override
Definition: DebugDrawerViewerWidgetController.cpp:57
index
uint8_t index
Definition: EtherCATFrame.h:59
ArmarXManager.h
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:360
armarx::DebugDrawerViewerWidgetController::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: DebugDrawerViewerWidgetController.cpp:106
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
armarx::DebugDrawerViewerWidgetController::getScene
SoNode * getScene() override
Reimplementing this function and returning a SoNode* will show this SoNode in the 3DViewerWidget,...
Definition: DebugDrawerViewerWidgetController.cpp:117
armarx::DebugDrawerViewerWidgetController::saveSettings
void saveSettings(QSettings *settings) override
Definition: DebugDrawerViewerWidgetController.cpp:51
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::ArmarXWidgetController::enableMainWidgetAsync
void enableMainWidgetAsync(bool enable)
This function enables/disables the main widget asynchronously (if called from a non qt thread).
Definition: ArmarXWidgetController.cpp:191
IceUtil::Handle< ArmarXManager >
DebugDrawerViewerWidgetController.h
armarx::ArmarXWidgetController::getWidget
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
Definition: ArmarXWidgetController.cpp:54
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:108
armarx::DebugDrawerViewerWidgetController::DebugDrawerViewerWidgetController
DebugDrawerViewerWidgetController()
Controller Constructor.
Definition: DebugDrawerViewerWidgetController.cpp:34
armarx::PropertyUser::getIceProperties
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
Definition: PropertyUser.cpp:221
ARMARX_CHECK_EQUAL
#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...
Definition: ExpressionException.h:130
armarx::DebugDrawerViewerWidgetController::loadSettings
void loadSettings(QSettings *settings) override
Definition: DebugDrawerViewerWidgetController.cpp:45
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27