[Sketcher] Refactor TaskSketcherElements::onSelectionChanged()
This commit is contained in:
committed by
Benjamin Nauck
parent
ace0c57dd6
commit
8fd9c19013
@@ -1400,138 +1400,150 @@ void TaskSketcherElements::updateVisibility()
|
||||
}
|
||||
|
||||
/*------------------*/
|
||||
// clang-format on
|
||||
void TaskSketcherElements::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
{
|
||||
std::string temp;
|
||||
if (msg.Type == Gui::SelectionChanges::ClrSelection) {
|
||||
clearWidget();
|
||||
}
|
||||
else if (msg.Type == Gui::SelectionChanges::AddSelection
|
||||
|| msg.Type == Gui::SelectionChanges::RmvSelection) {
|
||||
bool select = (msg.Type == Gui::SelectionChanges::AddSelection);
|
||||
// is it this object??
|
||||
if (strcmp(msg.pDocName, sketchView->getSketchObject()->getDocument()->getName()) == 0
|
||||
&& strcmp(msg.pObjectName, sketchView->getSketchObject()->getNameInDocument()) == 0) {
|
||||
if (msg.pSubName) {
|
||||
ElementItem* modified_item = NULL;
|
||||
QString expr = QString::fromLatin1(msg.pSubName);
|
||||
std::string shapetype(msg.pSubName);
|
||||
// if-else edge vertex
|
||||
if (shapetype.size() > 4 && shapetype.substr(0, 4) == "Edge") {
|
||||
QRegularExpression rx(QStringLiteral("^Edge(\\d+)$"));
|
||||
QRegularExpressionMatch match;
|
||||
boost::ignore_unused(expr.indexOf(rx, 0, &match));
|
||||
if (match.hasMatch()) {
|
||||
bool ok;
|
||||
int ElementId = match.captured(1).toInt(&ok) - 1;
|
||||
if (ok) {
|
||||
int countItems = ui->listWidgetElements->count();
|
||||
// TODO: This and the loop below get slow when we have a lot of items.
|
||||
// Perhaps we should also maintain a map so that we can look up items
|
||||
// by element number.
|
||||
for (int i = 0; i < countItems; i++) {
|
||||
ElementItem* item =
|
||||
static_cast<ElementItem*>(ui->listWidgetElements->item(i));
|
||||
if (item->ElementNbr == ElementId) {
|
||||
item->isLineSelected = select;
|
||||
modified_item = item;
|
||||
SketcherGui::scrollTo(ui->listWidgetElements, i, select);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shapetype.size() > 12 && shapetype.substr(0, 12) == "ExternalEdge") {
|
||||
QRegularExpression rx(QStringLiteral("^ExternalEdge(\\d+)$"));
|
||||
QRegularExpressionMatch match;
|
||||
boost::ignore_unused(expr.indexOf(rx, 0, &match));
|
||||
if (match.hasMatch()) {
|
||||
bool ok;
|
||||
int ElementId = -match.captured(1).toInt(&ok) - 2;
|
||||
if (ok) {
|
||||
int countItems = ui->listWidgetElements->count();
|
||||
for (int i = 0; i < countItems; i++) {
|
||||
ElementItem* item =
|
||||
static_cast<ElementItem*>(ui->listWidgetElements->item(i));
|
||||
if (item->ElementNbr == ElementId) {
|
||||
item->isLineSelected = select;
|
||||
modified_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shapetype.size() > 6 && shapetype.substr(0, 6) == "Vertex") {
|
||||
QRegularExpression rx(QStringLiteral("^Vertex(\\d+)$"));
|
||||
QRegularExpressionMatch match;
|
||||
boost::ignore_unused(expr.indexOf(rx, 0, &match));
|
||||
if (match.hasMatch()) {
|
||||
bool ok;
|
||||
int ElementId = match.captured(1).toInt(&ok) - 1;
|
||||
if (ok) {
|
||||
// Get the GeoID&Pos
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
sketchView->getSketchObject()->getGeoVertexIndex(
|
||||
ElementId, GeoId, PosId);
|
||||
// update the listwidget
|
||||
auto updateListWidget = [this](auto& modified_item) {
|
||||
QSignalBlocker sigblk(this->ui->listWidgetElements);
|
||||
if (modified_item == nullptr) {
|
||||
return;
|
||||
}
|
||||
bool is_selected = modified_item->isSelected();
|
||||
const bool should_be_selected = modified_item->isLineSelected
|
||||
|| modified_item->isStartingPointSelected || modified_item->isEndPointSelected
|
||||
|| modified_item->isMidPointSelected;
|
||||
|
||||
int countItems = ui->listWidgetElements->count();
|
||||
for (int i = 0; i < countItems; i++) {
|
||||
ElementItem* item =
|
||||
static_cast<ElementItem*>(ui->listWidgetElements->item(i));
|
||||
if (item->ElementNbr == GeoId) {
|
||||
modified_item = item;
|
||||
switch (PosId) {
|
||||
case Sketcher::PointPos::start:
|
||||
item->isStartingPointSelected = select;
|
||||
break;
|
||||
case Sketcher::PointPos::end:
|
||||
item->isEndPointSelected = select;
|
||||
break;
|
||||
case Sketcher::PointPos::mid:
|
||||
item->isMidPointSelected = select;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If an element is already selected and a new subelement gets selected
|
||||
// (eg., if you select the arc of a circle then select the center as
|
||||
// well), the new subelement won't get highlighted in the list until you
|
||||
// mouseover the list. To avoid this, we deselect first to trigger a
|
||||
// redraw.
|
||||
if (should_be_selected && is_selected) {
|
||||
modified_item->setSelected(false);
|
||||
is_selected = false;
|
||||
}
|
||||
|
||||
if (should_be_selected != is_selected) {
|
||||
modified_item->setSelected(should_be_selected);
|
||||
}
|
||||
};
|
||||
|
||||
switch (msg.Type) {
|
||||
case Gui::SelectionChanges::ClrSelection: {
|
||||
clearWidget();
|
||||
return;
|
||||
}
|
||||
case Gui::SelectionChanges::AddSelection:
|
||||
case Gui::SelectionChanges::RmvSelection: {
|
||||
bool select = (msg.Type == Gui::SelectionChanges::AddSelection);
|
||||
// is it this object??
|
||||
if (strcmp(msg.pDocName, sketchView->getSketchObject()->getDocument()->getName()) != 0
|
||||
|| strcmp(msg.pObjectName, sketchView->getSketchObject()->getNameInDocument())
|
||||
!= 0) {
|
||||
return;
|
||||
}
|
||||
if (!msg.pSubName) {
|
||||
return;
|
||||
}
|
||||
ElementItem* modified_item = nullptr;
|
||||
QString expr = QString::fromLatin1(msg.pSubName);
|
||||
std::string shapetype(msg.pSubName);
|
||||
// if-else edge vertex
|
||||
if (boost::starts_with(shapetype, "Edge")) {
|
||||
QRegularExpression rx(QStringLiteral("^Edge(\\d+)$"));
|
||||
QRegularExpressionMatch match;
|
||||
boost::ignore_unused(expr.indexOf(rx, 0, &match));
|
||||
if (!match.hasMatch()) {
|
||||
return;
|
||||
}
|
||||
// update the listwidget
|
||||
{
|
||||
QSignalBlocker sigblk(ui->listWidgetElements);
|
||||
if (modified_item != NULL) {
|
||||
bool is_selected = modified_item->isSelected();
|
||||
const bool should_be_selected = modified_item->isLineSelected
|
||||
|| modified_item->isStartingPointSelected || modified_item->isEndPointSelected
|
||||
|| modified_item->isMidPointSelected;
|
||||
|
||||
// If an element is already selected and a new subelement gets selected
|
||||
// (eg., if you select the arc of a circle then select the center as well),
|
||||
// the new subelement won't get highlighted in the list until you mouseover
|
||||
// the list. To avoid this, we deselect first to trigger a redraw.
|
||||
if (should_be_selected && is_selected) {
|
||||
modified_item->setSelected(false);
|
||||
is_selected = false;
|
||||
}
|
||||
|
||||
if (should_be_selected != is_selected) {
|
||||
modified_item->setSelected(should_be_selected);
|
||||
}
|
||||
bool ok;
|
||||
int ElementId = match.captured(1).toInt(&ok) - 1;
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
int countItems = ui->listWidgetElements->count();
|
||||
// TODO: This and the loop below get slow when we have a lot of items.
|
||||
// Perhaps we should also maintain a map so that we can look up items
|
||||
// by element number.
|
||||
for (int i = 0; i < countItems; i++) {
|
||||
ElementItem* item = static_cast<ElementItem*>(ui->listWidgetElements->item(i));
|
||||
if (item->ElementNbr == ElementId) {
|
||||
item->isLineSelected = select;
|
||||
modified_item = item;
|
||||
SketcherGui::scrollTo(ui->listWidgetElements, i, select);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (boost::starts_with(shapetype, "ExternalEdge")) {
|
||||
QRegularExpression rx(QStringLiteral("^ExternalEdge(\\d+)$"));
|
||||
QRegularExpressionMatch match;
|
||||
boost::ignore_unused(expr.indexOf(rx, 0, &match));
|
||||
if (!match.hasMatch()) {
|
||||
return;
|
||||
}
|
||||
bool ok;
|
||||
int ElementId = -match.captured(1).toInt(&ok) - 2;
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
int countItems = ui->listWidgetElements->count();
|
||||
for (int i = 0; i < countItems; i++) {
|
||||
ElementItem* item = static_cast<ElementItem*>(ui->listWidgetElements->item(i));
|
||||
if (item->ElementNbr == ElementId) {
|
||||
item->isLineSelected = select;
|
||||
modified_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (boost::starts_with(shapetype, "Vertex")) {
|
||||
QRegularExpression rx(QStringLiteral("^Vertex(\\d+)$"));
|
||||
QRegularExpressionMatch match;
|
||||
boost::ignore_unused(expr.indexOf(rx, 0, &match));
|
||||
if (!match.hasMatch()) {
|
||||
return;
|
||||
}
|
||||
bool ok;
|
||||
int ElementId = match.captured(1).toInt(&ok) - 1;
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
// Get the GeoID&Pos
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
sketchView->getSketchObject()->getGeoVertexIndex(ElementId, GeoId, PosId);
|
||||
|
||||
int countItems = ui->listWidgetElements->count();
|
||||
for (int i = 0; i < countItems; i++) {
|
||||
ElementItem* item = static_cast<ElementItem*>(ui->listWidgetElements->item(i));
|
||||
if (item->ElementNbr == GeoId) {
|
||||
modified_item = item;
|
||||
switch (PosId) {
|
||||
case Sketcher::PointPos::start:
|
||||
item->isStartingPointSelected = select;
|
||||
break;
|
||||
case Sketcher::PointPos::end:
|
||||
item->isEndPointSelected = select;
|
||||
break;
|
||||
case Sketcher::PointPos::mid:
|
||||
item->isMidPointSelected = select;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateListWidget(modified_item);
|
||||
}
|
||||
}
|
||||
else if (msg.Type == Gui::SelectionChanges::SetSelection) {
|
||||
// do nothing here
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
// clang-format off
|
||||
|
||||
void TaskSketcherElements::onListWidgetElementsItemPressed(QListWidgetItem* it)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user