diff --git a/docs/dev_doc/UndoRedoStackDesign.md b/docs/dev_doc/UndoRedoStackDesign.md new file mode 100644 index 0000000000..0f0ae6a50f --- /dev/null +++ b/docs/dev_doc/UndoRedoStackDesign.md @@ -0,0 +1,408 @@ +# Undo/Redo Stack Redesign + +**Relates to:** Issues #41 (Global State Manager), #221 (History: store diffs not full state), #223 (Undo position bug on module-with-connections removal), #300 (Performance of undo/redo when network.size > 60), #393 (Algorithm set/get parameters needs hook for Global State Manager) + +--- + +## Problem Summary + +The current provenance/undo system has three compounding failures: + +1. **Missing event coverage.** Module parameter changes are never recorded. The + `connectProvenanceStateChanged` signal fires correctly with old/new values, but the + subscriber only emits `LOG_TRACE` and discards the data. There is no + `ModuleStateChangedProvenanceItem` class. + +2. **Broken Python-string approach for connections.** `ConnectionAddedProvenanceItem` + generates `scirun_connect_modules("")` — a single opaque + string — but the actual Python API requires four arguments: + `connect(moduleIdFrom, int fromPortIndex, moduleIdTo, int toPortIndex)`. The + `#if 0` block in its own constructor documents the failed attempt to extract port + indices. Connection undo/redo does not work. + +3. **ID mutation breaks sequences.** When undoing a module removal, + `scirun_add_module("ReadMatrix")` re-adds the module with a fresh + auto-incremented ID (`ReadMatrix:2` instead of the original `ReadMatrix:0`). Any + subsequent connection operations in the same undo sequence reference the original + (now stale) ID. The `mostRecentAddModuleId()` hack is a single-slot variable that + cannot handle sequences involving more than one re-added module. + +4. **Performance scales with network size, not operation size.** Every + `ProvenanceItemBase` stores a full `NetworkFileHandle` XML snapshot regardless of + what changed. Undo/redo dispatches through the Python interpreter. Measured cost: + ~3 s for 64 modules, ~6 s for 120 modules (issue #300). + +5. **Dead stub code.** `ModuleAddCommand` / `NetworkCommands.cc` — the + `RedoableCommand` hierarchy that was the right design — throws `"not implemented"` + for all three methods and has never been touched. + +--- + +## Design Goals + +| Goal | Constraint | +|---|---| +| Cover all editable events | module add/remove, connection add/remove, move, parameter change | +| Delta-only storage | no per-item XML snapshot; store only what changed | +| C++ execution | no Python interpreter on the undo/redo hot path | +| Stable IDs across sequences | undo → redo → undo of multi-step sequences must be consistent | +| Coalesce noisy events | slider/spinbox changes must merge into one undo step | +| Composite steps | multi-select delete must be one undo step | +| Keep the ProvenanceWindow UI | list, click-to-inspect, undo/redo/clear buttons stay | +| Keyboard shortcuts | Ctrl+Z / Ctrl+Y wire to the same stack | + +--- + +## Architecture Overview + +``` +NetworkEditor (Qt GUI) + │ signals: moduleAdded, moduleRemoved, connectionAdded, + │ connectionRemoved, moduleMoved, stateChanged + ▼ +GuiActionProvenanceConverter ← keep this; change what it creates + │ Q_EMIT commandRecorded(cmd) + ▼ +NetworkUndoStack ← replaces ProvenanceManager + │ push / undo / redo / clear + ▼ +ProvenanceWindow ← adapt display; keep UX +``` + +The key change: `GuiActionProvenanceConverter` creates `NetworkCommand` objects +instead of `ProvenanceItem` objects. `NetworkCommand` objects execute C++ controller +calls directly; no Python strings are stored or interpreted. + +--- + +## Core Interface + +```cpp +// src/Dataflow/Engine/Controller/NetworkUndoCommands.h + +class NetworkCommand +{ +public: + virtual ~NetworkCommand() = default; + virtual void undo() = 0; + virtual void redo() = 0; // re-executes the operation + virtual std::string description() const = 0; + + // Optional: return true and mutate *this to absorb `next`. + // Used for coalescing move and parameter-change events. + virtual bool tryMerge(const NetworkCommand& next) { return false; } +}; + +using NetworkCommandHandle = SharedPointer; +``` + +`redo()` is what the current system calls `execute()`. Every concrete command +implements both directions entirely in C++, calling the existing +`NetworkEditorController` API. + +--- + +## Concrete Commands + +### AddModuleCommand + +``` +Captured at record time: moduleName (string) +Captured after first redo: assignedId (ModuleId) +``` + +- `redo()` — calls `controller_.addModule(moduleName_)`, stores the returned + `ModuleId` as `assignedId_`. On all subsequent redos it calls + `controller_.addModuleWithId(moduleName_, assignedId_)` (see §ID Stability). +- `undo()` — calls `controller_.removeModule(assignedId_)`. + +### RemoveModuleCommand + +``` +Captured at record time: + moduleId, moduleName, position (QPointF), + savedState (ModuleStateHandle deep copy), + connections (vector) +``` + +Removing a module implicitly removes all its connections. This command must +capture those connections before the removal executes so that `undo()` can +restore them. The connections are re-added as a sub-sequence in `undo()` (see +§Composite Commands for the multi-select case). + +- `undo()` — calls `controller_.addModuleWithId(moduleName_, moduleId_)`, sets + position, restores `savedState_`, then calls `controller_.requestConnection` + for each captured connection. +- `redo()` — calls `controller_.removeModule(moduleId_)`. + +### AddConnectionCommand + +``` +Captured at record time: + fromModuleId, fromPortIndex (int), + toModuleId, toPortIndex (int) +``` + +Port **indices** are captured at record time by calling +`port->getIndex()` inside `GuiActionProvenanceConverter::connectionAdded()`, +where the live port objects are available. This sidesteps the port-ID-to-index +conversion problem that broke the Python approach. + +- `undo()` — calls `controller_.removeConnection(ConnectionId::create(desc_))`. +- `redo()` — looks up ports by index on the live modules and calls + `controller_.requestConnection(from, to)`. + +### RemoveConnectionCommand + +Symmetric to `AddConnectionCommand`. + +### MoveModuleCommand + +``` +Captured at record time: moduleId, oldPos, newPos +``` + +- `undo()` — calls `controller_.moveModule(id_, oldPos_)`. +- `redo()` — calls `controller_.moveModule(id_, newPos_)`. +- `tryMerge(next)` — if `next` is a `MoveModuleCommand` for the same module, + update `newPos_` to `next.newPos_` and return `true`. This collapses a drag + sequence into a single undo step. + +### SetModuleParameterCommand + +``` +Captured at record time: moduleId, parameterName, oldValue, newValue +``` + +- `undo()` — calls `module->get_state()->setValue(paramName_, oldValue_)`. +- `redo()` — calls `module->get_state()->setValue(paramName_, newValue_)`. +- `tryMerge(next)` — if `next` is a `SetModuleParameterCommand` for the same + `(moduleId, parameterName)`, update `newValue_` to `next.newValue_` and return + `true`. This collapses a slider drag into a single undo step. + +The `connectProvenanceStateChanged` lambda in `NetworkEditor.cc` (currently just +`LOG_TRACE`) is completed to emit a `SetModuleParameterCommand` through +`GuiActionProvenanceConverter`. + +### CompositeNetworkCommand + +``` +Holds: vector steps_ +``` + +Used for multi-select delete (and any future batch operation). + +- `undo()` — iterates `steps_` in **reverse** order, calls `undo()` on each. +- `redo()` — iterates `steps_` in forward order, calls `redo()` on each. +- `description()` — e.g. `"Remove 5 modules"`. + +Multi-select delete assembles a `CompositeNetworkCommand` from one +`RemoveConnectionCommand` per affected connection (in the order they are +removed) followed by one `RemoveModuleCommand` per selected module. + +--- + +## NetworkUndoStack + +Replaces `ProvenanceManager`. Uses `std::vector` + a cursor index rather than +two `std::stack`s, which lets the `ProvenanceWindow` support click-to-jump +navigation and makes the undo/redo/clear logic straightforward. + +```cpp +class NetworkUndoStack +{ +public: + explicit NetworkUndoStack(size_t maxDepth = 50); + + // Record a new command. Discards any redo history above the cursor. + // If the new command merges with the top item (tryMerge returns true), + // the stack is not grown. + void push(NetworkCommandHandle cmd); + + bool undo(); // steps cursor back one, calls cmd->undo() + bool redo(); // steps cursor forward one, calls cmd->redo() + void clear(); + + bool canUndo() const; + bool canRedo() const; + std::string undoDescription() const; // description of the command that would be undone + std::string redoDescription() const; + + size_t undoSize() const; + size_t redoSize() const; + size_t maxDepth() const; + void setMaxDepth(size_t max); + + // For ProvenanceWindow list display + const std::vector& history() const; + int currentIndex() const; // cursor position + +private: + std::vector history_; + int cursor_ {-1}; // index of last executed command; -1 = nothing done + size_t maxDepth_; +}; +``` + +`push()` logic: + +1. Drop all items above `cursor_` (discards redo history on new action). +2. Call `history_.back()->tryMerge(*cmd)`. If `true`, do not push; the top + command has absorbed the new one. +3. Otherwise append. If `history_.size() > maxDepth_`, drop `history_.front()` + and decrement `cursor_`. +4. Advance `cursor_`. + +--- + +## ID Stability + +The fundamental problem: `addModule("ReadMatrix")` auto-assigns an ID like +`ReadMatrix:2`; the original may have been `ReadMatrix:0`. Connections recorded +against the original ID break on redo. + +**Solution: `addModuleWithId`** + +Add one method to `NetworkEditorController`: + +```cpp +ModuleHandle addModuleWithId(const std::string& name, const ModuleId& requestedId); +``` + +Behaviour: attempts to register the new module under `requestedId`. If that ID +is already in use (e.g. the user manually added another copy before redoing), +falls back to auto-assignment and logs a warning. This case is inherently +ambiguous; a warning is the right response. + +`AddModuleCommand` and `RemoveModuleCommand::undo()` both use this method after +the first execution, so every redo of an add reliably produces the same ID that +downstream connection commands expect. + +`mostRecentAddModuleId()` and its single-slot implementation in `PythonImpl` can +be removed once this is in place. + +--- + +## Parameter Change Coalescing + +`connectProvenanceStateChanged` fires on every `setValue` call, which includes +every tick of a slider or spinner. Without coalescing, a single slider drag +could push hundreds of commands onto the stack. + +`GuiActionProvenanceConverter` (or a thin helper owned by it) maintains: + +```cpp +QTimer* coalesceTimer_; // single-shot, 300 ms +SharedPointer pending_; // one per (module, param) in flight +``` + +On each `stateChanged(moduleId, paramName, oldV, newV)`: + +1. If `pending_` is null, create it with `oldV` as the baseline old value. +2. Update `pending_->newValue_` to `newV`. +3. Restart `coalesceTimer_`. + +When `coalesceTimer_` fires: emit `commandRecorded(pending_)`, clear `pending_`. + +This ensures that after a slider drag, one undo step restores the full before +value, regardless of how many intermediate ticks fired. + +The 300 ms window is a good default but should be a user preference (same +settings panel as the undo depth spinner that already exists in +`ProvenanceWindow`). + +--- + +## Guard Against Re-recording During Undo/Redo + +The existing `provenanceManagerModifyingNetwork_` boolean in +`GuiActionProvenanceConverter` already handles this correctly. All signals from +`NetworkEditor` that fire during an undo/redo operation are gated by this flag. +No design change needed here. + +The flag is set via `Q_EMIT modifyingNetwork(true/false)` in +`ProvenanceWindow::undo()` / `redo()`, which connects to +`GuiActionProvenanceConverter::networkBeingModifiedByProvenanceManager()`. This +chain is kept as-is. + +--- + +## ProvenanceWindow Adaptation + +The `ProvenanceWindow` UI requires minimal changes: + +- `addProvenanceItem(ProvenanceItemHandle)` → `addCommand(NetworkCommandHandle)`. + The list item label comes from `cmd->description()`. +- The XML preview pane (currently showing the full network XML snapshot stored in + each `ProvenanceItemBase`) is removed or repurposed. The per-item snapshot was + only meaningful in the memento approach, which is being abandoned. +- `undo()` / `redo()` / `undoAll()` / `redoAll()` delegate to `NetworkUndoStack` + rather than `ProvenanceManager`. +- The `itemMaxSpinBox_` already wires to `setMaxDepth`; keep it. +- Click-to-jump: clicking a list item calls `undoStack_.jumpTo(index)`, which + calls `undo()` or `redo()` repeatedly until the cursor reaches that index. + +--- + +## Files + +### New + +| File | Purpose | +|---|---| +| `src/Dataflow/Engine/Controller/NetworkUndoCommands.h` | All concrete command classes | +| `src/Dataflow/Engine/Controller/NetworkUndoCommands.cc` | Implementations | +| `src/Dataflow/Engine/Controller/NetworkUndoStack.h` | Stack class | +| `src/Dataflow/Engine/Controller/NetworkUndoStack.cc` | Stack implementation | + +### Modified + +| File | Change | +|---|---| +| `src/Dataflow/Engine/Controller/NetworkEditorController.h/.cc` | Add `addModuleWithId()` | +| `src/Interface/Application/NetworkEditor.cc` | Complete `connectProvenanceStateChanged` lambda (lines 475–479) to emit commands | +| `src/Interface/Application/ProvenanceWindow.h/.cc` | Replace `ProvenanceManager` with `NetworkUndoStack`; adapt list display | +| `src/Interface/Application/ProvenanceWindow.h` | Add `GuiActionProvenanceConverter::moduleStateChanged` slot and `NetworkEditor::moduleStateChanged` signal | +| `src/Interface/Application/SCIRunMainWindowSetup.cc` | Wire `commandRecorded` signal to `NetworkUndoStack::push` | + +### Deleted / Emptied + +| File | Reason | +|---|---| +| `src/Dataflow/Engine/Controller/NetworkCommands.h/.cc` | Dead stub; replaced by `NetworkUndoCommands` | +| `src/Dataflow/Engine/Controller/ProvenanceItemImpl.h/.cc` | Python-string items replaced by commands | +| `src/Dataflow/Engine/Controller/ProvenanceItem.h/.cc` | Abstract base no longer needed | +| `src/Dataflow/Engine/Controller/ProvenanceManager.h/.cc` | Replaced by `NetworkUndoStack` | +| `src/Dataflow/Engine/Python/NetworkEditorPythonInterface.h` | Remove `mostRecentAddModuleId()` pure virtual | +| `src/Dataflow/Engine/Controller/PythonImpl.h/.cc` | Remove `mostRecentAddModuleId_` field and its setter | + +`ProvenanceItemFactory.h/.cc` should also be audited; if it only creates +`ProvenanceItemImpl` types it can be deleted. + +--- + +## Performance Impact + +| Metric | Current | New | +|---|---|---| +| Storage per undo item | full XML snapshot (~100 KB for large networks) | delta only (bytes to tens of bytes) | +| Undo/redo execution | Python interpreter + network reload | direct C++ controller call | +| 64-module undo latency | ~3 s (measured, issue #300) | ~0 ms (no reload, no Python) | +| Parameter change items | 0 (not recorded) | 1 per coalesced edit | +| Connection undo | broken | works | + +--- + +## What This Resolves + +| Issue | Status after this work | +|---|---| +| #41 — Global State Manager | All five event types covered in one unified C++ stack | +| #221 — Store diffs not full network state | Each command is a pure delta; no `NetworkFileHandle` snapshot stored per item | +| #223 — Undo of module-with-connections loses position | `RemoveModuleCommand` captures `position` explicitly at record time; `undo()` restores it directly; no XML round-trip, no invalid-state window | +| #300 — Performance > 60 modules | Delta commands; no network reload on undo/redo | +| Connection undo (broken Python API) | Port indices captured at record time; no Python | +| Module parameter undo (never implemented) | `SetModuleParameterCommand` + coalescing | +| ID mutation in sequences | `addModuleWithId` makes IDs stable across undo/redo | +| #393 — Algorithm set/get parameters hook for GSM | `connectProvenanceStateChanged` already exists as the signal; completing its subscriber to emit `SetModuleParameterCommand` is the "hook/signal/slot" the issue requested | +| `ModuleAddCommand` dead stubs | Replaced by working implementation | diff --git a/src/Core/Algorithms/Legacy/Fields/Cleanup/ReorderNormalCoherentlyAlgo.cc b/src/Core/Algorithms/Legacy/Fields/Cleanup/ReorderNormalCoherentlyAlgo.cc index 50397e2dfd..fde6c80ca9 100644 --- a/src/Core/Algorithms/Legacy/Fields/Cleanup/ReorderNormalCoherentlyAlgo.cc +++ b/src/Core/Algorithms/Legacy/Fields/Cleanup/ReorderNormalCoherentlyAlgo.cc @@ -200,7 +200,7 @@ void ReorderNormalCoherentlyAlgo::runImpl(FieldHandle inputField, FieldHandle& o for (j = 0; j < noOfV; j++) { k=(j+1)%noOfV; - edges.insert(std::make_pair(elem[i][j], elem[i][k])); + edges.emplace(elem[i][j], elem[i][k]); } outputVMesh->add_elem(nodesFromFace); diff --git a/src/Graphics/Glyphs/GlyphConstructor.cc b/src/Graphics/Glyphs/GlyphConstructor.cc index a20d020492..6eb238a323 100644 --- a/src/Graphics/Glyphs/GlyphConstructor.cc +++ b/src/Graphics/Glyphs/GlyphConstructor.cc @@ -80,17 +80,17 @@ void GlyphConstructor::buildObject(GeometryObjectSpire& geom, const std::string& std::vector attribs; std::vector uniforms; - attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float))); - uniforms.push_back(SpireSubPass::Uniform("uUseClippingPlanes", isClippable)); - uniforms.push_back(SpireSubPass::Uniform("uUseFog", true)); + attribs.emplace_back("aPos", 3 * sizeof(float)); + uniforms.emplace_back("uUseClippingPlanes", isClippable); + uniforms.emplace_back("uUseFog", true); if (useNormals) { numAttributes += 3; - attribs.push_back(SpireVBO::AttributeData("aNormal", 3 * sizeof(float))); - uniforms.push_back(SpireSubPass::Uniform("uAmbientColor", glm::vec4(0.1f, 0.1f, 0.1f, 1.0f))); - uniforms.push_back(SpireSubPass::Uniform("uSpecularColor", glm::vec4(0.1f, 0.1f, 0.1f, 0.1f))); - uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f)); + attribs.emplace_back("aNormal", 3 * sizeof(float)); + uniforms.emplace_back("uAmbientColor", glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)); + uniforms.emplace_back("uSpecularColor", glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)); + uniforms.emplace_back("uSpecularPower", 32.0f); } SpireText text; @@ -101,7 +101,7 @@ void GlyphConstructor::buildObject(GeometryObjectSpire& geom, const std::string& { numAttributes += 2; shader += "_ColorMap"; - attribs.push_back(SpireVBO::AttributeData("aTexCoords", 2 * sizeof(float))); + attribs.emplace_back("aTexCoords", 2 * sizeof(float)); const static int colorMapResolution = 256; for(int i = 0; i < colorMapResolution; ++i) @@ -121,16 +121,16 @@ void GlyphConstructor::buildObject(GeometryObjectSpire& geom, const std::string& { numAttributes += 4; shader += "_Color"; - attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float))); + attribs.emplace_back("aColor", 4 * sizeof(float)); } } else { - uniforms.push_back(SpireSubPass::Uniform("uDiffuseColor", - glm::vec4(dft.r(), dft.g(), dft.b(), static_cast(transparencyValue)))); + uniforms.emplace_back("uDiffuseColor", + glm::vec4(dft.r(), dft.g(), dft.b(), static_cast(transparencyValue))); } - if (isTransparent) uniforms.push_back(SpireSubPass::Uniform("uTransparency", static_cast(transparencyValue))); + if (isTransparent) uniforms.emplace_back("uTransparency", static_cast(transparencyValue)); size_t pointsLeft = data.points_.size(); size_t startOfPass = 0; @@ -149,8 +149,8 @@ void GlyphConstructor::buildObject(GeometryObjectSpire& geom, const std::string& size_t vboSize = static_cast(pointsInThisPass) * numAttributes * sizeof(float); size_t iboSize = static_cast(pointsInThisPass) * sizeof(uint32_t); - std::shared_ptr iboBufferSPtr(new spire::VarBuffer(iboSize)); - std::shared_ptr vboBufferSPtr(new spire::VarBuffer(vboSize)); + auto iboBufferSPtr = std::make_shared(iboSize); + auto vboBufferSPtr = std::make_shared(vboSize); auto iboBuffer = iboBufferSPtr.get(); auto vboBuffer = vboBufferSPtr.get(); diff --git a/src/Interface/Application/ModuleWidget.cc b/src/Interface/Application/ModuleWidget.cc index 3c71c38770..1ad97cd9f1 100644 --- a/src/Interface/Application/ModuleWidget.cc +++ b/src/Interface/Application/ModuleWidget.cc @@ -521,6 +521,22 @@ void ModuleWidget::subnetButtonClicked() void ModuleWidget::setLogButtonColor(const QColor& color) { + const auto incoming = static_cast( + (color == Qt::red) ? LogColorPriority::Error : + (color == Qt::yellow) ? LogColorPriority::Warning : + LogColorPriority::Remark); + + // Only update if the incoming message has strictly higher priority than + // whatever is already shown (fixes #103: remark after error stays red). + int expected = currentLogPriority_.load(); + while (incoming > expected) + { + if (currentLogPriority_.compare_exchange_weak(expected, incoming)) + break; + } + if (incoming <= expected) + return; + if (color == Qt::red) { errored_ = true; @@ -531,6 +547,7 @@ void ModuleWidget::setLogButtonColor(const QColor& color) void ModuleWidget::resetLogButtonColor() { + currentLogPriority_ = static_cast(LogColorPriority::None); fullWidgetDisplay_->setStatusColor(""); } @@ -1092,6 +1109,7 @@ bool ModuleWidget::executeWithSignals() { Q_EMIT signalExecuteButtonIconChangeToStop(); errored_ = false; + currentLogPriority_ = static_cast(LogColorPriority::None); //colorLocked_ = true; //TODO timer_.reset(new SimpleScopedTimer); theModule_->executeWithSignals(); diff --git a/src/Interface/Application/ModuleWidget.h b/src/Interface/Application/ModuleWidget.h index f2d7a62f81..57b950c6bb 100644 --- a/src/Interface/Application/ModuleWidget.h +++ b/src/Interface/Application/ModuleWidget.h @@ -267,6 +267,8 @@ private Q_SLOTS: bool deletedFromGui_, colorLocked_; bool executedOnce_, skipExecuteDueToFatalError_, disabled_, programmablePortEnabled_{false}; std::atomic errored_; + enum class LogColorPriority { None = 0, Remark = 1, Warning = 2, Error = 3 }; + std::atomic currentLogPriority_ { static_cast(LogColorPriority::None) }; int previousPageIndex_ {0}; QDialog* replaceWithDialog_{ nullptr }; diff --git a/src/Interface/Application/NoteEditor.cc b/src/Interface/Application/NoteEditor.cc index c9df5442f4..0fbfae1f7e 100644 --- a/src/Interface/Application/NoteEditor.cc +++ b/src/Interface/Application/NoteEditor.cc @@ -32,6 +32,16 @@ using namespace SCIRun::Gui; +// Applies a character format to all text in the document without +// destroying existing formatting (unlike the setPlainText(toPlainText()) hack). +static void applyFormatToAll(QTextEdit* edit, const QTextCharFormat& format) +{ + QTextCursor cursor = edit->textCursor(); + cursor.select(QTextCursor::Document); + cursor.mergeCharFormat(format); + edit->setTextCursor(cursor); +} + NoteEditor::NoteEditor(const QString& moduleName, bool positionAdjustable, QWidget* parent) : QDialog(parent), moduleName_(moduleName) { setupUi(this); @@ -74,13 +84,13 @@ void NoteEditor::changeFontSize(const QString& text) size = defaultNoteFontSize_; else size = text.toDouble(); - textEdit_->setFontPointSize(size); - textEdit_->setPlainText(textEdit_->toPlainText()); + QTextCharFormat fmt; + fmt.setFontPointSize(size); + applyFormatToAll(textEdit_, fmt); } void NoteEditor::changeTextAlignment(const QString& text) { - //TODO: only changes one line at a time...may just chuck this option Qt::Alignment alignment; if (text == "Left") alignment = Qt::AlignLeft; @@ -90,8 +100,12 @@ void NoteEditor::changeTextAlignment(const QString& text) alignment = Qt::AlignRight; else // text == "Justify") alignment = Qt::AlignJustify; - textEdit_->setAlignment(alignment); - textEdit_->setPlainText(textEdit_->toPlainText()); + QTextCursor cursor = textEdit_->textCursor(); + cursor.select(QTextCursor::Document); + QTextBlockFormat blockFmt; + blockFmt.setAlignment(alignment); + cursor.mergeBlockFormat(blockFmt); + textEdit_->setTextCursor(cursor); } void NoteEditor::changeTextColor() @@ -105,6 +119,13 @@ void NoteEditor::setNoteHtml(const QString& text) { textEdit_->blockSignals(true); textEdit_->setHtml(text); + // Sync color tracking state from the loaded HTML so that Reset Color and + // Cancel work correctly against the actual loaded color, not Qt::white. + QTextCursor cursor = textEdit_->textCursor(); + cursor.movePosition(QTextCursor::Start); + const auto loadedColor = cursor.charFormat().foreground().color(); + if (loadedColor.isValid()) + currentColor_ = previousColor_ = loadedColor; textEdit_->blockSignals(false); } @@ -112,8 +133,9 @@ void NoteEditor::setNoteFontSize(int size) { textEdit_->blockSignals(true); fontSizeComboBox_->blockSignals(true); - textEdit_->setFontPointSize(size); - textEdit_->setPlainText(textEdit_->toPlainText()); + QTextCharFormat fmt; + fmt.setFontPointSize(size); + applyFormatToAll(textEdit_, fmt); int index = fontSizeComboBox_->findText(QString::number(size)); if (index != -1) fontSizeComboBox_->setCurrentIndex(index); @@ -129,9 +151,9 @@ void NoteEditor::setDefaultNoteFontSize(int size) if (fontSizeComboBox_->currentText() == "Default") { textEdit_->blockSignals(true); - - textEdit_->setFontPointSize(size); - textEdit_->setPlainText(textEdit_->toPlainText()); + QTextCharFormat fmt; + fmt.setFontPointSize(size); + applyFormatToAll(textEdit_, fmt); currentNote_.html_ = textEdit_->toHtml(); if (callCount_ > 1) updateNote(); @@ -144,9 +166,9 @@ void NoteEditor::setNoteColor(const QColor& color) { if (color.isValid()) { - previousColor_ = textEdit_->textColor(); - textEdit_->setTextColor(color); - textEdit_->setPlainText(textEdit_->toPlainText()); + QTextCharFormat fmt; + fmt.setForeground(QBrush(color)); + applyFormatToAll(textEdit_, fmt); updateNote(); } else @@ -162,10 +184,12 @@ void NoteEditor::resetText() void NoteEditor::resetTextColor() { - auto oldColor = textEdit_->textColor(); - textEdit_->setTextColor(previousColor_); - textEdit_->setPlainText(textEdit_->toPlainText()); + const auto oldColor = currentColor_; + QTextCharFormat fmt; + fmt.setForeground(QBrush(previousColor_)); + applyFormatToAll(textEdit_, fmt); previousColor_ = currentColor_ = oldColor; + updateNote(); } void NoteEditor::ok() @@ -177,6 +201,7 @@ void NoteEditor::cancel() { textEdit_->setHtml(noteHtmlBackup_); fontSizeComboBox_->setCurrentIndex(fontSizeBackup_); + currentColor_ = previousColor_ = colorBackup_; hide(); } @@ -191,5 +216,6 @@ void NoteEditor::showEvent(QShowEvent* event) { noteHtmlBackup_ = textEdit_->toHtml(); fontSizeBackup_ = fontSizeComboBox_->currentIndex(); + colorBackup_ = currentColor_; QDialog::showEvent(event); } diff --git a/src/Interface/Application/NoteEditor.h b/src/Interface/Application/NoteEditor.h index 56c21f8185..b62cb34efe 100644 --- a/src/Interface/Application/NoteEditor.h +++ b/src/Interface/Application/NoteEditor.h @@ -68,7 +68,7 @@ private Q_SLOTS: Note currentNote_; QString noteHtmlBackup_; int fontSizeBackup_, positionBackup_; - QColor previousColor_, currentColor_; + QColor previousColor_, currentColor_, colorBackup_; NotePosition position_; int defaultNoteFontSize_{ 20 }; int callCount_{ 0 }; diff --git a/src/Interface/Application/SCIRunMainWindow.ui b/src/Interface/Application/SCIRunMainWindow.ui index 635a4a01e8..b93a63310a 100644 --- a/src/Interface/Application/SCIRunMainWindow.ui +++ b/src/Interface/Application/SCIRunMainWindow.ui @@ -359,33 +359,8 @@ Enter a filter string here. The module list below will display only those modules whose name matches the filter (either by exact string or wildcard). - - - - - - - 58 - 35 - - - - - 58 - 35 - - - - Clear filter text - - - Click this button to clear the filter text and see all available modules. - - - Clear - - - false + + true @@ -1361,21 +1336,5 @@ - - clearFilterButton_ - clicked() - moduleFilterLineEdit_ - clear() - - - 243 - 64 - - - 141 - 63 - - - diff --git a/src/Interface/Modules/Base/CMakeLists.txt b/src/Interface/Modules/Base/CMakeLists.txt index 5ed41e5a10..4ba59de5c9 100644 --- a/src/Interface/Modules/Base/CMakeLists.txt +++ b/src/Interface/Modules/Base/CMakeLists.txt @@ -55,6 +55,7 @@ SET(Interface_Modules_Base_HEADERS_M CustomWidgets/QtHistogramWidget.h CustomWidgets/QtHistogramGraph.h CustomWidgets/CodeEditorWidgets.h + CustomWidgets/FileNameLineEdit.h CustomWidgets/CTK/ctkColorPickerButton.h CustomWidgets/CTK/ctkDoubleSpinBox.h CustomWidgets/CTK/ctkDoubleSpinBox_p.h @@ -78,6 +79,7 @@ SET(Interface_Modules_Base_SOURCES CustomWidgets/QtHistogramWidget.cc CustomWidgets/QtHistogramGraph.cc CustomWidgets/CodeEditorWidgets.cc + CustomWidgets/FileNameLineEdit.cc CustomWidgets/CTK/ctkColorPickerButton.cpp CustomWidgets/CTK/ctkDoubleSpinBox.cpp CustomWidgets/CTK/ctkPopupWidget.cpp diff --git a/src/Interface/Modules/Base/CustomWidgets/FileNameLineEdit.cc b/src/Interface/Modules/Base/CustomWidgets/FileNameLineEdit.cc new file mode 100644 index 0000000000..8aa83ced99 --- /dev/null +++ b/src/Interface/Modules/Base/CustomWidgets/FileNameLineEdit.cc @@ -0,0 +1,56 @@ +/* + For more information, please see: http://software.sci.utah.edu + + The MIT License + + Copyright (c) 2020 Scientific Computing and Imaging Institute, + University of Utah. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include + +FileNameLineEdit::FileNameLineEdit(QWidget* parent) + : QLineEdit(parent) +{ + setAcceptDrops(true); +} + +void FileNameLineEdit::dragEnterEvent(QDragEnterEvent* event) +{ + if (event->mimeData()->hasUrls()) + event->acceptProposedAction(); + else + QLineEdit::dragEnterEvent(event); +} + +void FileNameLineEdit::dropEvent(QDropEvent* event) +{ + const auto urls = event->mimeData()->urls(); + if (!urls.isEmpty()) + { + setText(urls.first().toLocalFile()); + Q_EMIT editingFinished(); + } +} diff --git a/src/Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h b/src/Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h new file mode 100644 index 0000000000..3db5246fba --- /dev/null +++ b/src/Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h @@ -0,0 +1,47 @@ +/* + For more information, please see: http://software.sci.utah.edu + + The MIT License + + Copyright (c) 2020 Scientific Computing and Imaging Institute, + University of Utah. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef INTERFACE_MODULES_BASE_CUSTOMWIDGETS_FILENAMELINEEDIT_H +#define INTERFACE_MODULES_BASE_CUSTOMWIDGETS_FILENAMELINEEDIT_H + +#include +#include + +// Note: intentionally in the global namespace so that uic-generated code +// (which cannot qualify custom widget names) can construct this class directly. +class SCISHARE FileNameLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit FileNameLineEdit(QWidget* parent = nullptr); + +protected: + void dragEnterEvent(QDragEnterEvent* event) override; + void dropEvent(QDropEvent* event) override; +}; + +#endif diff --git a/src/Interface/Modules/BrainStimulator/ElectrodeCoilSetupDialog.cc b/src/Interface/Modules/BrainStimulator/ElectrodeCoilSetupDialog.cc index 6360c7d414..9d962c7b3e 100644 --- a/src/Interface/Modules/BrainStimulator/ElectrodeCoilSetupDialog.cc +++ b/src/Interface/Modules/BrainStimulator/ElectrodeCoilSetupDialog.cc @@ -168,19 +168,19 @@ std::vector ElectrodeCoilSetupDialog::validate_numerical_input(int i) int stimtype_ind=((QComboBox *)stimTypeVector_[i])->currentIndex(); static const std::string unknown("???"); - values.push_back(Variable(ElectrodeCoilSetupAlgorithm::columnNames[0], boost::lexical_cast(inputport_ind))); - values.push_back(Variable(Name("Type"), boost::lexical_cast(stimtype_ind))); + values.emplace_back(ElectrodeCoilSetupAlgorithm::columnNames[0], boost::lexical_cast(inputport_ind)); + values.emplace_back(Name("Type"), boost::lexical_cast(stimtype_ind)); for (int j=2; j((electrode_coil_tableWidget->item(i,j)->text()).toStdString()); - values.push_back(Variable(ElectrodeCoilSetupAlgorithm::columnNames[j], electrode_coil_tableWidget->item(i,j)->text().toStdString())); + values.emplace_back(ElectrodeCoilSetupAlgorithm::columnNames[j], electrode_coil_tableWidget->item(i,j)->text().toStdString()); } catch(boost::bad_lexical_cast &) { - values.push_back(Variable(ElectrodeCoilSetupAlgorithm::columnNames[j], unknown)); + values.emplace_back(ElectrodeCoilSetupAlgorithm::columnNames[j], unknown); } } diff --git a/src/Interface/Modules/DataIO/ReadBundleDialog.ui b/src/Interface/Modules/DataIO/ReadBundleDialog.ui index a060cb5d95..bcf9fdd2dc 100644 --- a/src/Interface/Modules/DataIO/ReadBundleDialog.ui +++ b/src/Interface/Modules/DataIO/ReadBundleDialog.ui @@ -43,7 +43,7 @@ - + 0 @@ -101,6 +101,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/ReadColorMapXml.ui b/src/Interface/Modules/DataIO/ReadColorMapXml.ui index df8e78ae9c..311350d0bf 100644 --- a/src/Interface/Modules/DataIO/ReadColorMapXml.ui +++ b/src/Interface/Modules/DataIO/ReadColorMapXml.ui @@ -33,7 +33,7 @@ - + 0 @@ -63,6 +63,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/ReadFieldDialog.ui b/src/Interface/Modules/DataIO/ReadFieldDialog.ui index aa20b2e177..db50cfffeb 100644 --- a/src/Interface/Modules/DataIO/ReadFieldDialog.ui +++ b/src/Interface/Modules/DataIO/ReadFieldDialog.ui @@ -43,7 +43,7 @@ - + 0 @@ -101,6 +101,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/ReadFile.ui b/src/Interface/Modules/DataIO/ReadFile.ui index f394af4a33..2334c3deeb 100644 --- a/src/Interface/Modules/DataIO/ReadFile.ui +++ b/src/Interface/Modules/DataIO/ReadFile.ui @@ -42,7 +42,7 @@ - + 0 @@ -73,6 +73,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/ReadMatrixClassic.ui b/src/Interface/Modules/DataIO/ReadMatrixClassic.ui index 57a44688b4..4bc7571166 100644 --- a/src/Interface/Modules/DataIO/ReadMatrixClassic.ui +++ b/src/Interface/Modules/DataIO/ReadMatrixClassic.ui @@ -43,7 +43,7 @@ - + 0 @@ -101,6 +101,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/ReadNrrd.ui b/src/Interface/Modules/DataIO/ReadNrrd.ui index f513da23fc..8ea2d98d83 100644 --- a/src/Interface/Modules/DataIO/ReadNrrd.ui +++ b/src/Interface/Modules/DataIO/ReadNrrd.ui @@ -42,7 +42,7 @@ - + 0 @@ -73,6 +73,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/WriteBundle.ui b/src/Interface/Modules/DataIO/WriteBundle.ui index 797656feb0..b9540868f6 100644 --- a/src/Interface/Modules/DataIO/WriteBundle.ui +++ b/src/Interface/Modules/DataIO/WriteBundle.ui @@ -33,7 +33,7 @@ - + 0 @@ -63,6 +63,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/WriteFieldDialog.ui b/src/Interface/Modules/DataIO/WriteFieldDialog.ui index d61c5aab55..297cfc1a68 100644 --- a/src/Interface/Modules/DataIO/WriteFieldDialog.ui +++ b/src/Interface/Modules/DataIO/WriteFieldDialog.ui @@ -33,7 +33,7 @@ - + 0 @@ -63,6 +63,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/DataIO/WriteMatrix.ui b/src/Interface/Modules/DataIO/WriteMatrix.ui index f364e2d63b..34f3413bc8 100644 --- a/src/Interface/Modules/DataIO/WriteMatrix.ui +++ b/src/Interface/Modules/DataIO/WriteMatrix.ui @@ -33,7 +33,7 @@ - + 0 @@ -63,6 +63,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/Matlab/ExportFieldsToMatlab.ui b/src/Interface/Modules/Matlab/ExportFieldsToMatlab.ui index 8012d7aacf..2fe7531963 100644 --- a/src/Interface/Modules/Matlab/ExportFieldsToMatlab.ui +++ b/src/Interface/Modules/Matlab/ExportFieldsToMatlab.ui @@ -33,7 +33,7 @@ - + 0 @@ -82,6 +82,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/Matlab/ExportMatricesToMatlab.ui b/src/Interface/Modules/Matlab/ExportMatricesToMatlab.ui index 6188c6ce7f..ccec0c35c3 100644 --- a/src/Interface/Modules/Matlab/ExportMatricesToMatlab.ui +++ b/src/Interface/Modules/Matlab/ExportMatricesToMatlab.ui @@ -33,7 +33,7 @@ - + 0 @@ -82,6 +82,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/Matlab/ImportDatatypesFromMatlab.ui b/src/Interface/Modules/Matlab/ImportDatatypesFromMatlab.ui index 222bd3f01e..a3c7c9048e 100644 --- a/src/Interface/Modules/Matlab/ImportDatatypesFromMatlab.ui +++ b/src/Interface/Modules/Matlab/ImportDatatypesFromMatlab.ui @@ -42,7 +42,7 @@ - + 0 @@ -92,6 +92,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/Matlab/ImportFieldsFromMatlab.ui b/src/Interface/Modules/Matlab/ImportFieldsFromMatlab.ui index 7d7b7a3b48..1cc1a950ab 100644 --- a/src/Interface/Modules/Matlab/ImportFieldsFromMatlab.ui +++ b/src/Interface/Modules/Matlab/ImportFieldsFromMatlab.ui @@ -42,7 +42,7 @@ - + 0 @@ -142,6 +142,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/Matlab/ImportMatricesFromMatlab.ui b/src/Interface/Modules/Matlab/ImportMatricesFromMatlab.ui index 9773e20b5c..86a169f72a 100644 --- a/src/Interface/Modules/Matlab/ImportMatricesFromMatlab.ui +++ b/src/Interface/Modules/Matlab/ImportMatricesFromMatlab.ui @@ -33,7 +33,7 @@ - + 0 @@ -132,6 +132,13 @@ + + + FileNameLineEdit + QLineEdit +
Interface/Modules/Base/CustomWidgets/FileNameLineEdit.h
+
+
diff --git a/src/Interface/Modules/Render/ES/SRInterface.cc b/src/Interface/Modules/Render/ES/SRInterface.cc index 3eac50e9d3..f60f0ef279 100644 --- a/src/Interface/Modules/Render/ES/SRInterface.cc +++ b/src/Interface/Modules/Render/ES/SRInterface.cc @@ -1071,7 +1071,7 @@ glm::vec2 ScreenParams::positionFromClick(int x, int y) const { mSelectedID = entityID; } - mEntityIdMap.insert(std::make_pair(objectName, entityID)); + mEntityIdMap.emplace(objectName, entityID); mCore.addComponent(entityID, trafo); @@ -1164,7 +1164,7 @@ glm::vec2 ScreenParams::positionFromClick(int x, int y) const for (const auto& pass : it->mPasses) { uint64_t entityID = getEntityIDForName(pass.passName, it->mPort); - mEntityIdMap.insert(std::make_pair(it->mName, entityID)); + mEntityIdMap.emplace(it->mName, entityID); } ++it; } diff --git a/src/Interface/Modules/Render/ViewScene.cc b/src/Interface/Modules/Render/ViewScene.cc index 5942e9ec13..067b96852b 100644 --- a/src/Interface/Modules/Render/ViewScene.cc +++ b/src/Interface/Modules/Render/ViewScene.cc @@ -2499,8 +2499,8 @@ GeometryHandle ViewSceneDialog::buildGeometryScaleBar() uint32_t iboSize = sizeof(uint32_t) * static_cast(indices.size()); uint32_t vboSize = sizeof(float) * 3 * static_cast(points.size()); - std::shared_ptr iboBufferSPtr(new spire::VarBuffer(vboSize)); - std::shared_ptr vboBufferSPtr(new spire::VarBuffer(iboSize)); + auto iboBufferSPtr = std::make_shared(vboSize); + auto vboBufferSPtr = std::make_shared(iboSize); auto* iboBuffer = iboBufferSPtr.get(); auto* vboBuffer = vboBufferSPtr.get(); diff --git a/src/Modules/Legacy/Fields/BuildPointCloudToLatVolMappingMatrix.cc b/src/Modules/Legacy/Fields/BuildPointCloudToLatVolMappingMatrix.cc index b7be183c39..085098612e 100644 --- a/src/Modules/Legacy/Fields/BuildPointCloudToLatVolMappingMatrix.cc +++ b/src/Modules/Legacy/Fields/BuildPointCloudToLatVolMappingMatrix.cc @@ -163,7 +163,7 @@ BuildPointCloudToLatVolMappingMatrix::execute() if (d > 0.0) { // Insert it and increase the normalization total - point2dist.insert(std::make_pair((*pcmn).index_, d)); + point2dist.emplace((*pcmn).index_, d); total += d; } // Next PCMeshNode please diff --git a/src/Modules/Visualization/ShowColorMapModule.cc b/src/Modules/Visualization/ShowColorMapModule.cc index e0be272960..33fae2f946 100644 --- a/src/Modules/Visualization/ShowColorMapModule.cc +++ b/src/Modules/Visualization/ShowColorMapModule.cc @@ -117,10 +117,8 @@ GeometryBaseHandle ShowColorMap::buildGeometryObject(ColorMapHandle cm, ModuleSt uint32_t iboSize = sizeof(uint32_t) * static_cast(indices.size()); uint32_t vboSize = sizeof(float) * 7 * static_cast(points.size()); - std::shared_ptr iboBufferSPtr( - new spire::VarBuffer(iboSize)); - std::shared_ptr vboBufferSPtr( - new spire::VarBuffer(vboSize)); + auto iboBufferSPtr = std::make_shared(iboSize); + auto vboBufferSPtr = std::make_shared(vboSize); spire::VarBuffer* iboBuffer = iboBufferSPtr.get(); spire::VarBuffer* vboBuffer = vboBufferSPtr.get(); @@ -165,14 +163,14 @@ GeometryBaseHandle ShowColorMap::buildGeometryObject(ColorMapHandle cm, ModuleSt // Construct VBO. std::string shader = "Shaders/ColorMapLegend"; std::vector attribs; - attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float))); - attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float))); + attribs.emplace_back("aPos", 3 * sizeof(float)); + attribs.emplace_back("aColor", 4 * sizeof(float)); std::vector uniforms; - uniforms.push_back(SpireSubPass::Uniform("uXTranslate",static_cast(xTrans))); - uniforms.push_back(SpireSubPass::Uniform("uYTranslate",static_cast(yTrans))); - uniforms.push_back(SpireSubPass::Uniform("uDisplaySide", static_cast(displaySide))); + uniforms.emplace_back("uXTranslate",static_cast(xTrans)); + uniforms.emplace_back("uYTranslate",static_cast(yTrans)); + uniforms.emplace_back("uDisplaySide", static_cast(displaySide)); int displayLength = state->getValue(DisplayLength).toInt(); - uniforms.push_back(SpireSubPass::Uniform("uDisplayLength", static_cast(displayLength))); + uniforms.emplace_back("uDisplayLength", static_cast(displayLength)); auto geomVBO = SpireVBO(vboName, attribs, vboBufferSPtr, numVBOElements, BBox(Point{}, Point{}), true); diff --git a/src/Modules/Visualization/ShowField.cc b/src/Modules/Visualization/ShowField.cc index 990430361a..4b0fd3e05b 100644 --- a/src/Modules/Visualization/ShowField.cc +++ b/src/Modules/Visualization/ShowField.cc @@ -570,8 +570,8 @@ void GeometryBuilder::renderFacesLinear( // Three 32 bit ints for each triangle to index into the VBO (triangles = verticies - 2) size_t iboSize = static_cast(facesLeftInThisPass * sizeof(uint32_t) * (numNodesPerFace - 2) * 3); size_t vboSize = static_cast(facesLeftInThisPass * sizeof(float) * numNodesPerFace * numAttributes); - std::shared_ptr iboBufferSPtr(new spire::VarBuffer(iboSize)); - std::shared_ptr vboBufferSPtr(new spire::VarBuffer(vboSize)); + auto iboBufferSPtr = std::make_shared(iboSize); + auto vboBufferSPtr = std::make_shared(vboSize); auto iboBuffer = iboBufferSPtr.get(); auto vboBuffer = vboBufferSPtr.get(); @@ -767,24 +767,24 @@ void GeometryBuilder::renderFacesLinear( std::vector attribs; std::vector uniforms; - attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float))); - uniforms.push_back(SpireSubPass::Uniform("uUseClippingPlanes", true)); - uniforms.push_back(SpireSubPass::Uniform("uUseFog", true)); - uniforms.push_back(SpireSubPass::Uniform("uTransparency", faceTransparencyValue_)); + attribs.emplace_back("aPos", 3 * sizeof(float)); + uniforms.emplace_back("uUseClippingPlanes", true); + uniforms.emplace_back("uUseFog", true); + uniforms.emplace_back("uTransparency", faceTransparencyValue_); if (useNormals) { - attribs.push_back(SpireVBO::AttributeData("aNormal", 3 * sizeof(float))); - uniforms.push_back(SpireSubPass::Uniform("uAmbientColor", glm::vec4(0.1f, 0.1f, 0.1f, 1.0f))); - uniforms.push_back(SpireSubPass::Uniform("uSpecularColor", glm::vec4(0.1f, 0.1f, 0.1f, 0.1f))); - uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f)); + attribs.emplace_back("aNormal", 3 * sizeof(float)); + uniforms.emplace_back("uAmbientColor", glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)); + uniforms.emplace_back("uSpecularColor", glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)); + uniforms.emplace_back("uSpecularPower", 32.0f); } SpireTexture2D texture; if (useColorMap) { shader += "_ColorMap"; - attribs.push_back(SpireVBO::AttributeData("aTexCoords", 2 * sizeof(float))); + attribs.emplace_back("aTexCoords", 2 * sizeof(float)); const static int colorMapResolution = 256; for(int i = 0; i < colorMapResolution; ++i) @@ -801,8 +801,8 @@ void GeometryBuilder::renderFacesLinear( } else { - uniforms.push_back(SpireSubPass::Uniform("uDiffuseColor", - glm::vec4(state.defaultColor.r(), state.defaultColor.g(), state.defaultColor.b(), 1.0f))); + uniforms.emplace_back("uDiffuseColor", + glm::vec4(state.defaultColor.r(), state.defaultColor.g(), state.defaultColor.b(), 1.0f)); } //numVBOElements is only used in dead code and should be removed which is why its hard coded to 0 diff --git a/src/Modules/Visualization/ShowString.cc b/src/Modules/Visualization/ShowString.cc index 106cc66213..392cf8bc98 100644 --- a/src/Modules/Visualization/ShowString.cc +++ b/src/Modules/Visualization/ShowString.cc @@ -133,8 +133,8 @@ std::tuple ShowString::getTextPosition() // TODO: clean up duplication here and in ShowColorMap GeometryBaseHandle ShowString::buildGeometryObject(const std::string& text) { - std::shared_ptr iboBufferSPtr(new spire::VarBuffer(0)); - std::shared_ptr vboBufferSPtr(new spire::VarBuffer(0)); + auto iboBufferSPtr = std::make_shared(0); + auto vboBufferSPtr = std::make_shared(0); auto uniqueNodeID = id().id_ + "_showString_" + text; auto vboName = uniqueNodeID + "VBO"; @@ -144,15 +144,15 @@ GeometryBaseHandle ShowString::buildGeometryObject(const std::string& text) // Construct VBO. std::string shader = "Shaders/ColorMapLegend"; std::vector attribs; - attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float))); - attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float))); + attribs.emplace_back("aPos", 3 * sizeof(float)); + attribs.emplace_back("aColor", 4 * sizeof(float)); std::vector uniforms; double xTrans, yTrans; std::tie(xTrans, yTrans) = getTextPosition(); - uniforms.push_back(SpireSubPass::Uniform("uXTranslate", xTrans)); - uniforms.push_back(SpireSubPass::Uniform("uYTranslate", yTrans)); + uniforms.emplace_back("uXTranslate", xTrans); + uniforms.emplace_back("uYTranslate", yTrans); SpireVBO geomVBO(vboName, attribs, vboBufferSPtr, 0, BBox(Point{}, Point{}), true); SpireIBO geomIBO(iboName, SpireIBO::PRIMITIVE::TRIANGLES, sizeof(uint32_t), iboBufferSPtr); diff --git a/src/Modules/Visualization/TextBuilder.cc b/src/Modules/Visualization/TextBuilder.cc index ef5307b116..c0042d2f34 100644 --- a/src/Modules/Visualization/TextBuilder.cc +++ b/src/Modules/Visualization/TextBuilder.cc @@ -203,10 +203,8 @@ void TextBuilder::printString(const std::string& oneline, uint32_t iboSize = sizeof(uint32_t) * static_cast(indices.size()); uint32_t vboSize = sizeof(float) * 5 * static_cast(points.size()); - std::shared_ptr iboBufferSPtr2( - new spire::VarBuffer(vboSize)); - std::shared_ptr vboBufferSPtr2( - new spire::VarBuffer(iboSize)); + auto iboBufferSPtr2 = std::make_shared(vboSize); + auto vboBufferSPtr2 = std::make_shared(iboSize); spire::VarBuffer* iboBuffer2 = iboBufferSPtr2.get(); spire::VarBuffer* vboBuffer2 = vboBufferSPtr2.get(); @@ -230,11 +228,11 @@ void TextBuilder::printString(const std::string& oneline, // Construct VBO. std::string shader = "Shaders/TextBuilder"; std::vector attribs; - attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float))); - attribs.push_back(SpireVBO::AttributeData("aTexCoord", 2 * sizeof(float))); + attribs.emplace_back("aPos", 3 * sizeof(float)); + attribs.emplace_back("aTexCoord", 2 * sizeof(float)); std::vector uniforms; - uniforms.push_back(SpireSubPass::Uniform("uTrans", glm::vec4(startNrmSpc.x(), startNrmSpc.y(), 0.0, 0.0))); - uniforms.push_back(SpireSubPass::Uniform("uColor", color_)); + uniforms.emplace_back("uTrans", glm::vec4(startNrmSpc.x(), startNrmSpc.y(), 0.0, 0.0)); + uniforms.emplace_back("uColor", color_); auto geomVBO = SpireVBO(vboName, attribs, vboBufferSPtr2, numVBOElements, BBox(Point{}, Point{}), true);