void NMEAGPS::updateEndPointUI(){ if (boat.isMoving){ ui->resultLabel->setText(QString::number(boat.boatSpeed, 'f', 2) + " knots"); if (boat.latitude < 0) ui->southButton->setChecked(true); else ui->northButton->setChecked(true); if (boat.longnitude < 0) { ui->westButton->setChecked(true); } else { ui->eastButton->setChecked(true); } QString latstr = QString::fromStdString(DegreesMinutesSecondsLat(boat.latitude, 0)); QString lngstr = QString::fromStdString(DegreesMinutesSecondsLng(boat.longnitude, 0)); ui->latLineEdit->setText(latstr.left(8)); ui->longLineEdit->setText(lngstr.left(9)); coordinatesChanged(); setBoatMapLocation(boat.latitude, boat.longnitude); } }
void LocationInformationWidget::acceptChanges() { emit stopFilterDiveSite(); char *uiString; currentDs->latitude = displayed_dive_site.latitude; currentDs->longitude = displayed_dive_site.longitude; uiString = ui.diveSiteName->text().toUtf8().data(); if (!same_string(uiString, currentDs->name)) { free(currentDs->name); currentDs->name = copy_string(uiString); } uiString = ui.diveSiteDescription->text().toUtf8().data(); if (!same_string(uiString, currentDs->description)) { free(currentDs->description); currentDs->description = copy_string(uiString); } uiString = ui.diveSiteNotes->document()->toPlainText().toUtf8().data(); if (!same_string(uiString, currentDs->notes)) { free(currentDs->notes); currentDs->notes = copy_string(uiString); } if (current_mode == CREATE_DIVE_SITE) displayed_dive.dive_site_uuid = currentDs->uuid; if (dive_site_is_empty(currentDs)) { LocationInformationModel::instance()->removeRow(get_divesite_idx(currentDs)); displayed_dive.dive_site_uuid = 0; } mark_divelist_changed(true); resetState(); emit informationManagementEnded(); emit coordinatesChanged(); }
void LocationInformationWidget::acceptChanges() { char *uiString; currentDs->latitude = displayed_dive_site.latitude; currentDs->longitude = displayed_dive_site.longitude; uiString = ui.diveSiteName->text().toUtf8().data(); if (!same_string(uiString, currentDs->name)) { free(currentDs->name); currentDs->name = copy_string(uiString); } uiString = ui.diveSiteDescription->text().toUtf8().data(); if (!same_string(uiString, currentDs->description)) { free(currentDs->description); currentDs->description = copy_string(uiString); } uiString = ui.diveSiteNotes->document()->toPlainText().toUtf8().data(); if (!same_string(uiString, currentDs->notes)) { free(currentDs->notes); currentDs->notes = copy_string(uiString); } if (dive_site_is_empty(currentDs)) { delete_dive_site(currentDs->uuid); displayed_dive.dive_site_uuid = 0; setLocationId(0); } else { setLocationId(currentDs->uuid); } mark_divelist_changed(true); resetState(); emit informationManagementEnded(); emit coordinatesChanged(); }
void LocationInformationWidget::rejectChanges() { resetState(); emit stopFilterDiveSite(); emit informationManagementEnded(); emit coordinatesChanged(); }
void LocationInformationWidget::on_diveSiteName_textChanged(const QString& text) { if (!same_string(qPrintable(text), currentDs->name)) { free(displayed_dive_site.name); displayed_dive_site.name = copy_string(qPrintable(text)); markChangedWidget(ui.diveSiteName); emit coordinatesChanged(); } }
//------------------------------------------------------------------------------ void ctkCoordinatesWidget::updateCoordinates() { Q_D(ctkCoordinatesWidget); for (int i = 0; i < d->Dimension; ++i) { d->Coordinates[i] = this->spinBox(i)->value(); } emit coordinatesChanged(d->Coordinates); }
void LocationInformationWidget::on_diveSiteCoordinates_textChanged(const QString& text) { if (!currentDs || !same_string(qPrintable(text), printGPSCoords(currentDs->latitude.udeg, currentDs->longitude.udeg))) { double latitude, longitude; if (parseGpsText(text, &latitude, &longitude)) { displayed_dive_site.latitude.udeg = latitude * 1000000; displayed_dive_site.longitude.udeg = longitude * 1000000; markChangedWidget(ui.diveSiteCoordinates); emit coordinatesChanged(); } } }
void LocationInformationWidget::rejectChanges() { Q_ASSERT(currentDs != NULL); if (dive_site_is_empty(currentDs)) { delete_dive_site(currentDs->uuid); displayed_dive.dive_site_uuid = 0; setLocationId(0); } else { setLocationId(currentDs->uuid); } resetState(); emit informationManagementEnded(); emit coordinatesChanged(); }
//------------------------------------------------------------------------------ void ctkCoordinatesWidget::updateCoordinates() { for (int i = 0; i < this->Dimension; ++i) { QLayoutItem* item = this->layout()->itemAt(i); QDoubleSpinBox* spinBox = item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : 0; if ( spinBox) { this->Coordinates[i] = spinBox->value(); } } emit coordinatesChanged(this->Coordinates); }
//------------------------------------------------------------------------------ void ctkCoordinatesWidget::updateCoordinate(double coordinate) { for (int i = 0; i < this->Dimension; ++i) { QLayoutItem* item = this->layout()->itemAt(i); QDoubleSpinBox* spinBox = item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : 0; if ( spinBox && spinBox == this->sender()) { this->Coordinates[i] = coordinate; break; } } emit coordinatesChanged(this->Coordinates); }
void NMEAGPS::setCoordinates() { if (validateCoordinates()){ boat.latitude = Boat::latDecimal(ui->latLineEdit->text()); if (ui->southButton->isChecked()) boat.latitude = boat.latitude * -1; boat.longnitude = Boat::longDecimal(ui->longLineEdit->text()); if (ui->westButton->isChecked()) boat.longnitude = boat.longnitude * -1; coordinatesChanged(); setBoatMapLocation(boat.latitude, boat.longnitude); ui->latLineEdit->setCursorPosition(latCursorPos); ui->longLineEdit->setCursorPosition(longCursorPos); } }
MainWindow::MainWindow() : dcStream_(0) , desktopSelectionWindow_(new DesktopSelectionWindow()) , x_(0) , y_(0) , width_(0) , height_(0) , deviceScale_(1.f) { generateCursorImage(); setupUI(); // Receive changes from the selection rectangle connect(desktopSelectionWindow_->getDesktopSelectionView()->getDesktopSelectionRectangle(), SIGNAL(coordinatesChanged(QRect)), this, SLOT(setCoordinates(QRect))); connect(desktopSelectionWindow_, SIGNAL(windowVisible(bool)), showDesktopSelectionWindowAction_, SLOT(setChecked(bool))); }
void LocationInformationWidget::on_diveSiteName_textChanged(const QString& text) { if (currentDs && text != currentDs->name) { // This needs to be changed directly into the model so that // the changes are replyed on the ComboBox with the current selection. int i; struct dive_site *ds; for_each_dive_site(i,ds) if (ds->uuid == currentDs->uuid) break; displayed_dive_site.name = copy_string(qPrintable(text)); QModelIndex idx = LocationInformationModel::instance()->index(i,0); LocationInformationModel::instance()->setData(idx, text, Qt::EditRole); markChangedWidget(ui.diveSiteName); emit coordinatesChanged(); }
void LocationInformationWidget::rejectChanges() { if (current_mode == CREATE_DIVE_SITE) { LocationInformationModel::instance()->removeRow(get_divesite_idx(currentDs)); if (displayed_dive.dive_site_uuid) { displayed_dive_site = *get_dive_site_by_uuid(displayed_dive.dive_site_uuid); } else { displayed_dive_site.uuid = 0; } } else if ((currentDs && dive_site_is_empty(currentDs))) { LocationInformationModel::instance()->removeRow(get_divesite_idx(currentDs)); displayed_dive_site.uuid = 0; } resetState(); emit stopFilterDiveSite(); emit informationManagementEnded(); emit coordinatesChanged(); }
QgsMapToolNodeTool::QgsMapToolNodeTool( QgsMapCanvas* canvas ): QgsMapToolVertexEdit( canvas ) { mSelectionFeature = NULL; mQRubberBand = NULL; mSelectAnother = false; mCtrl = false; mMoving = true; mClicked = false; mChangingGeometry = false; mIsPoint = false; //signal handling change of layer structure connect( canvas, SIGNAL( layersChanged() ), this, SLOT( layersChanged() ) ); //signal when destination srs changed to repaint coordinates connect( canvas->mapRenderer(), SIGNAL( destinationSrsChanged() ), this, SLOT( coordinatesChanged() ) ); //signal changing of coordinate renderer changed to repaint markers connect( canvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( coordinatesChanged( ) ) ); //signal changing of current layer connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) ); }
/*! \class MatrixModel \brief Model for the access to data of a Matrix-object. This is a model in the sense of Qt4 model/view framework which is used to access a Matrix object from any of Qt4s view classes, typically a QMatrixView. Its main purposes are translating Matrix signals into QAbstractItemModel signals and translating calls to the QAbstractItemModel read/write API into calls in the public API of Matrix. \ingroup backend */ MatrixModel::MatrixModel(Matrix* matrix) : QAbstractItemModel(0), m_matrix(matrix), m_suppressDataChangedSignal(false) { connect(m_matrix, SIGNAL(columnsAboutToBeInserted(int,int)), this, SLOT(handleColumnsAboutToBeInserted(int,int))); connect(m_matrix, SIGNAL(columnsInserted(int,int)), this, SLOT(handleColumnsInserted(int,int))); connect(m_matrix, SIGNAL(columnsAboutToBeRemoved(int,int)), this, SLOT(handleColumnsAboutToBeRemoved(int,int))); connect(m_matrix, SIGNAL(columnsRemoved(int,int)), this, SLOT(handleColumnsRemoved(int,int))); connect(m_matrix, SIGNAL(rowsAboutToBeInserted(int,int)), this, SLOT(handleRowsAboutToBeInserted(int,int))); connect(m_matrix, SIGNAL(rowsInserted(int,int)), this, SLOT(handleRowsInserted(int,int))); connect(m_matrix, SIGNAL(rowsAboutToBeRemoved(int,int)), this, SLOT(handleRowsAboutToBeRemoved(int,int))); connect(m_matrix, SIGNAL(rowsRemoved(int,int)), this, SLOT(handleRowsRemoved(int,int))); connect(m_matrix, SIGNAL(dataChanged(int,int,int,int)), this, SLOT(handleDataChanged(int,int,int,int))); connect(m_matrix, SIGNAL(coordinatesChanged()), this, SLOT(handleCoordinatesChanged())); connect(m_matrix, SIGNAL(numericFormatChanged(char)), this, SLOT(handleFormatChanged())); connect(m_matrix, SIGNAL(precisionChanged(int)), this, SLOT(handleFormatChanged())); }
void DesktopSelectionRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { if(event->buttons().testFlag(Qt::LeftButton)) { if(resizing_) { QRectF r = rect(); QPointF eventPos = event->pos(); r.setBottomRight(eventPos); setRect(r); } else { QPointF delta = event->pos() - event->lastPos(); moveBy(delta.x(), delta.y()); } updateCoordinates(); emit coordinatesChanged(x_, y_, width_, height_); } }
MainWindow::MainWindow() : QMainWindow(), actionNextDive(0), actionPreviousDive(0), helpView(0), state(VIEWALL), survey(0) { Q_ASSERT_X(m_Instance == NULL, "MainWindow", "MainWindow recreated!"); m_Instance = this; ui.setupUi(this); read_hashes(); // Define the States of the Application Here, Currently the states are situations where the different // widgets will change on the mainwindow. // for the "default" mode MainTab *mainTab = new MainTab(); DiveListView *diveListView = new DiveListView(); ProfileWidget2 *profileWidget = new ProfileWidget2(); #ifndef NO_MARBLE GlobeGPS *globeGps = new GlobeGPS(); #else QWidget *globeGps = NULL; #endif PlannerSettingsWidget *plannerSettings = new PlannerSettingsWidget(); DivePlannerWidget *plannerWidget = new DivePlannerWidget(); PlannerDetails *plannerDetails = new PlannerDetails(); LocationInformationWidget *locationInformation = new LocationInformationWidget(); // what is a sane order for those icons? we should have the ones the user is // most likely to want towards the top so they are always visible // and the ones that someone likely sets and then never touches again towards the bottom profileToolbarActions << ui.profCalcCeiling << ui.profCalcAllTissues << // start with various ceilings ui.profIncrement3m << ui.profDcCeiling << ui.profPhe << ui.profPn2 << ui.profPO2 << // partial pressure graphs ui.profRuler << ui.profScaled << // measuring and scaling ui.profTogglePicture << ui.profTankbar << ui.profMod << ui.profNdl_tts << // various values that a user is either interested in or not ui.profEad << ui.profSAC << ui.profHR << // very few dive computers support this ui.profTissues; // maybe less frequently used QToolBar *toolBar = new QToolBar(); Q_FOREACH (QAction *a, profileToolbarActions) toolBar->addAction(a); toolBar->setOrientation(Qt::Vertical); toolBar->setIconSize(QSize(24,24)); QWidget *profileContainer = new QWidget(); QHBoxLayout *profLayout = new QHBoxLayout(); profLayout->setSpacing(0); profLayout->setMargin(0); profLayout->setContentsMargins(0,0,0,0); profLayout->addWidget(toolBar); profLayout->addWidget(profileWidget); profileContainer->setLayout(profLayout); registerApplicationState("Default", mainTab, profileContainer, diveListView, globeGps ); registerApplicationState("AddDive", mainTab, profileContainer, diveListView, globeGps ); registerApplicationState("EditDive", mainTab, profileContainer, diveListView, globeGps ); registerApplicationState("PlanDive", plannerWidget, profileContainer, plannerSettings, plannerDetails ); registerApplicationState("EditPlannedDive", plannerWidget, profileContainer, diveListView, globeGps ); registerApplicationState("EditDiveSite",locationInformation, profileContainer, diveListView, globeGps ); setApplicationState("Default"); ui.multiFilter->hide(); setWindowIcon(QIcon(":subsurface-icon")); if (!QIcon::hasThemeIcon("window-close")) { QIcon::setThemeName("subsurface"); } connect(dive_list(), SIGNAL(currentDiveChanged(int)), this, SLOT(current_dive_changed(int))); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(readSettings())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), diveListView, SLOT(update())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), diveListView, SLOT(reloadHeaderActions())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), information(), SLOT(updateDiveInfo())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerWidget(), SLOT(settingsChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerSettingsWidget(), SLOT(settingsChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), TankInfoModel::instance(), SLOT(update())); connect(ui.actionRecent1, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent2, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent3, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent4, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(information(), SIGNAL(addDiveFinished()), graphics(), SLOT(setProfileState())); connect(DivePlannerPointsModel::instance(), SIGNAL(planCreated()), this, SLOT(planCreated())); connect(DivePlannerPointsModel::instance(), SIGNAL(planCanceled()), this, SLOT(planCanceled())); connect(plannerDetails->printPlan(), SIGNAL(pressed()), divePlannerWidget(), SLOT(printDecoPlan())); connect(mainTab, SIGNAL(requestDiveSiteEdit(uint32_t)), this, SLOT(enableDiveSiteEdit(uint32_t))); connect(locationInformation, SIGNAL(informationManagementEnded()), this, SLOT(setDefaultState())); connect(locationInformation, SIGNAL(informationManagementEnded()), information(), SLOT(showLocation())); connect(locationInformation, SIGNAL(coordinatesChanged()), globe(), SLOT(repopulateLabels())); #ifdef NO_PRINTING plannerDetails->printPlan()->hide(); ui.menuFile->removeAction(ui.actionPrint); #endif #ifndef USE_LIBGIT23_API ui.menuFile->removeAction(ui.actionCloudstorageopen); ui.menuFile->removeAction(ui.actionCloudstoragesave); qDebug() << "disabled / made invisible the cloud storage stuff"; #endif ui.mainErrorMessage->hide(); graphics()->setEmptyState(); initialUiSetup(); readSettings(); diveListView->reload(DiveTripModel::TREE); diveListView->reloadHeaderActions(); diveListView->setFocus(); globe()->reload(); diveListView->expand(dive_list()->model()->index(0, 0)); diveListView->scrollTo(dive_list()->model()->index(0, 0), QAbstractItemView::PositionAtCenter); divePlannerWidget()->settingsChanged(); divePlannerSettingsWidget()->settingsChanged(); #ifdef NO_MARBLE ui.menuView->removeAction(ui.actionViewGlobe); #else connect(globe(), SIGNAL(coordinatesChanged()), locationInformation, SLOT(updateGpsCoordinates())); #endif #ifdef NO_USERMANUAL ui.menuHelp->removeAction(ui.actionUserManual); #endif memset(©PasteDive, 0, sizeof(copyPasteDive)); memset(&what, 0, sizeof(what)); updateManager = new UpdateManager(this); undoStack = new QUndoStack(this); QAction *undoAction = undoStack->createUndoAction(this, tr("&Undo")); QAction *redoAction = undoStack->createRedoAction(this, tr("&Redo")); undoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z)); redoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z)); QList<QAction*>undoRedoActions; undoRedoActions.append(undoAction); undoRedoActions.append(redoAction); ui.menu_Edit->addActions(undoRedoActions); ReverseGeoLookupThread *geoLookup = ReverseGeoLookupThread::instance(); connect(geoLookup, SIGNAL(started()),information(), SLOT(disableGeoLookupEdition())); connect(geoLookup, SIGNAL(finished()), information(), SLOT(enableGeoLookupEdition())); }
//------------------------------------------------------------------------------ void ctkCoordinatesWidget::updateCoordinate(double coordinate) { Q_D(ctkCoordinatesWidget); int element = -1; for (int i = 0; i < d->Dimension; ++i) { if ( this->spinBox(i) && this->spinBox(i) == this->sender()) { d->Coordinates[i] = coordinate; element = i; } } Q_ASSERT(element != -1); // Update the last edited history by push first the element. for (int i = d->Dimension -1; i > 0; --i) { if (d->LastUserEditedCoordinates[i] == element) { d->LastUserEditedCoordinates.swap(i,i-1); } } // What is the oldest coordinate to be edited int oldestElement = d->LastUserEditedCoordinates.last(); if (this->isNormalized()) { // We have to ensure the coordinates are normalized. double den = 0.; double squaredNorm = this->squaredNorm(); // Old Values xx + yy + zz = 1 // New values: x'x' + y'y' + z'z' = 1 // Say we are changing y into y': // x'x' + z'z' = 1 - y'y' if (oldestElement != -1 && d->Coordinates[oldestElement] != 0.0 && squaredNorm != 0.0) { // 1) Normalize only with the oldest user edited value // The oldest element is z, that means we try to have // x = x' (so that the user doesn't loose the edit he just made on the // element (x) he edited before this one (y). // Let's pose a the coef to multiply z into z' that keeps the norm to 1 // xx + z'z' = 1 - y'y' (because x = x') // xx + azaz = 1 - y'y' (because z' = az) // aa*zz = 1 - y'y' - xx // a = sqrt( (1 - y'y' - xx) / zz ) den = (1. - (squaredNorm - d->Coordinates[oldestElement] * d->Coordinates[oldestElement])) / (d->Coordinates[oldestElement] * d->Coordinates[oldestElement]); if (den > 0.) { den = sqrt(den); } } // Maybe 1) failed, then give 2) a chance. if (den <= 0) { oldestElement = -1; } bool mult = true; if (oldestElement == -1) { // 2) Normalize with all the coordinates // Let's pose a the coef to multiply x into x' and z into z' that keeps // the norm to 1: // axax + azaz = 1 - y'y' // aa(xx + zz) = 1 - y'y' // a = sqrt( (1 - y'y') / (xx + zz) ) squaredNorm -= coordinate * coordinate; if (squaredNorm != 0.0) { den = sqrt( (1. - coordinate * coordinate) / squaredNorm); } else if (d->Dimension > 1) { mult = false; den = sqrt((1. - coordinate*coordinate) / (d->Dimension - 1)); } } // Normalize coordinates double* normalizedCoordinates = new double[d->Dimension]; for (int i = 0; i < d->Dimension; ++i) { if ((i != element && oldestElement == -1) || (i == oldestElement && oldestElement != -1)) { normalizedCoordinates[i] = mult ? d->Coordinates[i] * den : den; } else { normalizedCoordinates[i] = d->Coordinates[i]; } } this->setCoordinates(normalizedCoordinates); delete [] normalizedCoordinates; } else { emit coordinatesChanged(d->Coordinates); } }
void MapView::redraw() { if (!this->isEnabled()) { // blank uchar *bits = image.bits(); int imgstride = image.bytesPerLine(); int imgoffset = 0; for (int y = 0; y < image.height(); y++, imgoffset += imgstride) memset(bits + imgoffset, 0xee, imgstride); update(); return; } double chunksize = 16 * zoom; // first find the center block position int centerchunkx = floor(x / 16); int centerchunkz = floor(z / 16); // and the center of the screen int centerx = image.width() / 2; int centery = image.height() / 2; // and align for panning centerx -= (x - centerchunkx * 16) * zoom; centery -= (z - centerchunkz * 16) * zoom; // now calculate the topleft block on the screen int startx = centerchunkx - floor(centerx / chunksize) - 1; int startz = centerchunkz - floor(centery / chunksize) - 1; // and the dimensions of the screen in blocks int blockswide = image.width() / chunksize + 3; int blockstall = image.height() / chunksize + 3; for (int cz = startz; cz < startz + blockstall; cz++) for (int cx = startx; cx < startx + blockswide; cx++) drawChunk(cx, cz); // add on the entity layer QPainter canvas(&image); double halfviewwidth = image.width() / 2 / zoom; double halvviewheight = image.height() / 2 / zoom; double x1 = x - halfviewwidth; double z1 = z - halvviewheight; double x2 = x + halfviewwidth; double z2 = z + halvviewheight; // draw the entities for (int cz = startz; cz < startz + blockstall; cz++) { for (int cx = startx; cx < startx + blockswide; cx++) { for (auto &type : overlayItemTypes) { Chunk *chunk = cache.fetch(cx, cz); if (chunk) { auto range = chunk->entities.equal_range(type); for (auto it = range.first; it != range.second; ++it) { // don't show entities above our depth int entityY = (*it)->midpoint().y; // everything below the current block, // but also inside the current block if (entityY < depth + 1) { int entityX = static_cast<int>((*it)->midpoint().x) & 0x0f; int entityZ = static_cast<int>((*it)->midpoint().z) & 0x0f; int index = entityX + (entityZ << 4); int highY = chunk->depth[index]; if ( (entityY+10 >= highY) || (entityY+10 >= depth) ) (*it)->draw(x1, z1, zoom, &canvas); } } } } } } // draw the generated structures for (auto &type : overlayItemTypes) { for (auto &item : overlayItems[type]) { if (item->intersects(OverlayItem::Point(x1 - 1, 0, z1 - 1), OverlayItem::Point(x2 + 1, depth, z2 + 1))) { item->draw(x1, z1, zoom, &canvas); } } } emit(coordinatesChanged(x, depth, z)); update(); }
//------------------------------------------------------------------------------ void ctkCoordinatesWidget::updateCoordinate(double coordinate) { double den = 0.; int element = -1; for (int i = 0; i < this->Dimension; ++i) { QLayoutItem* item = this->layout()->itemAt(i); QDoubleSpinBox* spinBox = item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : 0; if ( spinBox && spinBox == this->sender()) { this->Coordinates[i] = coordinate; element = i; } else { den += this->Coordinates[i]*this->Coordinates[i]; } } Q_ASSERT(element != -1); if (this->isNormalized()) { // Old Values xx + yy + zz = 1 // New values: x'x' + y'y' + z'z' = 1 // Say we are changing y into y': // x'x' + z'z' = 1 - y'y' // Let's pose a the coef to multiply x into x' that keeps the norm to 1: // axax + azaz = 1 - y'y' // aa(xx + zz) = 1 - y'y' // a = sqrt( (1 - y'y') / (xx + zz) ) bool mult = true; if (den != 0.0) { mult = true; den = sqrt( (1. - coordinate * coordinate) / den); } else if (this->Dimension > 1) { mult = false; den = sqrt((1. - coordinate*coordinate) / (this->Dimension - 1)); } double* normalizedCoordinates = new double[this->Dimension]; for (int i = 0; i < this->Dimension; ++i) { if (i != element) { normalizedCoordinates[i] = mult ? this->Coordinates[i] * den : den; } else { normalizedCoordinates[i] = this->Coordinates[i]; } } this->setCoordinates(normalizedCoordinates); delete [] normalizedCoordinates; } else { emit coordinatesChanged(this->Coordinates); } }