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