From a8b12b1d5e2c8cebec12bd550d622f99d7728188 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sun, 29 Dec 2024 16:48:00 +0100 Subject: [PATCH 01/35] from now on fix addon release number to same as Mosaic --- src/ofxVPConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ofxVPConfig.h b/src/ofxVPConfig.h index 629bfae7..0ff3fb7f 100644 --- a/src/ofxVPConfig.h +++ b/src/ofxVPConfig.h @@ -33,7 +33,7 @@ #pragma once #define PACKAGE_OFXVP "ofxVisualProgramming" -#define VERSION_OFXVP "0.1.0" +#define VERSION_OFXVP "0.7.2" #define DESCRIPTION_OFXVP "A visual programming patching environment for OF" From c2897641dd506daf7f9a4ee9cffa962e1d84cfbb Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Wed, 1 Jan 2025 19:06:52 +0100 Subject: [PATCH 02/35] now graphical canvas drag&zoom managed from imgui --- addon_config.mk | 2 +- src/core/imgui_helpers.h | 4 +- src/core/imgui_node_canvas.cpp | 81 ++++++++++++++- src/core/imgui_node_canvas.h | 99 ++++++++++++++++--- src/objects/audio_analysis/AudioAnalyzer.cpp | 8 +- src/objects/audio_analysis/BPMExtractor.cpp | 2 +- src/objects/audio_analysis/FftExtractor.cpp | 2 +- .../audio_analysis/MelBandsExtractor.cpp | 2 +- src/objects/audio_analysis/PitchExtractor.cpp | 2 +- src/objects/audio_analysis/RMSExtractor.cpp | 2 +- src/objects/communications/ArduinoSerial.cpp | 15 ++- src/objects/communications/KeyPressed.cpp | 2 +- src/objects/communications/KeyReleased.cpp | 2 +- src/objects/communications/MidiKey.cpp | 2 +- src/objects/communications/MidiKnob.cpp | 7 +- src/objects/communications/MidiPad.cpp | 2 +- src/objects/communications/MidiReceiver.cpp | 2 + src/objects/communications/MidiSender.cpp | 2 + src/objects/communications/OscReceiver.cpp | 3 +- .../computer_vision/BackgroundSubtraction.cpp | 5 +- src/objects/computer_vision/ColorTracking.cpp | 5 +- src/objects/computer_vision/HaarTracking.cpp | 5 +- .../computer_vision/MotionDetection.cpp | 2 +- src/objects/computer_vision/OpticalFlow.cpp | 5 +- src/objects/data/BangMultiplexer.cpp | 2 +- src/objects/data/BangToFloat.cpp | 2 +- src/objects/data/DataToFile.cpp | 11 ++- src/objects/data/DataToTexture.cpp | 5 +- src/objects/data/FileToData.cpp | 2 +- src/objects/data/FloatMultiplexer.cpp | 2 +- src/objects/data/FloatsToVector.cpp | 2 +- src/objects/data/Receiver.cpp | 2 +- src/objects/data/Sender.cpp | 2 +- src/objects/data/TextureToData.cpp | 5 +- src/objects/data/VectorAt.cpp | 2 +- src/objects/data/VectorConcat.cpp | 8 +- src/objects/data/VectorExtract.cpp | 4 +- src/objects/data/VectorGate.cpp | 6 +- src/objects/data/VectorOperator.cpp | 2 +- src/objects/graphics/ColorPalette.cpp | 9 +- src/objects/graphics/ImageExporter.cpp | 5 +- src/objects/graphics/ImageLoader.cpp | 5 +- src/objects/gui/mo2DPad.cpp | 2 +- src/objects/gui/moDataViewer.cpp | 2 +- src/objects/gui/moMessage.cpp | 4 +- src/objects/gui/moMultiSlider.cpp | 7 +- src/objects/gui/moMultiToggle.cpp | 5 +- src/objects/gui/moPlayerControls.cpp | 6 +- src/objects/gui/moSignalViewer.cpp | 6 +- src/objects/gui/moSlider.cpp | 2 +- src/objects/gui/moSonogram.cpp | 5 +- src/objects/gui/moTimeline.cpp | 2 +- src/objects/gui/moValuePlotter.cpp | 4 +- src/objects/gui/moVideoViewer.cpp | 6 +- src/objects/logic/BooleanOperator.cpp | 9 +- src/objects/logic/Conditional.cpp | 2 +- src/objects/logic/Counter.cpp | 4 +- src/objects/logic/DelayFloat.cpp | 4 +- src/objects/logic/Gate.cpp | 6 +- src/objects/logic/LoadBang.cpp | 2 +- src/objects/logic/Spigot.cpp | 2 +- src/objects/logic/TimedSemaphore.cpp | 53 ++++++---- src/objects/logic/TimedSemaphore.h | 4 + src/objects/math/Clamp.cpp | 2 +- src/objects/math/Constant.cpp | 2 +- src/objects/math/CosineGenerator.cpp | 2 +- src/objects/math/Map.cpp | 12 +-- src/objects/math/Metronome.cpp | 12 ++- src/objects/math/NumberOperator.cpp | 2 +- src/objects/math/SimpleNoise.cpp | 2 +- src/objects/math/SimpleRandom.cpp | 2 +- src/objects/math/SineGenerator.cpp | 2 +- src/objects/math/Smooth.cpp | 2 +- src/objects/scripting/LuaScript.cpp | 8 +- src/objects/scripting/ShaderObject.cpp | 8 +- src/objects/sound/AudioExporter.cpp | 15 +-- src/objects/sound/AudioGate.cpp | 6 +- src/objects/sound/Crossfader.cpp | 3 +- src/objects/sound/Mixer.cpp | 16 +-- src/objects/sound/Oscillator.cpp | 20 ++-- src/objects/sound/Panner.cpp | 6 +- src/objects/sound/QuadPanner.cpp | 2 +- src/objects/sound/SamplePlayer.cpp | 2 +- src/objects/sound/SigMult.cpp | 2 +- src/objects/sound/SignalOperator.cpp | 2 +- src/objects/sound/SoundfilePlayer.cpp | 2 +- src/objects/sound/pdspADSR.cpp | 8 +- src/objects/sound/pdspAHR.cpp | 6 +- src/objects/sound/pdspBitCruncher.cpp | 2 +- src/objects/sound/pdspBitNoise.cpp | 12 +-- src/objects/sound/pdspChorusEffect.cpp | 12 +-- src/objects/sound/pdspCombFilter.cpp | 12 +-- src/objects/sound/pdspCompressor.cpp | 10 +- src/objects/sound/pdspDataOscillator.cpp | 4 +- src/objects/sound/pdspDecimator.cpp | 2 +- src/objects/sound/pdspDelay.cpp | 12 +-- src/objects/sound/pdspDucker.cpp | 8 +- src/objects/sound/pdspHiCut.cpp | 2 +- src/objects/sound/pdspKick.cpp | 28 +++--- src/objects/sound/pdspLFO.cpp | 8 +- src/objects/sound/pdspLowCut.cpp | 2 +- src/objects/sound/pdspParametricEQ.cpp | 6 +- src/objects/sound/pdspResonant2PoleFilter.cpp | 12 +-- src/objects/sound/pdspReverb.cpp | 12 +-- src/objects/sound/pdspSequencer.cpp | 12 +-- src/objects/string/StringAt.cpp | 2 +- src/objects/string/StringConcat.cpp | 8 +- src/objects/string/StringExtract.cpp | 4 +- src/objects/string/StringGate.cpp | 6 +- src/objects/string/StringMultiplexer.cpp | 2 +- src/objects/video/KinectGrabber.cpp | 5 +- src/objects/video/ToGrayScaleTexture.cpp | 5 +- src/objects/video/VideoCrop.cpp | 5 +- src/objects/video/VideoDelay.cpp | 5 +- src/objects/video/VideoExporter.cpp | 16 ++- src/objects/video/VideoGate.cpp | 6 +- src/objects/video/VideoGrabber.cpp | 4 +- src/objects/video/VideoMixer.cpp | 5 +- src/objects/video/VideoPlayer.cpp | 7 +- src/objects/video/VideoStreaming.cpp | 14 ++- src/objects/video/VideoTimelapse.cpp | 5 +- src/objects/video/VideoTransform.cpp | 5 +- src/objects/windowing/LivePatching.cpp | 5 +- src/objects/windowing/OutputWindow.cpp | 5 +- src/objects/windowing/ProjectionMapping.cpp | 5 +- src/ofxVPConfig.h | 4 + src/ofxVisualProgramming.cpp | 47 ++------- src/ofxVisualProgramming.h | 3 - src/utils.h | 22 +++-- 129 files changed, 531 insertions(+), 442 deletions(-) diff --git a/addon_config.mk b/addon_config.mk index 535ea2de..75fe4814 100644 --- a/addon_config.mk +++ b/addon_config.mk @@ -26,7 +26,7 @@ common: # or use += in several lines ADDON_DEPENDENCIES = ofxKinect ofxOpenCv ofxOsc ofxXmlSettings ADDON_DEPENDENCIES += ofxAudioFile ofxBTrack ofxCv ofxEasing ofxFFmpegRecorder ofxFft - ADDON_DEPENDENCIES += ofxJSON ofxImGui ofxInfiniteCanvas ofxLua ofxMidi ofxMtlMapping2D + ADDON_DEPENDENCIES += ofxJSON ofxImGui ofxLua ofxMidi ofxMtlMapping2D ADDON_DEPENDENCIES += ofxOpenDHT ofxPd ofxPDSP ofxTimeline ofxWarp # include search paths, this will be usually parsed from the file system diff --git a/src/core/imgui_helpers.h b/src/core/imgui_helpers.h index 84621b2f..34dec138 100644 --- a/src/core/imgui_helpers.h +++ b/src/core/imgui_helpers.h @@ -153,10 +153,10 @@ inline void drawWaveform(ImDrawList* drawList, ImVec2 dim, float* data, int data } //-------------------------------------------------------------- -inline void plotValue(float value, float min, float max, ImU32 color=IM_COL32(255,255,255,255), float retinaScale=1.0f){ +inline void plotValue(float value, float min, float max, ImU32 color=IM_COL32(255,255,255,255), float height=OBJECT_STANDARD_HEIGHT, float scale=1.0f){ ImGuiEx::PlotVarConfig conf; conf.value = value; - conf.frame_size = ImVec2(ImGui::GetWindowSize().x - 20, ImGui::GetWindowSize().y - ((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*retinaScale)); + conf.frame_size = ImVec2(ImGui::GetWindowSize().x - (20*scale), height); conf.scale.min = min; conf.scale.max = max; conf.buffer_size = 256; diff --git a/src/core/imgui_node_canvas.cpp b/src/core/imgui_node_canvas.cpp index 11d260b3..7d01fd7f 100644 --- a/src/core/imgui_node_canvas.cpp +++ b/src/core/imgui_node_canvas.cpp @@ -247,6 +247,79 @@ void ImGuiEx::NodeCanvas::End(){ canvasDrawList = nullptr; } +void ImGuiEx::NodeCanvas::Update(){ + UpdateCanvasRect(); + UpdateCanvasScrollZoom(); + UpdateCanvasGrid(ImGui::GetWindowDrawList()); +} + +void ImGuiEx::NodeCanvas::UpdateCanvasRect(){ + canvasView.mousePos = ImGui::GetMousePos(); + canvasView.position = ImGui::GetWindowPos(); + canvasView.size = ImGui::GetContentRegionAvail(); + canvasView.rectCanvas = ImRect(canvasView.position, canvasView.position + canvasView.size); +} + +void ImGuiEx::NodeCanvas::UpdateCanvasScrollZoom(){ + const ImGuiIO& io = ImGui::GetIO(); + bool dragCond = canvasView.state == ImGuiExCanvasState::DragingInput || canvasView.state == ImGuiExCanvasState::DragingOutput; + if (canvasView.state != ImGuiExCanvasState::None && (ImGui::IsMouseDown(0) == false || dragCond) && canvasView.rectCanvas.Contains(canvasView.mousePos)) + { + if (ImGui::IsMouseDragging(1)) + { + canvasView.scroll += io.MouseDelta; + } + ImVec2 focus = (canvasView.mousePos - canvasView.scroll - canvasView.position) / canvasView.scale; + auto zoom = static_cast(io.MouseWheel); + if (zoom < 0) + { + while (zoom < 0) + { + canvasView.scale = ImMax(canvasView.scaleMin, canvasView.scale - canvasView.deltaScale); + zoom += 1; + } + } + if (zoom > 0) + { + while (zoom > 0) + { + canvasView.scale = ImMin(canvasView.scaleMax, canvasView.scale + canvasView.deltaScale); + zoom -= 1; + } + } + if (ImGui::IsMouseClicked(2)) + { + canvasView.scale = 1.0f; + } + ImVec2 shift = canvasView.scroll + (focus * canvasView.scale); + canvasView.scroll += canvasView.mousePos - shift - canvasView.position; + } + + canvasView.translation = canvasView.scroll; +} + +void ImGuiEx::NodeCanvas::UpdateCanvasGrid(ImDrawList* drawList) const{ + const float grid = 32.0f * canvasView.scale; + float x = std::fmod(canvasView.scroll.x, grid); + float y = std::fmod(canvasView.scroll.y, grid); + auto markX = static_cast(canvasView.scroll.x / grid); + auto markY = static_cast(canvasView.scroll.y / grid); + while (x < canvasView.size.x) + { + ImColor color = markX % 5 ? ImColor(0.5f, 0.5f, 0.5f, 0.05f) : ImColor(1.0f, 1.0f, 1.0f, 0.05f); + drawList->AddLine(ImVec2(x, 0.0f) + canvasView.position, ImVec2(x, canvasView.size.y) + canvasView.position, color, 0.1f); + x += grid; + markX -= 1; + } + while (y < canvasView.size.y) + { + ImColor color = markY % 5 ? ImColor(0.5f, 0.5f, 0.5f, 0.05f) : ImColor(1.0f, 1.0f, 1.0f, 0.05f); + drawList->AddLine(ImVec2(0.0f, y) + canvasView.position, ImVec2(canvasView.size.x, y) + canvasView.position, color, 0.1f); + y += grid; + markY -= 1; + } +} + void ImGuiEx::NodeCanvas::DrawFrameBorder(const bool& _drawOnForeground) const { // Only use between NodeCanvas::Begin() and End(). IM_ASSERT(isDrawingCanvas == true); // forgot to Begin(); @@ -285,15 +358,17 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name, curNodeData.zoomName = ImGuiExNodeZoom_Invisible; //return false; }else{ - unsigned int curWidth = curNodeData.outerContentBox.GetSize().x; - if( curWidth < IMGUI_EX_NODE_MIN_WIDTH_SMALL ) + //unsigned int curWidth = curNodeData.outerContentBox.GetSize().x; + /*if( curWidth < IMGUI_EX_NODE_MIN_WIDTH_SMALL ) curNodeData.zoomName = ImGuiExNodeZoom_Imploded; else if( curWidth < IMGUI_EX_NODE_MIN_WIDTH_NORMAL ) curNodeData.zoomName = ImGuiExNodeZoom_Small; else if( curWidth < IMGUI_EX_NODE_MIN_WIDTH_LARGE ) curNodeData.zoomName = ImGuiExNodeZoom_Normal; else - curNodeData.zoomName = ImGuiExNodeZoom_Large; + curNodeData.zoomName = ImGuiExNodeZoom_Large;*/ + + curNodeData.zoomName = ImGuiExNodeZoom_Normal; } curNodeData.viewName = ImGuiExNodeView_None; diff --git a/src/core/imgui_node_canvas.h b/src/core/imgui_node_canvas.h index b55c797b..c00a4b1e 100644 --- a/src/core/imgui_node_canvas.h +++ b/src/core/imgui_node_canvas.h @@ -49,11 +49,13 @@ # define __IMGUI_EX_NODECANVAS_DEBUG__ 0 // enable for debugging layout # pragma once -# include -# include // Access to more advanced ImGui variables. +#include +#include // Access to more advanced ImGui variables. #include +#include "ofxVPConfig.h" + // Default values. You can override them in imconfig.h // Everything below is in screen pixels, actual size, non scaled. # define IMGUI_EX_NODE_MIN_WIDTH 160 // Minimum width. Items cannot be smaller. @@ -118,15 +120,49 @@ enum ImGuiExNodeView_ { ImGuiExNodeView_Any = ImGuiExNodeView_Params | ImGuiExNodeView_Visualise | ImGuiExNodeView_Info }; +enum class ImGuiExCanvasState +{ + None = 0, + Default, + HoveringNode, + HoveringInput, + HoveringOutput, + Draging, + DragingInput, + DragingOutput, + Selecting +}; + // extend ImGui in ImGuiEx namespace namespace ImGuiEx { + + // Defines Canvas View data struct NodeCanvasView { + bool mNodeDrag = false; // For node drag modification. + bool modifFlag = false; // Modification flag. + + ImGuiExCanvasState state = ImGuiExCanvasState::Default; + ImVec2 translation = ImVec2(0,0); float scale = 1.0f; - //ImRect contentRect = ImRect(ImVec2(0,0), ImVec2(0,0)); - //ImRect screenRect = ImRect(ImVec2(0,0), ImVec2(100,100)); + const float scaleMin = CANVAS_MIN_SCALE; + const float scaleMax = CANVAS_MAX_SCALE; + const float deltaScale = 0.05f; + + ImVec2 position; + ImVec2 size; + ImVec2 scroll; + ImVec2 mousePos; + + ImRect rectCanvas; + + bool draggingOutOfCanvas = false; + ImVec2 distFromClickToCenter; + ImVec2 clickPosAtTheEdge; + + ImRect rectSelecting; NodeCanvasView() = default; NodeCanvasView(const ImVec2& _offset, float _scale) : @@ -137,6 +173,7 @@ struct NodeCanvasView { translation = ImFloor(_offset); scale = _scale; } + }; // Layout for pins data @@ -189,14 +226,6 @@ struct NodeLayoutData { } }; -struct ofxVPLinkData{ - int _fromObjectID; - int _fromPinID; - int _linkID; - std::string _linkLabel; - ImVec2 _toPinPosition; -}; - struct NodeConnectData{ int connectType; // 1 connect, 2 disconnect, 3 re-connect int linkID; @@ -206,16 +235,48 @@ struct NodeConnectData{ int toInletPinID; }; +struct NodeFlag { + NodeFlag() = delete; + static const unsigned int Default = 0; + static const unsigned int Visible = 1 << 0; + static const unsigned int Hovered = 1 << 1; + static const unsigned int Selected = 1 << 2; + static const unsigned int Collapsed = 1 << 3; + static const unsigned int Disabled = 1 << 4; + static const unsigned int Highlighted = 1 << 5; +}; + +enum class ofxVPLinkPosition +{ + NONE, + LINK_RIGHT, + LINK_LEFT_OVER, + LINK_LEFT_UNDER, + LINK_LEFT_MID +}; + +struct ofxVPLinkData{ + int _fromObjectID; + int _fromPinID; + int _linkID; + std::string _linkLabel; + ImVec2 _toPinPosition; +}; struct NodeCanvas { // Setup a drawing canvas space // Uses ImGui available space except if over-ridden with SetNextWindowPos and Size. - bool Begin(const char* _id ); + bool Begin( const char* _id ); // Must be called only when Begin() returned true. void End(); + void Update(); + void UpdateCanvasRect(); + void UpdateCanvasScrollZoom(); + void UpdateCanvasGrid(ImDrawList* drawList) const; + // Draws the frame border void DrawFrameBorder(const bool& _drawOnForeground=true) const; @@ -268,9 +329,13 @@ struct NodeCanvas { // Returns origin of the view. const ImVec2& GetCanvasTranslation() const { return canvasView.translation; } + void SetCanvasTranslation(ImVec2 t) { canvasView.scroll = t; } + // Returns scale of the view. float GetCanvasScale() const { return canvasView.scale; } + void resetCanvas() { canvasView.scroll = ImVec2(0,0); canvasView.scale = 1.0f; } + // Returns data about the current node. // Useful inside: scale, niewName, scaleName, etc. const NodeLayoutData& GetNodeData() const { @@ -319,9 +384,6 @@ struct NodeCanvas { ImGuiContext* getContext() { return context; } private: -// void pushNodeWorkRect(); -// void popNodeWorkRect(); -// ImRect canvasWorkRectBackup; // context ImGuiContext* context; @@ -340,6 +402,11 @@ struct NodeCanvas { ImDrawList* canvasDrawList = nullptr; ImDrawList* nodeDrawList = nullptr; + // Dragging + bool draggingOutOfCanvas = false; + ImVec2 distFromClickToCenter; + ImVec2 clickPosAtTheEdge; + // Patch Control data std::map> inletPinsPositions; std::map> outletPinsPositions; diff --git a/src/objects/audio_analysis/AudioAnalyzer.cpp b/src/objects/audio_analysis/AudioAnalyzer.cpp index 06ad6d41..97abc0c0 100644 --- a/src/objects/audio_analysis/AudioAnalyzer.cpp +++ b/src/objects/audio_analysis/AudioAnalyzer.cpp @@ -196,10 +196,10 @@ void AudioAnalyzer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ // draw waveform - ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y*0.5f), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); + ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImVec2(ImGui::GetWindowSize().x,this->height*0.5f*_nodeCanvas.GetCanvasScale()), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); // draw signal RMS amplitude - _nodeCanvas.getNodeDrawList()->AddRectFilled(ImGui::GetWindowPos()+ImVec2(0,ImGui::GetWindowSize().y*0.5f),ImGui::GetWindowPos()+ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y *0.5f * (1.0f - ofClamp(static_cast(_inletParams[0])->getRMSAmplitude()*audioInputLevel,0.0,1.0))),IM_COL32(255,255,120,12)); + _nodeCanvas.getNodeDrawList()->AddRectFilled(ImGui::GetWindowPos()+ImVec2(0,this->height*0.5f*_nodeCanvas.GetCanvasScale()),ImGui::GetWindowPos()+ImVec2(ImGui::GetWindowSize().x,this->height*0.5f*_nodeCanvas.GetCanvasScale() * (1.0f - ofClamp(static_cast(_inletParams[0])->getRMSAmplitude()*audioInputLevel,0.0,1.0))),IM_COL32(255,255,120,12)); ImGui::Spacing(); ImGui::Spacing(); @@ -209,12 +209,12 @@ void AudioAnalyzer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Spacing(); ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if (ImGuiKnobs::Knob("level", &audioInputLevel, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)) { + if (ImGuiKnobs::Knob("level", &audioInputLevel, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*scaleFactor)) { this->setCustomVar(static_cast(audioInputLevel),"INPUT_LEVEL"); } ImGui::SameLine(); - if (ImGuiKnobs::Knob("smooth", &smoothingValue, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)) { + if (ImGuiKnobs::Knob("smooth", &smoothingValue, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*scaleFactor)) { this->setCustomVar(static_cast(smoothingValue),"SMOOTHING"); } diff --git a/src/objects/audio_analysis/BPMExtractor.cpp b/src/objects/audio_analysis/BPMExtractor.cpp index ece5e5b3..c46bde3f 100755 --- a/src/objects/audio_analysis/BPMExtractor.cpp +++ b/src/objects/audio_analysis/BPMExtractor.cpp @@ -159,7 +159,7 @@ void BPMExtractor::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); ImVec2 pos = ImVec2(window_pos.x + window_size.x - (50*scaleFactor), window_pos.y + window_size.y/2); char temp[32]; diff --git a/src/objects/audio_analysis/FftExtractor.cpp b/src/objects/audio_analysis/FftExtractor.cpp index 9c337f4e..ab680db7 100755 --- a/src/objects/audio_analysis/FftExtractor.cpp +++ b/src/objects/audio_analysis/FftExtractor.cpp @@ -169,7 +169,7 @@ void FftExtractor::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ // draw FFT - ImGuiEx::PlotBands(_nodeCanvas.getNodeDrawList(), 0, ImGui::GetWindowSize().y - 26, static_cast *>(_outletParams[0])); + ImGuiEx::PlotBands(_nodeCanvas.getNodeDrawList(), 0, (this->height*_nodeCanvas.GetCanvasScale()) - (26*this->scaleFactor), static_cast *>(_outletParams[0])); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/audio_analysis/MelBandsExtractor.cpp b/src/objects/audio_analysis/MelBandsExtractor.cpp index 3d2f910f..74b2a6e3 100755 --- a/src/objects/audio_analysis/MelBandsExtractor.cpp +++ b/src/objects/audio_analysis/MelBandsExtractor.cpp @@ -155,7 +155,7 @@ void MelBandsExtractor::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ // draw MEL BANDS - ImGuiEx::PlotBands(_nodeCanvas.getNodeDrawList(), 0, ImGui::GetWindowSize().y - 26, static_cast *>(_outletParams[0])); + ImGuiEx::PlotBands(_nodeCanvas.getNodeDrawList(), 0, (this->height*_nodeCanvas.GetCanvasScale()) - (26*this->scaleFactor), static_cast *>(_outletParams[0])); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/audio_analysis/PitchExtractor.cpp b/src/objects/audio_analysis/PitchExtractor.cpp index 5c09da7d..63ad0c14 100755 --- a/src/objects/audio_analysis/PitchExtractor.cpp +++ b/src/objects/audio_analysis/PitchExtractor.cpp @@ -145,7 +145,7 @@ void PitchExtractor::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.f, 4186.f,IM_COL32(255,255,120,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.f, 4186.f,IM_COL32(255,255,120,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/audio_analysis/RMSExtractor.cpp b/src/objects/audio_analysis/RMSExtractor.cpp index 3b43ed3f..409ee00d 100755 --- a/src/objects/audio_analysis/RMSExtractor.cpp +++ b/src/objects/audio_analysis/RMSExtractor.cpp @@ -147,7 +147,7 @@ void RMSExtractor::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.f, 1.f,IM_COL32(255,255,120,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.f, 1.f,IM_COL32(255,255,120,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor*_nodeCanvas.GetCanvasScale()); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/communications/ArduinoSerial.cpp b/src/objects/communications/ArduinoSerial.cpp index e2daf052..147d0de3 100644 --- a/src/objects/communications/ArduinoSerial.cpp +++ b/src/objects/communications/ArduinoSerial.cpp @@ -200,14 +200,21 @@ void ArduinoSerial::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::SetCursorPos(ImVec2(posX+IMGUI_EX_NODE_PINS_WIDTH_NORMAL, posY+IMGUI_EX_NODE_HEADER_HEIGHT)); - ImGui::Image(arduinoIcon->getTexture().getTextureData().textureID, ImVec2(this->width-IMGUI_EX_NODE_PINS_WIDTH_NORMAL-IMGUI_EX_NODE_PINS_WIDTH_SMALL,this->height-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)); + ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.13f, 0.13f, 0.13f, 1.0f))); + if(arduinoIcon->getTexture().isAllocated()){ + calcTextureDims(arduinoIcon->getTexture(), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); + ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); + ImGui::Image(arduinoIcon->getTexture().getTextureData().textureID, ImVec2(drawW, drawH)); + } + //ImGui::SetCursorPos(ImVec2(posX+IMGUI_EX_NODE_PINS_WIDTH_NORMAL, posY+IMGUI_EX_NODE_HEADER_HEIGHT)); + //ImGui::Image(arduinoIcon->getTexture().getTextureData().textureID, ImVec2(this->width-IMGUI_EX_NODE_PINS_WIDTH_NORMAL-IMGUI_EX_NODE_PINS_WIDTH_SMALL,this->height-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)); // get imgui node translated/scaled position/dimension for drawing textures in OF //objOriginX = (ImGui::GetWindowPos().x + ((IMGUI_EX_NODE_PINS_WIDTH_NORMAL - 1)*this->scaleFactor) - _nodeCanvas.GetCanvasTranslation().x)/_nodeCanvas.GetCanvasScale(); //objOriginY = (ImGui::GetWindowPos().y - _nodeCanvas.GetCanvasTranslation().y)/_nodeCanvas.GetCanvasScale(); - //scaledObjW = this->width - (IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor/_nodeCanvas.GetCanvasScale()); - //scaledObjH = this->height - ((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor/_nodeCanvas.GetCanvasScale()); + scaledObjW = this->width - (IMGUI_EX_NODE_PINS_WIDTH_NORMAL+IMGUI_EX_NODE_PINS_WIDTH_SMALL)*this->scaleFactor/_nodeCanvas.GetCanvasScale(); + scaledObjH = this->height - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor/_nodeCanvas.GetCanvasScale(); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/communications/KeyPressed.cpp b/src/objects/communications/KeyPressed.cpp index 5c707d3f..cc22f552 100755 --- a/src/objects/communications/KeyPressed.cpp +++ b/src/objects/communications/KeyPressed.cpp @@ -113,7 +113,7 @@ void KeyPressed::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - 40)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::InputInt("KEY",&requiredKey)){ this->setCustomVar(static_cast(requiredKey),"KEY"); diff --git a/src/objects/communications/KeyReleased.cpp b/src/objects/communications/KeyReleased.cpp index 3b331b31..2e14d567 100755 --- a/src/objects/communications/KeyReleased.cpp +++ b/src/objects/communications/KeyReleased.cpp @@ -114,7 +114,7 @@ void KeyReleased::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - 40)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::InputInt("KEY",&requiredKey)){ this->setCustomVar(static_cast(requiredKey),"KEY"); diff --git a/src/objects/communications/MidiKey.cpp b/src/objects/communications/MidiKey.cpp index 1602d432..f36ff4c4 100755 --- a/src/objects/communications/MidiKey.cpp +++ b/src/objects/communications/MidiKey.cpp @@ -150,7 +150,7 @@ void MidiKey::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - 40)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::InputInt("PITCH",&lastPitch)){ savedPitch = lastPitch; diff --git a/src/objects/communications/MidiKnob.cpp b/src/objects/communications/MidiKnob.cpp index 7a48c652..fcb96df3 100755 --- a/src/objects/communications/MidiKnob.cpp +++ b/src/objects/communications/MidiKnob.cpp @@ -126,7 +126,7 @@ void MidiKnob::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,10)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/4 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::InputInt("CONTROL",&lastControl)){ savedControl = lastControl; @@ -134,10 +134,9 @@ void MidiKnob::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ } - ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*2)); - ImGui::Dummy(ImVec2((ImGui::GetWindowSize().x-46)/2 - (ImGui::GetWindowSize().x-46)/6,1)); ImGui::SameLine(); + ImGui::SetCursorPos(ImVec2((this->width/2 - 26*this->scaleFactor) *_nodeCanvas.GetCanvasScale(), (this->height - 110*this->scaleFactor) * _nodeCanvas.GetCanvasScale())); - ImGuiKnobs::Knob("value", &actualValue, 0.0f, 127.0f, 0.1f, "%.0f", ImGuiKnobVariant_Wiper); + ImGuiKnobs::Knob("value", &actualValue, 0.0f, 127.0f, 0.1f, "%.0f", ImGuiKnobVariant_Stepped,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/communications/MidiPad.cpp b/src/objects/communications/MidiPad.cpp index 8de6003a..14296faf 100755 --- a/src/objects/communications/MidiPad.cpp +++ b/src/objects/communications/MidiPad.cpp @@ -164,7 +164,7 @@ void MidiPad::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - 40)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::InputInt("PITCH",&lastPitch)){ savedPitch = lastPitch; diff --git a/src/objects/communications/MidiReceiver.cpp b/src/objects/communications/MidiReceiver.cpp index d315418c..50ad3342 100644 --- a/src/objects/communications/MidiReceiver.cpp +++ b/src/objects/communications/MidiReceiver.cpp @@ -55,6 +55,8 @@ MidiReceiver::MidiReceiver() : PatchObject("midi receiver"){ midiDeviceID = 0; + this->width *= 2; + loaded = false; } diff --git a/src/objects/communications/MidiSender.cpp b/src/objects/communications/MidiSender.cpp index fd4cff66..80c346ab 100644 --- a/src/objects/communications/MidiSender.cpp +++ b/src/objects/communications/MidiSender.cpp @@ -56,6 +56,8 @@ MidiSender::MidiSender() : PatchObject("midi sender"){ trigger = false; lastNote = 0.0f; + this->width *= 2; + loaded = false; } diff --git a/src/objects/communications/OscReceiver.cpp b/src/objects/communications/OscReceiver.cpp index 68bec61d..1a95cd15 100644 --- a/src/objects/communications/OscReceiver.cpp +++ b/src/objects/communications/OscReceiver.cpp @@ -416,7 +416,8 @@ string OscReceiver::getLocalIP(){ string cmd = ""; FILE *execFile; #ifdef TARGET_LINUX - cmd = "ifconfig | grep -w 'inet' | grep -v 127.0.0.1 | awk '{print $2}'"; + //cmd = "ifconfig | grep -w 'inet' | grep -v 127.0.0.1 | awk '{print $2}'"; + cmd = "ifconfig | grep -w 'flags=4163' -A 1 | grep -w 'inet' | grep -v 127.0.0.1 | awk '{print $2}'"; execFile = popen(cmd.c_str(), "r"); #elif defined(TARGET_OSX) cmd = "ifconfig | grep -w 'inet' | grep -v 127.0.0.1 | awk '{print $2}'"; diff --git a/src/objects/computer_vision/BackgroundSubtraction.cpp b/src/objects/computer_vision/BackgroundSubtraction.cpp index 913433ab..650f6526 100644 --- a/src/objects/computer_vision/BackgroundSubtraction.cpp +++ b/src/objects/computer_vision/BackgroundSubtraction.cpp @@ -241,13 +241,12 @@ void BackgroundSubtraction::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated() && static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); + ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/computer_vision/ColorTracking.cpp b/src/objects/computer_vision/ColorTracking.cpp index 798492a9..bcdb3650 100644 --- a/src/objects/computer_vision/ColorTracking.cpp +++ b/src/objects/computer_vision/ColorTracking.cpp @@ -316,14 +316,11 @@ void ColorTracking::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated() && static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/computer_vision/HaarTracking.cpp b/src/objects/computer_vision/HaarTracking.cpp index 5a334868..f040b585 100644 --- a/src/objects/computer_vision/HaarTracking.cpp +++ b/src/objects/computer_vision/HaarTracking.cpp @@ -233,14 +233,11 @@ void HaarTracking::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated() && static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/computer_vision/MotionDetection.cpp b/src/objects/computer_vision/MotionDetection.cpp index 9429674f..c9ddabfb 100644 --- a/src/objects/computer_vision/MotionDetection.cpp +++ b/src/objects/computer_vision/MotionDetection.cpp @@ -165,7 +165,7 @@ void MotionDetection::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.0f, 1.0f, IM_COL32(255,255,255,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.0f, 1.0f, IM_COL32(255,255,255,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/computer_vision/OpticalFlow.cpp b/src/objects/computer_vision/OpticalFlow.cpp index 65bee853..71d59293 100644 --- a/src/objects/computer_vision/OpticalFlow.cpp +++ b/src/objects/computer_vision/OpticalFlow.cpp @@ -222,14 +222,11 @@ void OpticalFlow::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated() && static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/data/BangMultiplexer.cpp b/src/objects/data/BangMultiplexer.cpp index 8367df0f..57595f76 100755 --- a/src/objects/data/BangMultiplexer.cpp +++ b/src/objects/data/BangMultiplexer.cpp @@ -146,7 +146,7 @@ void BangMultiplexer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; char temp[32]; diff --git a/src/objects/data/BangToFloat.cpp b/src/objects/data/BangToFloat.cpp index c7c00f85..3ed68aa8 100644 --- a/src/objects/data/BangToFloat.cpp +++ b/src/objects/data/BangToFloat.cpp @@ -137,7 +137,7 @@ void BangToFloat::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,2)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); if(ImGui::DragFloat("", &number,0.1f)){ this->setCustomVar(number,"NUMBER"); diff --git a/src/objects/data/DataToFile.cpp b/src/objects/data/DataToFile.cpp index 84aae92a..712268a2 100755 --- a/src/objects/data/DataToFile.cpp +++ b/src/objects/data/DataToFile.cpp @@ -141,18 +141,19 @@ void DataToFile::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (16*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::Button(ICON_FA_FILE_UPLOAD,ImVec2(-1,26*scaleFactor))){ exportFileFlag = true; } ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); - ImVec2 pos = ImVec2(window_pos.x + window_size.x - (30*scaleFactor), window_pos.y + (40*scaleFactor)); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + ImVec2 pos = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,10,60)*scaleFactor), window_pos.y + IMGUI_EX_NODE_HEADER_HEIGHT + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,40)*scaleFactor)); + float radius = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,20)*scaleFactor; if (recordData){ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10, IM_COL32(255, 0, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(255, 0, 0, 255), 40); }else{ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10, IM_COL32(0, 255, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(0, 255, 0, 255), 40); } _nodeCanvas.EndNodeContent(); diff --git a/src/objects/data/DataToTexture.cpp b/src/objects/data/DataToTexture.cpp index bb0fb774..8f0cc0a3 100644 --- a/src/objects/data/DataToTexture.cpp +++ b/src/objects/data/DataToTexture.cpp @@ -208,14 +208,11 @@ void DataToTexture::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/data/FileToData.cpp b/src/objects/data/FileToData.cpp index 88841395..afa3a1fd 100644 --- a/src/objects/data/FileToData.cpp +++ b/src/objects/data/FileToData.cpp @@ -136,7 +136,7 @@ void FileToData::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (16*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::Button(ICON_FA_FILE,ImVec2(-1,26*scaleFactor))){ openFileFlag = true; } diff --git a/src/objects/data/FloatMultiplexer.cpp b/src/objects/data/FloatMultiplexer.cpp index 3ab871c1..ade25e60 100755 --- a/src/objects/data/FloatMultiplexer.cpp +++ b/src/objects/data/FloatMultiplexer.cpp @@ -146,7 +146,7 @@ void FloatMultiplexer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; char temp[32]; diff --git a/src/objects/data/FloatsToVector.cpp b/src/objects/data/FloatsToVector.cpp index 32345b0d..7bd4a281 100755 --- a/src/objects/data/FloatsToVector.cpp +++ b/src/objects/data/FloatsToVector.cpp @@ -144,7 +144,7 @@ void FloatsToVector::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; char temp[32]; diff --git a/src/objects/data/Receiver.cpp b/src/objects/data/Receiver.cpp index ff5f866e..a5db6383 100644 --- a/src/objects/data/Receiver.cpp +++ b/src/objects/data/Receiver.cpp @@ -188,7 +188,7 @@ void vpReceiver::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ if(isReceivingON){ - ImGui::Dummy(ImVec2(-1,6*scaleFactor)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (2*scaleFactor))); ImGui::Text("%s",varName.c_str()); } diff --git a/src/objects/data/Sender.cpp b/src/objects/data/Sender.cpp index 6fda00bc..00541425 100644 --- a/src/objects/data/Sender.cpp +++ b/src/objects/data/Sender.cpp @@ -179,7 +179,7 @@ void vpSender::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ if(isSendingON){ - ImGui::Dummy(ImVec2(-1,6*scaleFactor)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (2*scaleFactor))); ImGui::Text("%s",varName.c_str()); } diff --git a/src/objects/data/TextureToData.cpp b/src/objects/data/TextureToData.cpp index 21dd8f3f..07cb95fd 100644 --- a/src/objects/data/TextureToData.cpp +++ b/src/objects/data/TextureToData.cpp @@ -135,14 +135,11 @@ void TextureToData::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_inletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_inletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/data/VectorAt.cpp b/src/objects/data/VectorAt.cpp index 9b14de54..7c79e29d 100755 --- a/src/objects/data/VectorAt.cpp +++ b/src/objects/data/VectorAt.cpp @@ -133,7 +133,7 @@ void VectorAt::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (26*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); if(ImGui::DragInt("", &vectorAt)){ if(vectorAt < 0){ diff --git a/src/objects/data/VectorConcat.cpp b/src/objects/data/VectorConcat.cpp index db02e35f..bb0cb252 100755 --- a/src/objects/data/VectorConcat.cpp +++ b/src/objects/data/VectorConcat.cpp @@ -142,14 +142,14 @@ void VectorConcat::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; for(int i=0;inumInlets;i++){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (14*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(120,255,120,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (14*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(120,255,120,60),2.0f); if(i==this->numInlets-1){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2)),IM_COL32(120,255,120,60),2.0f); - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + ((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(120,255,120,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2)),IM_COL32(120,255,120,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + ((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(120,255,120,60),2.0f); } } diff --git a/src/objects/data/VectorExtract.cpp b/src/objects/data/VectorExtract.cpp index 8ab23b59..1ab9956f 100755 --- a/src/objects/data/VectorExtract.cpp +++ b/src/objects/data/VectorExtract.cpp @@ -134,7 +134,7 @@ void VectorExtract::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,10*scaleFactor)); + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(static_cast(static_cast *>(_outletParams[0])->size()) > 0){ ImGui::Text("size\nrange"); ImGui::SameLine(); @@ -161,7 +161,7 @@ void VectorExtract::drawObjectNodeConfig(){ } ImGui::Spacing(); int prevEnd = end; - if(ImGui::InputInt("End",&end)){ + if(ImGui::InputInt("Size",&end)){ if(end > start && end <= static_cast(static_cast *>(_inletParams[0])->size())-1){ this->setCustomVar(static_cast(end),"END"); }else{ diff --git a/src/objects/data/VectorGate.cpp b/src/objects/data/VectorGate.cpp index 3860f084..b6921cf3 100644 --- a/src/objects/data/VectorGate.cpp +++ b/src/objects/data/VectorGate.cpp @@ -151,14 +151,14 @@ void VectorGate::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; for(int i=1;inumInlets;i++){ if(i == openInlet){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (90*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(120,255,120,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(120,255,120,60),2.0f); } - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (90*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(120,255,120,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(120,255,120,60),2.0f); } // save object dimensions (for resizable ones) diff --git a/src/objects/data/VectorOperator.cpp b/src/objects/data/VectorOperator.cpp index 78695862..eb77b960 100755 --- a/src/objects/data/VectorOperator.cpp +++ b/src/objects/data/VectorOperator.cpp @@ -138,7 +138,7 @@ void VectorOperator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (46*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-50*scaleFactor); if(ImGui::BeginCombo("operator", operators_string.at(_operator).c_str() )){ diff --git a/src/objects/graphics/ColorPalette.cpp b/src/objects/graphics/ColorPalette.cpp index 50819831..2161bb9f 100644 --- a/src/objects/graphics/ColorPalette.cpp +++ b/src/objects/graphics/ColorPalette.cpp @@ -173,13 +173,12 @@ void ColorPalette::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor, IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor); - - //calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); + ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); + for(size_t i=0;iAddRectFilled(window_pos + ImVec2(tw*i,0),window_pos + ImVec2(tw*i,0) + ImVec2(tw, th),ImGui::GetColorU32(ImVec4(palette.at(i).r, palette.at(i).g, palette.at(i).b, 1.0f))); } diff --git a/src/objects/graphics/ImageExporter.cpp b/src/objects/graphics/ImageExporter.cpp index 8ebedfd6..8593d58f 100644 --- a/src/objects/graphics/ImageExporter.cpp +++ b/src/objects/graphics/ImageExporter.cpp @@ -149,14 +149,11 @@ void ImageExporter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_inletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_inletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/graphics/ImageLoader.cpp b/src/objects/graphics/ImageLoader.cpp index 3ea3dac2..347b5d43 100644 --- a/src/objects/graphics/ImageLoader.cpp +++ b/src/objects/graphics/ImageLoader.cpp @@ -156,14 +156,11 @@ void ImageLoader::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/gui/mo2DPad.cpp b/src/objects/gui/mo2DPad.cpp index 95348d79..a71a0933 100644 --- a/src/objects/gui/mo2DPad.cpp +++ b/src/objects/gui/mo2DPad.cpp @@ -130,7 +130,7 @@ void mo2DPad::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - if(ImGuiEx::Pad2D(_nodeCanvas.getNodeDrawList(), 0, ImGui::GetWindowSize().y - 26,&_x,&_y)){ + if(ImGuiEx::Pad2D(_nodeCanvas.getNodeDrawList(), 0, (this->height*_nodeCanvas.GetCanvasScale()) - (26*this->scaleFactor),&_x,&_y)){ this->setCustomVar(static_cast(_x),"XPOS"); this->setCustomVar(static_cast(_y),"YPOS"); } diff --git a/src/objects/gui/moDataViewer.cpp b/src/objects/gui/moDataViewer.cpp index 7fbe4098..ea662acf 100755 --- a/src/objects/gui/moDataViewer.cpp +++ b/src/objects/gui/moDataViewer.cpp @@ -128,7 +128,7 @@ void moDataViewer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // draw data if(this->inletsConnected[0] && !static_cast *>(_inletParams[0])->empty()){ - ImGuiEx::PlotBands(_nodeCanvas.getNodeDrawList(), 0, ImGui::GetWindowSize().y - 26, static_cast *>(_inletParams[0]), max, IM_COL32(color.x*255,color.y*255,color.z*255,color.w*255)); + ImGuiEx::PlotBands(_nodeCanvas.getNodeDrawList(), 0, (this->height*_nodeCanvas.GetCanvasScale()) - (26*this->scaleFactor), static_cast *>(_inletParams[0]), max, IM_COL32(color.x*255,color.y*255,color.z*255,color.w*255)); } if(this->width != prevW){ diff --git a/src/objects/gui/moMessage.cpp b/src/objects/gui/moMessage.cpp index 21e2cfc9..89423618 100644 --- a/src/objects/gui/moMessage.cpp +++ b/src/objects/gui/moMessage.cpp @@ -118,8 +118,8 @@ void moMessage::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (40*scaleFactor))); // Padding top - ImGui::PushItemWidth(-24*scaleFactor); + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); + ImGui::PushItemWidth(-26*scaleFactor); ImGui::PushStyleColor(ImGuiCol_FrameBg, VHS_DGRAY); if(ImGui::InputText("##source", &actualMessage)){ saveMessageSetting(); diff --git a/src/objects/gui/moMultiSlider.cpp b/src/objects/gui/moMultiSlider.cpp index 68282526..e0e92788 100644 --- a/src/objects/gui/moMultiSlider.cpp +++ b/src/objects/gui/moMultiSlider.cpp @@ -118,7 +118,7 @@ void moMultiSlider::updateObjectContent(map> &patchO } } - this->width = 20*scaleFactor + numSliders*(sliderW+9.0f)*scaleFactor + 10*scaleFactor; + this->width = 20*scaleFactor + numSliders*(30.0f + 9.0f)*scaleFactor + 10*scaleFactor; if(this->width < OBJECT_WIDTH*scaleFactor){ this->width = OBJECT_WIDTH*scaleFactor; } @@ -190,7 +190,7 @@ void moMultiSlider::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(120,120,120,60)); ImGui::PushStyleColor(ImGuiCol_FrameBgActive, IM_COL32(120,120,120,60)); ImGui::PushStyleColor(ImGuiCol_SliderGrab, IM_COL32(120,120,120,160)); - ImGui::VSliderFloat("##v", ImVec2(sliderW*scaleFactor, this->height - 36.0f*scaleFactor), &values[i], 0.0f, 1.0f, ""); + ImGui::VSliderFloat("##v", ImVec2(sliderW*this->scaleFactor, this->height*_nodeCanvas.GetCanvasScale() - 36.0f*scaleFactor), &values[i], 0.0f, 1.0f, ""); if (ImGui::IsItemActive() || ImGui::IsItemHovered()){ ImGui::SetTooltip("s%i %.2f", i+1, values[i]); this->setCustomVar(values[i],"SLIDERVALUE_"+ofToString(i+1)); @@ -199,8 +199,11 @@ void moMultiSlider::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::PopID(); } + sliderW = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-2,72); + _nodeCanvas.EndNodeContent(); } + } //-------------------------------------------------------------- diff --git a/src/objects/gui/moMultiToggle.cpp b/src/objects/gui/moMultiToggle.cpp index 7d86fdc3..6f2fd571 100644 --- a/src/objects/gui/moMultiToggle.cpp +++ b/src/objects/gui/moMultiToggle.cpp @@ -134,7 +134,7 @@ void moMultiToggle::updateObjectContent(map> &patchO } } - this->width = 20*scaleFactor + numToggles*(toggleW+9.0f)*scaleFactor + 10*scaleFactor; + this->width = 20*scaleFactor + numToggles*(toggleW+8.0f)*scaleFactor + 10*scaleFactor; if(this->width < OBJECT_WIDTH*scaleFactor){ this->width = OBJECT_WIDTH*scaleFactor; } @@ -200,7 +200,8 @@ void moMultiToggle::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,2.0f)); // Padding top + ImGui::SetCursorPos(ImVec2(((this->width*_nodeCanvas.GetCanvasScale())/2.0f)-(((toggleW+8.0)*scaleFactor)*numToggles/2.0f)+(8.0f*scaleFactor),(IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor)+(this->height*_nodeCanvas.GetCanvasScale()/2.0f)-(toggleW*scaleFactor))); + for(int i=0;i 0) ImGui::SameLine(); diff --git a/src/objects/gui/moPlayerControls.cpp b/src/objects/gui/moPlayerControls.cpp index 53655cb6..0b0c498e 100644 --- a/src/objects/gui/moPlayerControls.cpp +++ b/src/objects/gui/moPlayerControls.cpp @@ -153,11 +153,11 @@ void moPlayerControls::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::PushStyleColor(ImGuiCol_Button, VHS_BLUE); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, VHS_BLUE_OVER); ImGui::PushStyleColor(ImGuiCol_ButtonActive, VHS_BLUE_OVER); - if(ImGui::Button(ICON_FA_PLAY,ImVec2(69*scaleFactor,26*scaleFactor))){ + if(ImGui::Button(ICON_FA_PLAY,ImVec2(69*scaleFactor*_nodeCanvas.GetCanvasScale(),26*scaleFactor*_nodeCanvas.GetCanvasScale()))){ *static_cast(_outletParams[0]) = "play"; } ImGui::SameLine(); - if(ImGui::Button(ICON_FA_STOP,ImVec2(69*scaleFactor,26*scaleFactor))){ + if(ImGui::Button(ICON_FA_STOP,ImVec2(69*scaleFactor*_nodeCanvas.GetCanvasScale(),26*scaleFactor*_nodeCanvas.GetCanvasScale()))){ *static_cast(_outletParams[0]) = "stop"; } ImGui::PopStyleColor(3); @@ -165,7 +165,7 @@ void moPlayerControls::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::PushStyleColor(ImGuiCol_Button, VHS_YELLOW); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, VHS_YELLOW_OVER); ImGui::PushStyleColor(ImGuiCol_ButtonActive, VHS_YELLOW_OVER); - if(ImGui::Button(ICON_FA_PAUSE,ImVec2(69*scaleFactor,26*scaleFactor))){ + if(ImGui::Button(ICON_FA_PAUSE,ImVec2(69*scaleFactor*_nodeCanvas.GetCanvasScale(),26*scaleFactor*_nodeCanvas.GetCanvasScale()))){ pause = !pause; if(pause){ *static_cast(_outletParams[0]) = "pause"; diff --git a/src/objects/gui/moSignalViewer.cpp b/src/objects/gui/moSignalViewer.cpp index 73991e45..240b7d6e 100644 --- a/src/objects/gui/moSignalViewer.cpp +++ b/src/objects/gui/moSignalViewer.cpp @@ -127,10 +127,10 @@ void moSignalViewer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ // draw waveform - ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImGui::GetWindowSize(), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); + ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImVec2(ImGui::GetWindowSize().x,this->height*_nodeCanvas.GetCanvasScale()), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); // draw signal RMS amplitude - _nodeCanvas.getNodeDrawList()->AddRectFilled(ImGui::GetWindowPos()+ImVec2(0,ImGui::GetWindowSize().y),ImGui::GetWindowPos()+ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y * (1.0f - ofClamp(static_cast(_inletParams[0])->getRMSAmplitude(),0.0,1.0))),IM_COL32(255,255,120,12)); + _nodeCanvas.getNodeDrawList()->AddRectFilled(ImGui::GetWindowPos()+ImVec2(0,this->height*_nodeCanvas.GetCanvasScale()),ImGui::GetWindowPos()+ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y * (1.0f - ofClamp(static_cast(_inletParams[0])->getRMSAmplitude(),0.0,1.0))),IM_COL32(255,255,120,12)); _nodeCanvas.EndNodeContent(); } @@ -140,7 +140,7 @@ void moSignalViewer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ //-------------------------------------------------------------- void moSignalViewer::drawObjectNodeConfig(){ ImGuiEx::ObjectInfo( - "Audio signal display, also byapass it through its outlets, plus the data buffer and the RMS amplitude.", + "Audio signal display, also bypass it through its outlets, extracting the data buffer and the RMS amplitude.", "https://mosaic.d3cod3.org/reference.php?r=signal-viewer", scaleFactor); } diff --git a/src/objects/gui/moSlider.cpp b/src/objects/gui/moSlider.cpp index 778964bd..df60be53 100644 --- a/src/objects/gui/moSlider.cpp +++ b/src/objects/gui/moSlider.cpp @@ -123,7 +123,7 @@ void moSlider::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,2)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); ImGui::SliderFloat("",&value,0.0f, 1.0f); ImGui::PopItemWidth(); diff --git a/src/objects/gui/moSonogram.cpp b/src/objects/gui/moSonogram.cpp index 3bc01ece..65a22729 100644 --- a/src/objects/gui/moSonogram.cpp +++ b/src/objects/gui/moSonogram.cpp @@ -185,14 +185,11 @@ void moSonogram::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/gui/moTimeline.cpp b/src/objects/gui/moTimeline.cpp index bbd061d0..7f51a38e 100755 --- a/src/objects/gui/moTimeline.cpp +++ b/src/objects/gui/moTimeline.cpp @@ -309,7 +309,7 @@ void moTimeline::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); ImVec2 ph_pos = ImVec2(window_pos.x + (20*this->scaleFactor), window_pos.y + (20*this->scaleFactor)); diff --git a/src/objects/gui/moValuePlotter.cpp b/src/objects/gui/moValuePlotter.cpp index 5eae5220..d5529af3 100644 --- a/src/objects/gui/moValuePlotter.cpp +++ b/src/objects/gui/moValuePlotter.cpp @@ -155,9 +155,9 @@ void moValuePlotter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); - ImGuiEx::plotValue(*(float *)&_outletParams[0], lastMinRange.get(), lastMaxRange.get(), IM_COL32(color.x*255,color.y*255,color.z*255,color.w*255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], lastMinRange.get(), lastMaxRange.get(), IM_COL32(color.x*255,color.y*255,color.z*255,color.w*255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.getNodeDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*_nodeCanvas.GetCanvasScale(), ImVec2(window_pos.x +(40*_nodeCanvas.GetCanvasScale()), window_pos.y+window_size.y-(36*_nodeCanvas.GetCanvasScale())), IM_COL32_WHITE, name.c_str(), NULL, 0.0f); diff --git a/src/objects/gui/moVideoViewer.cpp b/src/objects/gui/moVideoViewer.cpp index aba1b20b..22cf0d34 100644 --- a/src/objects/gui/moVideoViewer.cpp +++ b/src/objects/gui/moVideoViewer.cpp @@ -133,14 +133,12 @@ void moVideoViewer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT)); + ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - ImGui::Image(kuro->getTexture().getTextureData().textureID, ImVec2(this->width-IMGUI_EX_NODE_PINS_WIDTH_NORMAL-IMGUI_EX_NODE_PINS_WIDTH_SMALL,this->height-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - ImGui::Image(kuro->getTexture().getTextureData().textureID, ImVec2(this->width-IMGUI_EX_NODE_PINS_WIDTH_NORMAL-IMGUI_EX_NODE_PINS_WIDTH_SMALL,this->height-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/logic/BooleanOperator.cpp b/src/objects/logic/BooleanOperator.cpp index dcdeb878..c87bca10 100755 --- a/src/objects/logic/BooleanOperator.cpp +++ b/src/objects/logic/BooleanOperator.cpp @@ -139,7 +139,7 @@ void BooleanOperator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/4)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), this->height/2 *_nodeCanvas.GetCanvasScale())); ImGui::PushItemWidth(-50*scaleFactor); if(ImGui::BeginCombo("operator", operators_string.at(_operator).c_str() )){ @@ -155,8 +155,11 @@ void BooleanOperator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ } if(bang){ - ImVec2 pos = ImVec2(ImGui::GetWindowPos().x + ImGui::GetWindowSize().x - (30*this->scaleFactor), ImGui::GetWindowPos().y + (40*this->scaleFactor)); - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(250, 250, 5, 255), 40); + ImVec2 window_pos = ImGui::GetWindowPos(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + ImVec2 pos = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,10,60)*scaleFactor), window_pos.y + IMGUI_EX_NODE_HEADER_HEIGHT + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,40)*scaleFactor)); + float radius = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,20)*scaleFactor; + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(250, 250, 5, 255), 40); } _nodeCanvas.EndNodeContent(); diff --git a/src/objects/logic/Conditional.cpp b/src/objects/logic/Conditional.cpp index a2086b44..07b887bb 100755 --- a/src/objects/logic/Conditional.cpp +++ b/src/objects/logic/Conditional.cpp @@ -155,7 +155,7 @@ void Conditional::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (46*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-50*scaleFactor); if(ImGui::BeginCombo("operator", operators_string.at(_operator).c_str() )){ diff --git a/src/objects/logic/Counter.cpp b/src/objects/logic/Counter.cpp index c7f89385..f43c315f 100755 --- a/src/objects/logic/Counter.cpp +++ b/src/objects/logic/Counter.cpp @@ -152,9 +152,9 @@ void Counter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,6*scaleFactor)); // Padding top + ImGui::SetCursorPos(ImVec2((this->width*0.5f*_nodeCanvas.GetCanvasScale()),IMGUI_EX_NODE_HEADER_HEIGHT*1.4*scaleFactor)); - ImGui::Dummy(ImVec2(this->width/3.5f,1)); ImGui::SameLine(); ImGui::Text("%i",static_cast(floor(*(float *)&_outletParams[0]))); + ImGui::Text("%i",static_cast(floor(*(float *)&_outletParams[0]))); ImGui::Dummy(ImVec2(-1,6*scaleFactor)); diff --git a/src/objects/logic/DelayFloat.cpp b/src/objects/logic/DelayFloat.cpp index 24e76552..4c4b7b57 100755 --- a/src/objects/logic/DelayFloat.cpp +++ b/src/objects/logic/DelayFloat.cpp @@ -155,9 +155,9 @@ void DelayFloat::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (28*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); if(ImGui::DragFloat("", &number,0.01f)){ this->setCustomVar(number,"NUMBER"); diff --git a/src/objects/logic/Gate.cpp b/src/objects/logic/Gate.cpp index 86924651..bf300211 100644 --- a/src/objects/logic/Gate.cpp +++ b/src/objects/logic/Gate.cpp @@ -154,17 +154,17 @@ void Gate::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; char temp[32]; for(int i=1;inumInlets;i++){ if(i == openInlet){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (50*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (90*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(60,60,60,255),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (50*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(60,60,60,255),2.0f); sprintf_s(temp,"%.2f",*(float *)&_inletParams[i]); _nodeCanvas.getNodeDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize(), ImVec2(window_pos.x+(20*this->scaleFactor),window_pos.y + ((IMGUI_EX_NODE_HEADER_HEIGHT-7)*this->scaleFactor) + (pinDistance/2) + pinDistance*i), IM_COL32_WHITE, temp, NULL, 0.0f); } - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (90*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(60,60,60,255),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(60,60,60,255),2.0f); } // save object dimensions (for resizable ones) diff --git a/src/objects/logic/LoadBang.cpp b/src/objects/logic/LoadBang.cpp index 4d0e9fd5..9e9bf4fc 100644 --- a/src/objects/logic/LoadBang.cpp +++ b/src/objects/logic/LoadBang.cpp @@ -144,7 +144,7 @@ void LoadBang::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); // BANG (PD Style) button ImGuiEx::BangButton("", currentColor, ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y)); diff --git a/src/objects/logic/Spigot.cpp b/src/objects/logic/Spigot.cpp index 29c642bf..9f2ad4f1 100644 --- a/src/objects/logic/Spigot.cpp +++ b/src/objects/logic/Spigot.cpp @@ -213,7 +213,7 @@ void Spigot::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float inletPinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; float outletPinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numOutlets; diff --git a/src/objects/logic/TimedSemaphore.cpp b/src/objects/logic/TimedSemaphore.cpp index 8e2c8372..28a8fc80 100755 --- a/src/objects/logic/TimedSemaphore.cpp +++ b/src/objects/logic/TimedSemaphore.cpp @@ -51,6 +51,8 @@ TimedSemaphore::TimedSemaphore() : PatchObject("timed semaphore"){ this->initInletsState(); + isAudioOUTObject = true; + bang = false; loadStart = true; @@ -82,28 +84,38 @@ void TimedSemaphore::setupObjectContent(shared_ptr &mainWindow) currentColor = releaseColor; } +//-------------------------------------------------------------- +void TimedSemaphore::setupAudioOutObjectContent(pdsp::Engine &engine){ + unusedArgs(engine); + + // ---- this code runs in the audio thread ---- + sync.code = [&]() noexcept { + if(this->inletsConnected[0] && loadStart){ + if(*(float *)&_inletParams[0] == 1.0 && !bang){ + bang = true; + loadStart = false; + startTime = ofGetElapsedTimeMillis(); + } + }else{ + bang = false; + } + + *(float *)&_outletParams[0] = static_cast(bang); + }; + +} + //-------------------------------------------------------------- void TimedSemaphore::updateObjectContent(map> &patchObjects){ + unusedArgs(patchObjects); if(this->inletsConnected[1]){ wait = static_cast(floor(*(float *)&_inletParams[1])); } - if(this->inletsConnected[0] && loadStart){ - if(*(float *)&_inletParams[0] == 1.0 && !bang){ - bang = true; - loadStart = false; - startTime = ofGetElapsedTimeMillis(); - } - }else{ - bang = false; - } - if(!loadStart && (ofGetElapsedTimeMillis()-startTime > wait)){ loadStart = true; } - - *(float *)&_outletParams[0] = static_cast(bang); if(!loaded){ loaded = true; @@ -114,7 +126,7 @@ void TimedSemaphore::updateObjectContent(map> &patch //-------------------------------------------------------------- void TimedSemaphore::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ - ofSetColor(255); + unusedArgs(font,glRenderer); } @@ -143,8 +155,9 @@ void TimedSemaphore::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); - ImVec2 pos = ImVec2(window_pos.x + window_size.x - (30*this->scaleFactor), window_pos.y + (40*this->scaleFactor)); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + ImVec2 pos = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,10,60)*scaleFactor), window_pos.y + IMGUI_EX_NODE_HEADER_HEIGHT + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,40)*scaleFactor)); + float radius = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,20)*scaleFactor; // BANG (PD Style) button ImGuiEx::BangButton("", currentColor, ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y)); @@ -156,9 +169,9 @@ void TimedSemaphore::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ } if(loadStart){ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(5, 250, 5, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(5, 250, 5, 255), 40); }else{ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(250, 5, 5, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(250, 5, 5, 255), 40); } _nodeCanvas.EndNodeContent(); @@ -184,6 +197,12 @@ void TimedSemaphore::drawObjectNodeConfig(){ //-------------------------------------------------------------- void TimedSemaphore::removeObjectContent(bool removeFileFromData){ + unusedArgs(removeFileFromData); +} + +//-------------------------------------------------------------- +void TimedSemaphore::audioOutObject(ofSoundBuffer &outputBuffer){ + unusedArgs(outputBuffer); } diff --git a/src/objects/logic/TimedSemaphore.h b/src/objects/logic/TimedSemaphore.h index 6903a918..b09a4c87 100755 --- a/src/objects/logic/TimedSemaphore.h +++ b/src/objects/logic/TimedSemaphore.h @@ -46,6 +46,7 @@ class TimedSemaphore : public PatchObject { void newObject() override; void setupObjectContent(shared_ptr &mainWindow) override; + void setupAudioOutObjectContent(pdsp::Engine &engine) override; void updateObjectContent(map> &patchObjects) override; void drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer) override; @@ -54,12 +55,15 @@ class TimedSemaphore : public PatchObject { void removeObjectContent(bool removeFileFromData=false) override; + void audioOutObject(ofSoundBuffer &outputBuffer) override; + ImVec4 currentColor; ImVec4 pressColor; ImVec4 releaseColor; bool bang; + pdsp::Function sync; bool loadStart; int wait; diff --git a/src/objects/math/Clamp.cpp b/src/objects/math/Clamp.cpp index 6f01a379..4fb8ab10 100755 --- a/src/objects/math/Clamp.cpp +++ b/src/objects/math/Clamp.cpp @@ -130,7 +130,7 @@ void Clamp::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(ImGui::DragFloat("Min",&min,0.01f)){ this->setCustomVar(static_cast(min),"MIN"); diff --git a/src/objects/math/Constant.cpp b/src/objects/math/Constant.cpp index 7f5fcc7e..6271aabf 100755 --- a/src/objects/math/Constant.cpp +++ b/src/objects/math/Constant.cpp @@ -156,7 +156,7 @@ void Constant::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,2)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); if(ImGui::DragFloat("", &inputValueNew.get(),0.01f)){ this->setCustomVar(static_cast(inputValueNew.get()),"NUMBER"); diff --git a/src/objects/math/CosineGenerator.cpp b/src/objects/math/CosineGenerator.cpp index 60a81b08..1b048bc3 100755 --- a/src/objects/math/CosineGenerator.cpp +++ b/src/objects/math/CosineGenerator.cpp @@ -126,7 +126,7 @@ void CosineGenerator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], -1.0f, 1.0f, IM_COL32(255,255,255,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], -1.0f, 1.0f, IM_COL32(255,255,255,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/math/Map.cpp b/src/objects/math/Map.cpp index 289df3b8..789ec6ff 100755 --- a/src/objects/math/Map.cpp +++ b/src/objects/math/Map.cpp @@ -150,19 +150,19 @@ void Map::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; float valuePercentage = ofMap(*(float *)&_outletParams[0],outMin,outMax,0.0f,1.0f,true); // vertical ranges - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (50*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + (pinDistance*1)),ImVec2(window_pos.x + (50*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + (pinDistance*3)),IM_COL32(60,60,60,255),2.0f); - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (130*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2)),ImVec2(window_pos.x + (130*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + (pinDistance*4)),IM_COL32(60,60,60,255),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (50*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + (pinDistance*1)),ImVec2(window_pos.x + (50*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + (pinDistance*3)),IM_COL32(60,60,60,255),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (130*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2)),ImVec2(window_pos.x + (130*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + (pinDistance*4)),IM_COL32(60,60,60,255),2.0f); // value - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (50*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*2)*valuePercentage) + pinDistance),ImVec2(window_pos.x + (130*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*4)*valuePercentage)),IM_COL32(90,90,90,255),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (50*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*2)*valuePercentage) + pinDistance),ImVec2(window_pos.x + (130*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*4)*valuePercentage)),IM_COL32(90,90,90,255),2.0f); - _nodeCanvas.getNodeDrawList()->AddCircleFilled(ImVec2(window_pos.x + (50*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*2)*valuePercentage) + pinDistance),4*scaleFactor,IM_COL32(160,160,160,255),40); - _nodeCanvas.getNodeDrawList()->AddCircleFilled(ImVec2(window_pos.x + (130*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*4)*valuePercentage)),4*scaleFactor,IM_COL32(160,160,160,255),40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(ImVec2(window_pos.x + (50*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*2)*valuePercentage) + pinDistance),4*scaleFactor*_nodeCanvas.GetCanvasScale(),IM_COL32(160,160,160,255),40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(ImVec2(window_pos.x + (130*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + ((pinDistance*4)*valuePercentage)),4*scaleFactor*_nodeCanvas.GetCanvasScale(),IM_COL32(160,160,160,255),40); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/math/Metronome.cpp b/src/objects/math/Metronome.cpp index 359c04e1..a75e2035 100755 --- a/src/objects/math/Metronome.cpp +++ b/src/objects/math/Metronome.cpp @@ -171,13 +171,15 @@ void Metronome::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.f, 1.f, IM_COL32(170,170,170,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.f, 1.f, IM_COL32(170,170,170,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); // draw System BPM ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); - ImVec2 pos = ImVec2(window_pos.x + window_size.x - 50*scaleFactor, window_pos.y + window_size.y - 38*scaleFactor); - ImVec2 posFirst = ImVec2(window_pos.x + window_size.x - 50*scaleFactor, window_pos.y + 38*scaleFactor); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + ImVec2 pos = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,100)*scaleFactor), window_pos.y + window_size.y - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,82)*scaleFactor)); + ImVec2 posFirst = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,100)*scaleFactor), window_pos.y + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,82)*scaleFactor)); + + float radius = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,8)*scaleFactor; char temp[32]; sprintf_s(temp,"%.1f",static_cast(60.0f/(timeSetting.get()/1000.0f))); @@ -187,7 +189,7 @@ void Metronome::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if(*(float *)&_outletParams[1] > 0){ // draw system BPM beat - _nodeCanvas.getNodeDrawList()->AddCircleFilled(ImVec2(pos.x + (32*scaleFactor),pos.y + (8*scaleFactor)), 6*scaleFactor, IM_COL32(255, 255, 120, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(ImVec2(pos.x + (28*scaleFactor*_nodeCanvas.GetCanvasScale()),pos.y + (8*scaleFactor)), radius, IM_COL32(255, 255, 120, 255), 40); } _nodeCanvas.EndNodeContent(); diff --git a/src/objects/math/NumberOperator.cpp b/src/objects/math/NumberOperator.cpp index 0eb24dd6..15345d84 100755 --- a/src/objects/math/NumberOperator.cpp +++ b/src/objects/math/NumberOperator.cpp @@ -147,7 +147,7 @@ void NumberOperator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (46*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-50*scaleFactor); if(ImGui::BeginCombo("operator", operators_string.at(_operator).c_str() )){ diff --git a/src/objects/math/SimpleNoise.cpp b/src/objects/math/SimpleNoise.cpp index e5f37fcc..47c77f94 100644 --- a/src/objects/math/SimpleNoise.cpp +++ b/src/objects/math/SimpleNoise.cpp @@ -119,7 +119,7 @@ void SimpleNoise::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.0f, 1.0f, IM_COL32(255,255,255,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], 0.0f, 1.0f, IM_COL32(255,255,255,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/math/SimpleRandom.cpp b/src/objects/math/SimpleRandom.cpp index 00840a8f..29228397 100755 --- a/src/objects/math/SimpleRandom.cpp +++ b/src/objects/math/SimpleRandom.cpp @@ -146,7 +146,7 @@ void SimpleRandom::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], lastMinRange.get(), lastMaxRange.get(), IM_COL32(255,255,255,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], lastMinRange.get(), lastMaxRange.get(), IM_COL32(255,255,255,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/math/SineGenerator.cpp b/src/objects/math/SineGenerator.cpp index 2a6d5d62..2e1100b1 100755 --- a/src/objects/math/SineGenerator.cpp +++ b/src/objects/math/SineGenerator.cpp @@ -126,7 +126,7 @@ void SineGenerator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], -1.0f, 1.0f, IM_COL32(255,255,255,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], -1.0f, 1.0f, IM_COL32(255,255,255,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.EndNodeContent(); } diff --git a/src/objects/math/Smooth.cpp b/src/objects/math/Smooth.cpp index f5b8ff68..cc5ef196 100755 --- a/src/objects/math/Smooth.cpp +++ b/src/objects/math/Smooth.cpp @@ -131,7 +131,7 @@ void Smooth::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGuiEx::plotValue(*(float *)&_outletParams[0], minRange, maxRange, IM_COL32(255,255,255,255), this->scaleFactor); + ImGuiEx::plotValue(*(float *)&_outletParams[0], minRange, maxRange, IM_COL32(255,255,255,255), this->height*_nodeCanvas.GetCanvasScale() - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT), this->scaleFactor); _nodeCanvas.EndNodeContent(); diff --git a/src/objects/scripting/LuaScript.cpp b/src/objects/scripting/LuaScript.cpp index 3bb3e201..797ae65e 100644 --- a/src/objects/scripting/LuaScript.cpp +++ b/src/objects/scripting/LuaScript.cpp @@ -291,14 +291,12 @@ void LuaScript::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT)); - if(static_cast(_outletParams[0])->isAllocated() && kuro->getTexture().isAllocated()){ + ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); + if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - ImGui::Image(kuro->getTexture().getTextureData().textureID, ImVec2(scaledObjW, scaledObjH)); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - ImGui::Image(kuro->getTexture().getTextureData().textureID, ImVec2(scaledObjW, scaledObjH)); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/scripting/ShaderObject.cpp b/src/objects/scripting/ShaderObject.cpp index d55ec657..e89de605 100644 --- a/src/objects/scripting/ShaderObject.cpp +++ b/src/objects/scripting/ShaderObject.cpp @@ -378,14 +378,12 @@ void ShaderObject::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT)); - if(static_cast(_outletParams[0])->isAllocated() && kuro->getTexture().isAllocated()){ + ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); + if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - ImGui::Image(kuro->getTexture().getTextureData().textureID, ImVec2(scaledObjW, scaledObjH)); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - ImGui::Image(kuro->getTexture().getTextureData().textureID, ImVec2(scaledObjW, scaledObjH)); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/sound/AudioExporter.cpp b/src/objects/sound/AudioExporter.cpp index 5d2e1c1f..96a2a441 100644 --- a/src/objects/sound/AudioExporter.cpp +++ b/src/objects/sound/AudioExporter.cpp @@ -149,22 +149,23 @@ void AudioExporter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if(this->inletsConnected[0] && !static_cast(_inletParams[0])->getBuffer().empty()){ // draw waveform - ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImGui::GetWindowSize(), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); + ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImVec2(ImGui::GetWindowSize().x,this->height*_nodeCanvas.GetCanvasScale()), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); // draw signal RMS amplitude - _nodeCanvas.getNodeDrawList()->AddRectFilled(ImGui::GetWindowPos()+ImVec2(0,ImGui::GetWindowSize().y),ImGui::GetWindowPos()+ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y * (1.0f - ofClamp(static_cast(_inletParams[0])->getRMSAmplitude(),0.0,1.0))),IM_COL32(255,255,120,12)); + _nodeCanvas.getNodeDrawList()->AddRectFilled(ImGui::GetWindowPos()+ImVec2(0,this->height*_nodeCanvas.GetCanvasScale()),ImGui::GetWindowPos()+ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y * (1.0f - ofClamp(static_cast(_inletParams[0])->getRMSAmplitude(),0.0,1.0))),IM_COL32(255,255,120,12)); } ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); - ImVec2 pos = ImVec2(window_pos.x + window_size.x - (30*this->scaleFactor), window_pos.y + (40*this->scaleFactor)); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + ImVec2 pos = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,10,60)*scaleFactor), window_pos.y + IMGUI_EX_NODE_HEADER_HEIGHT + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,40)*scaleFactor)); + float radius = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,20)*scaleFactor; if (recorder.isRecording()){ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(255, 0, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(255, 0, 0, 255), 40); }else if(recorder.isPaused() && recorder.isRecording()){ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(255, 255, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(255, 255, 0, 255), 40); }else{ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(0, 255, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(0, 255, 0, 255), 40); } _nodeCanvas.EndNodeContent(); diff --git a/src/objects/sound/AudioGate.cpp b/src/objects/sound/AudioGate.cpp index 62cbc7c7..7f54a25e 100644 --- a/src/objects/sound/AudioGate.cpp +++ b/src/objects/sound/AudioGate.cpp @@ -156,14 +156,14 @@ void AudioGate::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; for(int i=1;inumInlets;i++){ if(i == openInlet){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (90*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(255,255,120,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(255,255,120,60),2.0f); } - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (90*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(255,255,120,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(255,255,120,60),2.0f); } // save object dimensions (for resizable ones) diff --git a/src/objects/sound/Crossfader.cpp b/src/objects/sound/Crossfader.cpp index 63e8aa93..5ac114c1 100755 --- a/src/objects/sound/Crossfader.cpp +++ b/src/objects/sound/Crossfader.cpp @@ -145,8 +145,7 @@ void Crossfader::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - //ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (26*scaleFactor))); // Padding top - ImGui::Dummy(ImVec2(-1,2)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(255,255,120,30)); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(255,255,120,60)); diff --git a/src/objects/sound/Mixer.cpp b/src/objects/sound/Mixer.cpp index d8eb4782..82ea9918 100755 --- a/src/objects/sound/Mixer.cpp +++ b/src/objects/sound/Mixer.cpp @@ -212,7 +212,7 @@ void Mixer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::PushStyleColor(ImGuiCol_FrameBgActive, IM_COL32(255,255,120,60)); ImGui::PushStyleColor(ImGuiCol_SliderGrab, IM_COL32(255,255,120,160)); - ImGui::VSliderFloat("##v", ImVec2(sliderW*scaleFactor, 150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor)), &levels_float[i], 0.0f, 1.0f, ""); + ImGui::VSliderFloat("##v", ImVec2(sliderW*scaleFactor, (150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor))*_nodeCanvas.GetCanvasScale()), &levels_float[i], 0.0f, 1.0f, ""); if (ImGui::IsItemActive() || ImGui::IsItemHovered()){ ImGui::SetTooltip("s%i %.2f", i+1, levels_float[i]); this->setCustomVar(levels_float[i],"LEVEL_"+ofToString(i+1)); @@ -227,7 +227,7 @@ void Mixer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(255,255,120,60)); ImGui::PushStyleColor(ImGuiCol_FrameBgActive, IM_COL32(255,255,120,60)); ImGui::PushStyleColor(ImGuiCol_SliderGrab, IM_COL32(255,255,120,160)); - ImGui::VSliderFloat("##main_volume", ImVec2(sliderW*scaleFactor, 150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor)), &mainlevel_float, 0.0f, 1.0f, ""); + ImGui::VSliderFloat("##main_volume", ImVec2(sliderW*scaleFactor, (150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor))*_nodeCanvas.GetCanvasScale()), &mainlevel_float, 0.0f, 1.0f, ""); if(ImGui::IsItemActive() || ImGui::IsItemHovered()){ ImGui::SetTooltip("Main Volume %.2f", mainlevel_float); this->setCustomVar(mainlevel_float,"MAIN_LEVEL"); @@ -236,15 +236,15 @@ void Mixer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::SameLine(); - ImGuiEx::VUMeter(_nodeCanvas.getNodeDrawList(), sliderW*scaleFactor/4.0f, 150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor), static_cast(_outletParams[0])->getRMSAmplitude(), false); + ImGuiEx::VUMeter(_nodeCanvas.getNodeDrawList(), sliderW*scaleFactor/4.0f, (150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor))*_nodeCanvas.GetCanvasScale(), static_cast(_outletParams[0])->getRMSAmplitude(), false); ImGui::SameLine(); - ImGuiEx::VUMeter(_nodeCanvas.getNodeDrawList(), sliderW*scaleFactor/4.0f, 150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor), static_cast(_outletParams[1])->getRMSAmplitude(), false); + ImGuiEx::VUMeter(_nodeCanvas.getNodeDrawList(), sliderW*scaleFactor/4.0f, (150.0f*scaleFactor - (26*scaleFactor + IMGUI_EX_NODE_CONTENT_PADDING*3*scaleFactor))*_nodeCanvas.GetCanvasScale(), static_cast(_outletParams[1])->getRMSAmplitude(), false); - ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); + ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*4*scaleFactor*_nodeCanvas.GetCanvasScale())); for(int i=0;inumInlets-1;i++){ sprintf_s(temp,"PAN s%i",i+1); - if(ImGuiKnobs::Knob(temp, &pans_float[i], -1.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Stepped)){ + if(ImGuiKnobs::Knob(temp, &pans_float[i], -1.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Stepped,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(pans_float[i],"PAN_"+ofToString(i+1)); } @@ -252,6 +252,8 @@ void Mixer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ } + sliderW = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,126); + _nodeCanvas.EndNodeContent(); } @@ -340,7 +342,7 @@ void Mixer::resetInletsSettings(){ this->numInlets = signalInlets+1; - this->width = 20*scaleFactor + signalInlets*(sliderW+6.0f)*scaleFactor + sliderW*scaleFactor/8.0f + sliderW*scaleFactor + (sliderW*scaleFactor*2) + 10*scaleFactor; // inlets gap + sliders + gap + main + vumeters + outlets gap + this->width = 20*scaleFactor + signalInlets*(56.0f+6.0f)*scaleFactor + 56.0f*scaleFactor/8.0f + 56.0f*scaleFactor + (56.0f*scaleFactor*2) + 10*scaleFactor; // inlets gap + sliders + gap + main + vumeters + outlets gap _inletParams[0] = new vector(); static_cast *>(_inletParams[0])->clear(); diff --git a/src/objects/sound/Oscillator.cpp b/src/objects/sound/Oscillator.cpp index 8ec890cb..9c8f9894 100755 --- a/src/objects/sound/Oscillator.cpp +++ b/src/objects/sound/Oscillator.cpp @@ -308,53 +308,53 @@ void Oscillator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*scaleFactor)); - if(ImGuiKnobs::Knob("pitch", &pitch_float, 0.0f, 127.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("pitch", &pitch_float, 0.0f, 127.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(pitch_float,"PITCH"); pitch_ctrl.set(pitch_float); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("level", &level_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("level", &level_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ level_ctrl.set(level_float); this->setCustomVar(level_float,"LEVEL"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("detune", &detune_float, -12.0f, 12.0f, 0.005f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("detune", &detune_float, -12.0f, 12.0f, 0.005f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ detuneCoarse_ctrl.set(detune_float); this->setCustomVar(detune_float,"DETUNE_COARSE"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("fine", &fine_float, -1.0f, 1.0f, 0.005f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("fine", &fine_float, -1.0f, 1.0f, 0.005f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ detuneFine_ctrl.set(fine_float); this->setCustomVar(fine_float,"DETUNE_FINE"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("pw", &pw_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("pw", &pw_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ pw_ctrl.set(pw_float); this->setCustomVar(pw_float,"PULSE_WIDTH"); } ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); - if(ImGuiKnobs::Knob("sine", &sine_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("sine", &sine_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ sine_ctrl.set(sine_float); this->setCustomVar(sine_float,"SINE_LEVEL"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("triangle", &triangle_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("triangle", &triangle_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ triangle_ctrl.set(triangle_float); this->setCustomVar(triangle_float,"TRIANGLE_LEVEL"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("saw", &saw_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("saw", &saw_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ saw_ctrl.set(saw_float); this->setCustomVar(saw_float,"SAW_LEVEL"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("pulse", &pulse_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("pulse", &pulse_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ pulse_ctrl.set(pulse_float); this->setCustomVar(pulse_float,"PULSE_LEVEL"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("noise", &noise_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("noise", &noise_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ noise_ctrl.set(noise_float); this->setCustomVar(noise_float,"NOISE_LEVEL"); } diff --git a/src/objects/sound/Panner.cpp b/src/objects/sound/Panner.cpp index 61c90d2e..44648f43 100755 --- a/src/objects/sound/Panner.cpp +++ b/src/objects/sound/Panner.cpp @@ -144,9 +144,9 @@ void Panner::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(20.0f*scaleFactor,0.0f));ImGui::SameLine(); + ImGui::SetCursorPos(ImVec2((this->width/2 - 26*this->scaleFactor) *_nodeCanvas.GetCanvasScale(), (this->height/2 - 48*this->scaleFactor) *_nodeCanvas.GetCanvasScale())); - if(ImGuiKnobs::Knob("", &pan, -1.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Stepped)){ + if(ImGuiKnobs::Knob("", &pan, -1.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Stepped,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ pan_ctrl.set(pan); this->setCustomVar(pan,"PAN"); } @@ -160,7 +160,7 @@ void Panner::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ void Panner::drawObjectNodeConfig(){ ImGuiEx::ObjectInfo( "Basic stereo panner", - "https://mosaic.d3cod3.org/reference.php?r=panner", scaleFactor); + "https://mosaic.d3cod3.org/reference.php?r=panner", this->scaleFactor); } //-------------------------------------------------------------- diff --git a/src/objects/sound/QuadPanner.cpp b/src/objects/sound/QuadPanner.cpp index 8377ba0b..13da2035 100755 --- a/src/objects/sound/QuadPanner.cpp +++ b/src/objects/sound/QuadPanner.cpp @@ -174,7 +174,7 @@ void QuadPanner::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - if(ImGuiEx::Pad2D(_nodeCanvas.getNodeDrawList(), 0, ImGui::GetWindowSize().y - 26,&padX,&padY)){ + if(ImGuiEx::Pad2D(_nodeCanvas.getNodeDrawList(), 0, (this->height*_nodeCanvas.GetCanvasScale()) - (26*this->scaleFactor),&padX,&padY)){ this->setCustomVar(padX,"XPOS"); this->setCustomVar(padY,"YPOS"); } diff --git a/src/objects/sound/SamplePlayer.cpp b/src/objects/sound/SamplePlayer.cpp index eb12068e..43fe2f73 100755 --- a/src/objects/sound/SamplePlayer.cpp +++ b/src/objects/sound/SamplePlayer.cpp @@ -257,7 +257,7 @@ void SamplePlayer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ if(isFileLoaded && sampleBuffer.loaded()){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); ImVec2 ph_pos = ImVec2(window_pos.x + (20*scaleFactor), window_pos.y + (20*scaleFactor)); objOriginX = ImGui::GetWindowPos().x + ((IMGUI_EX_NODE_PINS_WIDTH_NORMAL - 1)*this->scaleFactor); diff --git a/src/objects/sound/SigMult.cpp b/src/objects/sound/SigMult.cpp index 0d180a7b..2e2cefa3 100755 --- a/src/objects/sound/SigMult.cpp +++ b/src/objects/sound/SigMult.cpp @@ -135,7 +135,7 @@ void SigMult::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (26*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(255,255,120,30)); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(255,255,120,60)); diff --git a/src/objects/sound/SignalOperator.cpp b/src/objects/sound/SignalOperator.cpp index 89b843eb..5e0ffa48 100755 --- a/src/objects/sound/SignalOperator.cpp +++ b/src/objects/sound/SignalOperator.cpp @@ -132,7 +132,7 @@ void SignalOperator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,2)); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-50*scaleFactor); if(ImGui::BeginCombo("operator", operators_string.at(_operator).c_str() )){ diff --git a/src/objects/sound/SoundfilePlayer.cpp b/src/objects/sound/SoundfilePlayer.cpp index 58b93f75..89138f6a 100755 --- a/src/objects/sound/SoundfilePlayer.cpp +++ b/src/objects/sound/SoundfilePlayer.cpp @@ -286,7 +286,7 @@ void SoundfilePlayer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ if(isFileLoaded && audiofile.loaded()){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); ImVec2 ph_pos = ImVec2(window_pos.x + (20*scaleFactor), window_pos.y + (20*scaleFactor)); objOriginX = ImGui::GetWindowPos().x + ((IMGUI_EX_NODE_PINS_WIDTH_NORMAL - 1)*this->scaleFactor); diff --git a/src/objects/sound/pdspADSR.cpp b/src/objects/sound/pdspADSR.cpp index 17d0beb4..527e3d86 100755 --- a/src/objects/sound/pdspADSR.cpp +++ b/src/objects/sound/pdspADSR.cpp @@ -192,19 +192,19 @@ void pdspADSR::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGuiEx::EnvelopeEditor(_nodeCanvas.getNodeDrawList(), 0, ImGui::GetWindowSize().y*0.3, &attackDuration, &decayDuration, &sustainLevel, &releaseDuration, ImGuiEnvelopeEditorType_ADSR); ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if(ImGuiKnobs::Knob("A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(attackDuration,"ATTACK"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("D", &decayDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("D", &decayDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(decayDuration,"DECAY"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("S", &sustainLevel, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("S", &sustainLevel, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(sustainLevel,"SUSTAIN"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(releaseDuration,"RELEASE"); } diff --git a/src/objects/sound/pdspAHR.cpp b/src/objects/sound/pdspAHR.cpp index dea2d516..d6787c20 100755 --- a/src/objects/sound/pdspAHR.cpp +++ b/src/objects/sound/pdspAHR.cpp @@ -180,15 +180,15 @@ void pdspAHR::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGuiEx::EnvelopeEditor(_nodeCanvas.getNodeDrawList(), 0, ImGui::GetWindowSize().y*0.3, &attackDuration, &holdDuration, &releaseDuration, &releaseDuration, ImGuiEnvelopeEditorType_AHR); - if(ImGuiKnobs::Knob("A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(attackDuration,"ATTACK"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("H", &holdDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("H", &holdDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(holdDuration,"HOLD"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(releaseDuration,"RELEASE"); } diff --git a/src/objects/sound/pdspBitCruncher.cpp b/src/objects/sound/pdspBitCruncher.cpp index 30348ee5..3d35b604 100755 --- a/src/objects/sound/pdspBitCruncher.cpp +++ b/src/objects/sound/pdspBitCruncher.cpp @@ -135,7 +135,7 @@ void pdspBitCruncher::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (26*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(255,255,120,30)); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(255,255,120,60)); diff --git a/src/objects/sound/pdspBitNoise.cpp b/src/objects/sound/pdspBitNoise.cpp index 0379eeb2..eb960381 100755 --- a/src/objects/sound/pdspBitNoise.cpp +++ b/src/objects/sound/pdspBitNoise.cpp @@ -169,18 +169,18 @@ void pdspBitNoise::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if (ImGuiKnobs::Knob("pitch", &pitch, -100.0f, 150.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)) { + ImGui::Dummy(ImVec2(0,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-20,40)*scaleFactor)); + if (ImGuiKnobs::Knob("pitch", &pitch, -100.0f, 150.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)) { pitch_ctrl.set(pitch); this->setCustomVar(pitch,"PITCH"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if (ImGuiKnobs::Knob("decimation", &decimation, 1.0f, 200.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)) { + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if (ImGuiKnobs::Knob("decimation", &decimation, 1.0f, 200.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)) { decimation_ctrl.set(decimation); this->setCustomVar(decimation,"DECIMATION"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if (ImGuiKnobs::Knob("bits", &bits, 0.0f, 8.0f, 0.07f, "%.2f", ImGuiKnobVariant_Wiper)) { + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if (ImGuiKnobs::Knob("bits", &bits, 0.0f, 8.0f, 0.07f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)) { bits_ctrl.set(bits); this->setCustomVar(bits,"BITS"); } diff --git a/src/objects/sound/pdspChorusEffect.cpp b/src/objects/sound/pdspChorusEffect.cpp index 3f4841ec..452a7c1b 100755 --- a/src/objects/sound/pdspChorusEffect.cpp +++ b/src/objects/sound/pdspChorusEffect.cpp @@ -169,22 +169,22 @@ void pdspChorusEffect::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(0,4*scaleFactor)); + ImGui::Dummy(ImVec2(0,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-20,40)*scaleFactor)); - if(ImGuiKnobs::Knob("speed", &speed, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("speed", &speed, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ speed_ctrl.set(speed); this->setCustomVar(speed,"SPEED"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("depth", &depth, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("depth", &depth, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ depth_ctrl.set(depth); this->setCustomVar(depth,"DEPTH"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("delay", &delay, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("delay", &delay, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ delay_ctrl.set(delay); this->setCustomVar(delay,"DELAY"); } diff --git a/src/objects/sound/pdspCombFilter.cpp b/src/objects/sound/pdspCombFilter.cpp index 16c19d45..5c7996e4 100755 --- a/src/objects/sound/pdspCombFilter.cpp +++ b/src/objects/sound/pdspCombFilter.cpp @@ -168,20 +168,20 @@ void pdspCombFilter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(0,4*scaleFactor)); + ImGui::Dummy(ImVec2(0,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-20,40)*scaleFactor)); - if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 127.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 127.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ pitch_ctrl.set(pitch); this->setCustomVar(static_cast(pitch),"PITCH"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("damping", &damping, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("damping", &damping, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ damping_ctrl.set(damping); this->setCustomVar(static_cast(damping),"DAMPING"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("feedback", &feedback, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("feedback", &feedback, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ feedback_ctrl.set(feedback); this->setCustomVar(static_cast(feedback),"FEEDBACK"); } diff --git a/src/objects/sound/pdspCompressor.cpp b/src/objects/sound/pdspCompressor.cpp index 2d06d9d3..f139a835 100755 --- a/src/objects/sound/pdspCompressor.cpp +++ b/src/objects/sound/pdspCompressor.cpp @@ -218,27 +218,27 @@ void pdspCompressor::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*scaleFactor)); - if(ImGuiKnobs::Knob("attack", &attack, 1.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("attack", &attack, 1.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ attack_ctrl.set(attack); this->setCustomVar(attack,"ATTACK"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("release", &release, 1.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("release", &release, 1.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ release_ctrl.set(release); this->setCustomVar(release,"RELEASE"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("thresh", &thresh, -48.0f, 0.0f, 0.1f, "%.2fdb", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("thresh", &thresh, -48.0f, 0.0f, 0.1f, "%.2fdb", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ thresh_ctrl.set(thresh); this->setCustomVar(thresh,"THRESH"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("ratio", &ratio, 1.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("ratio", &ratio, 1.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ ratio_ctrl.set(ratio); this->setCustomVar(ratio,"RATIO"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("knee", &knee, -48.0f, 0.0f, 0.1f, "%.2fdb", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("knee", &knee, -48.0f, 0.0f, 0.1f, "%.2fdb", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ knee_ctrl.set(knee); this->setCustomVar(knee,"KNEE"); } diff --git a/src/objects/sound/pdspDataOscillator.cpp b/src/objects/sound/pdspDataOscillator.cpp index d5a624c9..9081e44c 100755 --- a/src/objects/sound/pdspDataOscillator.cpp +++ b/src/objects/sound/pdspDataOscillator.cpp @@ -183,7 +183,7 @@ void pdspDataOscillator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ // draw waveform - ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y*0.5f), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); + ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImVec2(ImGui::GetWindowSize().x,this->height*0.5f*_nodeCanvas.GetCanvasScale()), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); char temp[128]; sprintf_s(temp,"%.2f Hz", pdsp::PitchToFreq::eval(ofClamp(pitch,0,127))); @@ -194,7 +194,7 @@ void pdspDataOscillator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Spacing(); ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*scaleFactor)); - if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 127.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 127.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(pitch,"PITCH"); pitch_ctrl.set(pitch); } diff --git a/src/objects/sound/pdspDecimator.cpp b/src/objects/sound/pdspDecimator.cpp index bc160fb5..b0023946 100755 --- a/src/objects/sound/pdspDecimator.cpp +++ b/src/objects/sound/pdspDecimator.cpp @@ -132,7 +132,7 @@ void pdspDecimator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (26*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(255,255,120,30)); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(255,255,120,60)); diff --git a/src/objects/sound/pdspDelay.cpp b/src/objects/sound/pdspDelay.cpp index c6638333..850ce5b0 100755 --- a/src/objects/sound/pdspDelay.cpp +++ b/src/objects/sound/pdspDelay.cpp @@ -171,16 +171,16 @@ void pdspDelay::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if(ImGuiKnobs::Knob("TIME", &time, 0.0f, DELAY_MAX_TIME, 10.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::Dummy(ImVec2(0,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-20,40)*scaleFactor)); + if(ImGuiKnobs::Knob("TIME", &time, 0.0f, DELAY_MAX_TIME, 10.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(time,"TIME"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("DAMPING", &damping, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("DAMPING", &damping, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(damping,"DAMPING"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("FEEDBACK", &feedback, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("FEEDBACK", &feedback, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(feedback,"FEEDBACK"); } diff --git a/src/objects/sound/pdspDucker.cpp b/src/objects/sound/pdspDucker.cpp index b2b7cf0f..564d3e06 100755 --- a/src/objects/sound/pdspDucker.cpp +++ b/src/objects/sound/pdspDucker.cpp @@ -216,22 +216,22 @@ void pdspDucker::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if(ImGuiKnobs::Knob("DUCK", &ducking, -48.0f, 0.0f, 0.1f, "%.2fdb", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("DUCK", &ducking, -48.0f, 0.0f, 0.1f, "%.2fdb", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ duck_ctrl.set(ducking); this->setCustomVar(ducking,"DUCKING"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ attack_ctrl.set(attackDuration); this->setCustomVar(attackDuration,"ATTACK"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("H", &holdDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("H", &holdDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ hold_ctrl.set(holdDuration); this->setCustomVar(holdDuration,"HOLD"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ release_ctrl.set(releaseDuration); this->setCustomVar(releaseDuration,"RELEASE"); } diff --git a/src/objects/sound/pdspHiCut.cpp b/src/objects/sound/pdspHiCut.cpp index 8e76af1d..0233418b 100755 --- a/src/objects/sound/pdspHiCut.cpp +++ b/src/objects/sound/pdspHiCut.cpp @@ -140,7 +140,7 @@ void pdspHiCut::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); diff --git a/src/objects/sound/pdspKick.cpp b/src/objects/sound/pdspKick.cpp index bbfa76c7..1cd034b8 100755 --- a/src/objects/sound/pdspKick.cpp +++ b/src/objects/sound/pdspKick.cpp @@ -244,70 +244,70 @@ void pdspKick::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if(ImGuiKnobs::Knob( "A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "A", &attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(attackDuration,"ATTACK"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "D", &decayDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "D", &decayDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(decayDuration,"DECAY"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "S", &sustainLevel, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "S", &sustainLevel, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(sustainLevel,"SUSTAIN"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "R", &releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(releaseDuration,"RELEASE"); } ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); - if(ImGuiKnobs::Knob( "FREQ A", &f_attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "FREQ A", &f_attackDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(f_attackDuration,"FREQ_ATTACK"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "FREQ D", &f_decayDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "FREQ D", &f_decayDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(f_decayDuration,"FREQ_DECAY"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "FREQ S", &f_sustainLevel, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "FREQ S", &f_sustainLevel, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(f_sustainLevel,"FREQ_SUSTAIN"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "FREQ R", &f_releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "FREQ R", &f_releaseDuration, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(f_releaseDuration,"FREQ_RELEASE"); } ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); - if(ImGuiKnobs::Knob( "FREQ", &oscFreq, 0.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "FREQ", &oscFreq, 0.0f, 100.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ osc_freq_ctrl.set(pdsp::f2p(oscFreq)); this->setCustomVar(oscFreq,"OSC_FREQ"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "F. FREQ", &filterFreq, 0.0f, 8260.0f, 10.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "F. FREQ", &filterFreq, 0.0f, 8260.0f, 10.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ filter_freq_ctrl.set(pdsp::f2p(filterFreq)); this->setCustomVar(filterFreq,"FILTER_FREQ"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "F. RES", &filterRes, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "F. RES", &filterRes, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ filter_res_ctrl.set(filterRes); this->setCustomVar(filterRes,"FILTER_RES"); } ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); - if(ImGuiKnobs::Knob( "RATIO", &compRatio, 1.0f, 40.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "RATIO", &compRatio, 1.0f, 40.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ comp_ratio_ctrl.set(compRatio); this->setCustomVar(compRatio,"COMP_RATIO"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "COMP A", &compAttack, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "COMP A", &compAttack, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ comp_A_ctrl.set(compAttack); this->setCustomVar(compAttack,"COMP_A"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob( "COMP R", &compRelease, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob( "COMP R", &compRelease, 0.0f, 1000.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ comp_R_ctrl.set(compRelease); this->setCustomVar(compRelease,"COMP_R"); } diff --git a/src/objects/sound/pdspLFO.cpp b/src/objects/sound/pdspLFO.cpp index 25cda044..ac25bfb2 100755 --- a/src/objects/sound/pdspLFO.cpp +++ b/src/objects/sound/pdspLFO.cpp @@ -181,14 +181,14 @@ void pdspLFO::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 10.0f, 0.01f, "%.5f", ImGuiKnobVariant_Wiper)){ + ImGui::Dummy(ImVec2(0,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-20,40)*scaleFactor)); + if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 10.0f, 0.01f, "%.5f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ pitch_ctrl.set(pitch); this->setCustomVar(pitch,"FREQUENCY"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(32*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("phase", &phase, -1.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,80)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("phase", &phase, -1.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ phase_ctrl.set(phase); this->setCustomVar(phase,"PHASE"); } diff --git a/src/objects/sound/pdspLowCut.cpp b/src/objects/sound/pdspLowCut.cpp index e937b776..22dc7b6a 100755 --- a/src/objects/sound/pdspLowCut.cpp +++ b/src/objects/sound/pdspLowCut.cpp @@ -139,7 +139,7 @@ void pdspLowCut::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); diff --git a/src/objects/sound/pdspParametricEQ.cpp b/src/objects/sound/pdspParametricEQ.cpp index 57eff098..5835ae4b 100755 --- a/src/objects/sound/pdspParametricEQ.cpp +++ b/src/objects/sound/pdspParametricEQ.cpp @@ -223,15 +223,15 @@ void pdspParametricEQ::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // LF - if(ImGuiKnobs::Knob("Freq Hz", &float_l1freq, 20.0f, 500.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("Freq Hz", &float_l1freq, 20.0f, 500.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(float_l1freq,"LF_FREQ"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("Q", &float_l1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("Q", &float_l1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(float_l1Q,"LF_Q"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("Gain dB", &float_l1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("Gain dB", &float_l1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(float_l1gain,"LF_GAIN"); } diff --git a/src/objects/sound/pdspResonant2PoleFilter.cpp b/src/objects/sound/pdspResonant2PoleFilter.cpp index d9ec1f3e..1204013d 100755 --- a/src/objects/sound/pdspResonant2PoleFilter.cpp +++ b/src/objects/sound/pdspResonant2PoleFilter.cpp @@ -182,18 +182,18 @@ void pdspResonant2PoleFilter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanva // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 127.0f, 0.3f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::Dummy(ImVec2(0,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-20,40)*scaleFactor)); + if(ImGuiKnobs::Knob("pitch", &pitch, 0.0f, 127.0f, 0.3f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ pitch_ctrl.set(pitch); this->setCustomVar(static_cast(pitch),"PITCH"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("cutoff", &cutoff, 0.0f, 127.0f, 0.3f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("cutoff", &cutoff, 0.0f, 127.0f, 0.3f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ cutoff_ctrl.set(cutoff); this->setCustomVar(cutoff,"CUTOFF"); } - ImGui::SameLine();ImGui::Dummy(ImVec2(40*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("resonance", &resonance, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::SameLine();ImGui::Dummy(ImVec2(ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,0,90)*scaleFactor,-1));ImGui::SameLine(); + if(ImGuiKnobs::Knob("resonance", &resonance, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ resonance_ctrl.set(resonance); this->setCustomVar(resonance,"RESONANCE"); } diff --git a/src/objects/sound/pdspReverb.cpp b/src/objects/sound/pdspReverb.cpp index 94d685e0..648d8abf 100755 --- a/src/objects/sound/pdspReverb.cpp +++ b/src/objects/sound/pdspReverb.cpp @@ -204,24 +204,24 @@ void pdspReverb::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(0,4*scaleFactor)); - if(ImGuiKnobs::Knob("TIME", &time, 0.0f, 60.0f, 0.05f, "%.2f", ImGuiKnobVariant_Wiper)){ + ImGui::Dummy(ImVec2(0,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,-20,40)*scaleFactor)); + if(ImGuiKnobs::Knob("TIME", &time, 0.0f, 60.0f, 0.05f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(time,"TIME"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("DENSITY", &density, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("DENSITY", &density, 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(density,"DENSITY"); } ImGui::SameLine();ImGui::Dummy(ImVec2(6*scaleFactor,-1));ImGui::SameLine(); - if(ImGuiKnobs::Knob("DAMPING", &damping, 0.0f, 2.0f, 0.002f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("DAMPING", &damping, 0.0f, 2.0f, 0.002f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(damping,"DAMPING"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("SPEED", &modSpeed, 0.0f, 20.0f, 0.02f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("SPEED", &modSpeed, 0.0f, 20.0f, 0.02f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(modSpeed,"MODSPEED"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("AMOUNT", &modAmount, 0.0f, 2.0f, 0.002f, "%.2f", ImGuiKnobVariant_Wiper)){ + if(ImGuiKnobs::Knob("AMOUNT", &modAmount, 0.0f, 2.0f, 0.002f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(modAmount,"MODAMOUNT"); } diff --git a/src/objects/sound/pdspSequencer.cpp b/src/objects/sound/pdspSequencer.cpp index f0952ff8..9c6649be 100755 --- a/src/objects/sound/pdspSequencer.cpp +++ b/src/objects/sound/pdspSequencer.cpp @@ -305,7 +305,7 @@ void pdspSequencer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); char temp[32]; @@ -320,7 +320,7 @@ void pdspSequencer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); for(size_t i=0;iscaleFactor)){ this->setCustomVar(seqSteps[i + (chapter*CHAPTER_STEPS)],"S_"+ofToString(i+1+ (chapter*CHAPTER_STEPS))); } if(i<15){ @@ -331,7 +331,7 @@ void pdspSequencer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*4*scaleFactor)); for(size_t i=0;iscaleFactor)){ this->setCustomVar(ctrl1Steps[i + (chapter*CHAPTER_STEPS)],"A_"+ofToString(i+1+ (chapter*CHAPTER_STEPS))); } if(i<15){ @@ -342,7 +342,7 @@ void pdspSequencer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*4*scaleFactor)); for(size_t i=0;iscaleFactor)){ this->setCustomVar(ctrl2Steps[i + (chapter*CHAPTER_STEPS)],"B_"+ofToString(i+1+ (chapter*CHAPTER_STEPS))); } if(i<15){ @@ -353,7 +353,7 @@ void pdspSequencer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*4*scaleFactor)); for(size_t i=0;iscaleFactor)){ this->setCustomVar(ctrl3Steps[i + (chapter*CHAPTER_STEPS)],"C_"+ofToString(i+1+ (chapter*CHAPTER_STEPS))); } if(i<15){ @@ -364,7 +364,7 @@ void pdspSequencer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*4*scaleFactor)); for(size_t i=0;iscaleFactor)){ this->setCustomVar(ctrl4Steps[i + (chapter*CHAPTER_STEPS)],"D_"+ofToString(i+1+ (chapter*CHAPTER_STEPS))); } if(i<15){ diff --git a/src/objects/string/StringAt.cpp b/src/objects/string/StringAt.cpp index 34a5b5c5..097bcfb5 100755 --- a/src/objects/string/StringAt.cpp +++ b/src/objects/string/StringAt.cpp @@ -128,7 +128,7 @@ void StringAt::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,ImGui::GetWindowSize().y/2 - (26*scaleFactor))); // Padding top + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); ImGui::PushItemWidth(-1); if(ImGui::DragInt("", &stringAt)){ if(stringAt < 0){ diff --git a/src/objects/string/StringConcat.cpp b/src/objects/string/StringConcat.cpp index 09d6f7bb..fdb47c9c 100755 --- a/src/objects/string/StringConcat.cpp +++ b/src/objects/string/StringConcat.cpp @@ -142,14 +142,14 @@ void StringConcat::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; for(int i=0;inumInlets;i++){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (14*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(200,180,255,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (14*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(200,180,255,60),2.0f); if(i==this->numInlets-1){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2)),IM_COL32(200,180,255,60),2.0f); - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + ((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(200,180,255,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2)),IM_COL32(200,180,255,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (114*this->scaleFactor*_nodeCanvas.GetCanvasScale()),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + ((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(200,180,255,60),2.0f); } } diff --git a/src/objects/string/StringExtract.cpp b/src/objects/string/StringExtract.cpp index e9eb19bd..f62f4331 100755 --- a/src/objects/string/StringExtract.cpp +++ b/src/objects/string/StringExtract.cpp @@ -128,7 +128,7 @@ void StringExtract::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - ImGui::Dummy(ImVec2(-1,10*scaleFactor)); + ImGui::SetCursorPos(ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL+(4*scaleFactor), (this->height/2 *_nodeCanvas.GetCanvasScale()) - (6*scaleFactor))); if(static_cast(static_cast(_outletParams[0])->size()) > 0){ ImGui::Text("size\nrange"); ImGui::SameLine(); @@ -155,7 +155,7 @@ void StringExtract::drawObjectNodeConfig(){ } ImGui::Spacing(); int prevEnd = end; - if(ImGui::InputInt("End",&end)){ + if(ImGui::InputInt("Size",&end)){ if(end > start && end <= static_cast(_inletParams[0])->size()){ this->setCustomVar(static_cast(end),"END"); }else{ diff --git a/src/objects/string/StringGate.cpp b/src/objects/string/StringGate.cpp index fdd9dac0..0130d1a0 100644 --- a/src/objects/string/StringGate.cpp +++ b/src/objects/string/StringGate.cpp @@ -153,14 +153,14 @@ void StringGate::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; for(int i=1;inumInlets;i++){ if(i == openInlet){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (90*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(200,180,255,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(200,180,255,60),2.0f); } - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (90*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(200,180,255,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(200,180,255,60),2.0f); } // save object dimensions (for resizable ones) diff --git a/src/objects/string/StringMultiplexer.cpp b/src/objects/string/StringMultiplexer.cpp index 0f4c15a0..28a23298 100755 --- a/src/objects/string/StringMultiplexer.cpp +++ b/src/objects/string/StringMultiplexer.cpp @@ -148,7 +148,7 @@ void StringMultiplexer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; for(int i=0;inumInlets;i++){ diff --git a/src/objects/video/KinectGrabber.cpp b/src/objects/video/KinectGrabber.cpp index e960011a..05055018 100644 --- a/src/objects/video/KinectGrabber.cpp +++ b/src/objects/video/KinectGrabber.cpp @@ -202,14 +202,11 @@ void KinectGrabber::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(weHaveKinect && static_cast(_outletParams[2])->isInitialized() && static_cast(_outletParams[2])->isConnected() && static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/video/ToGrayScaleTexture.cpp b/src/objects/video/ToGrayScaleTexture.cpp index 6f45a504..536253a0 100644 --- a/src/objects/video/ToGrayScaleTexture.cpp +++ b/src/objects/video/ToGrayScaleTexture.cpp @@ -148,14 +148,11 @@ void ToGrayScaleTexture::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated() && static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/video/VideoCrop.cpp b/src/objects/video/VideoCrop.cpp index 85f60e63..b4867e67 100644 --- a/src/objects/video/VideoCrop.cpp +++ b/src/objects/video/VideoCrop.cpp @@ -190,14 +190,11 @@ void VideoCrop::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/video/VideoDelay.cpp b/src/objects/video/VideoDelay.cpp index e87e92f5..516edc41 100644 --- a/src/objects/video/VideoDelay.cpp +++ b/src/objects/video/VideoDelay.cpp @@ -203,14 +203,11 @@ void VideoDelay::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/video/VideoExporter.cpp b/src/objects/video/VideoExporter.cpp index b958ea9a..a5c5d7a5 100644 --- a/src/objects/video/VideoExporter.cpp +++ b/src/objects/video/VideoExporter.cpp @@ -200,14 +200,11 @@ void VideoExporter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_inletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_inletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF @@ -226,14 +223,15 @@ void VideoExporter::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ } window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); - ImVec2 pos = ImVec2(window_pos.x + window_size.x - (30*this->scaleFactor), window_pos.y + (40*this->scaleFactor)); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + ImVec2 pos = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,10,60)*scaleFactor), window_pos.y + IMGUI_EX_NODE_HEADER_HEIGHT + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,40)*scaleFactor)); + float radius = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,20)*scaleFactor; if (recorder.isRecording()){ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(255, 0, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(255, 0, 0, 255), 40); }else if(recorder.isPaused() && recorder.isRecording()){ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(255, 255, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(255, 255, 0, 255), 40); }else{ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(0, 255, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(0, 255, 0, 255), 40); } _nodeCanvas.EndNodeContent(); diff --git a/src/objects/video/VideoGate.cpp b/src/objects/video/VideoGate.cpp index 4968dda1..e3b12f03 100644 --- a/src/objects/video/VideoGate.cpp +++ b/src/objects/video/VideoGate.cpp @@ -169,14 +169,14 @@ void VideoGate::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; for(int i=1;inumInlets;i++){ if(i == openInlet){ - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (90*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(120,255,255,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),IM_COL32(120,255,255,60),2.0f); } - _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (90*this->scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(120,255,255,60),2.0f); + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,2,180)*scaleFactor),window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(120,255,255,60),2.0f); } // save object dimensions (for resizable ones) diff --git a/src/objects/video/VideoGrabber.cpp b/src/objects/video/VideoGrabber.cpp index 04f1e8bb..8c3620f3 100644 --- a/src/objects/video/VideoGrabber.cpp +++ b/src/objects/video/VideoGrabber.cpp @@ -186,13 +186,11 @@ void VideoGrabber::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if(isOneDeviceAvailable){ if(vidGrabber->isInitialized() && !needReset){ + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } } } diff --git a/src/objects/video/VideoMixer.cpp b/src/objects/video/VideoMixer.cpp index 48dd7905..cf5d210c 100644 --- a/src/objects/video/VideoMixer.cpp +++ b/src/objects/video/VideoMixer.cpp @@ -218,14 +218,11 @@ void VideoMixer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/video/VideoPlayer.cpp b/src/objects/video/VideoPlayer.cpp index 6daaace0..ff5be26d 100644 --- a/src/objects/video/VideoPlayer.cpp +++ b/src/objects/video/VideoPlayer.cpp @@ -311,16 +311,13 @@ void VideoPlayer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(isFileLoaded && video->isLoaded()){ if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); } - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } @@ -331,7 +328,7 @@ void VideoPlayer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ scaledObjH = this->height - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor/_nodeCanvas.GetCanvasScale(); window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); ImVec2 ph_pos = ImVec2(window_pos.x + (20*this->scaleFactor), window_pos.y + (20*this->scaleFactor)); if(static_cast(_outletParams[0])->isAllocated()){ diff --git a/src/objects/video/VideoStreaming.cpp b/src/objects/video/VideoStreaming.cpp index 81f8e15e..27452440 100644 --- a/src/objects/video/VideoStreaming.cpp +++ b/src/objects/video/VideoStreaming.cpp @@ -189,14 +189,11 @@ void VideoStreaming::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_inletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_inletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF @@ -215,12 +212,13 @@ void VideoStreaming::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ } window_pos = ImGui::GetWindowPos(); - ImVec2 window_size = ImGui::GetWindowSize(); - ImVec2 pos = ImVec2(window_pos.x + window_size.x - (30*this->scaleFactor), window_pos.y + (40*this->scaleFactor)); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + ImVec2 pos = ImVec2(window_pos.x + window_size.x - (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,10,60)*scaleFactor), window_pos.y + IMGUI_EX_NODE_HEADER_HEIGHT + (ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,40)*scaleFactor)); + float radius = ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,1,20)*scaleFactor; if (isSending){ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(255, 0, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(255, 0, 0, 255), 40); }else{ - _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, 10*this->scaleFactor, IM_COL32(0, 255, 0, 255), 40); + _nodeCanvas.getNodeDrawList()->AddCircleFilled(pos, radius, IM_COL32(0, 255, 0, 255), 40); } _nodeCanvas.EndNodeContent(); diff --git a/src/objects/video/VideoTimelapse.cpp b/src/objects/video/VideoTimelapse.cpp index 6ea543f6..7658a747 100644 --- a/src/objects/video/VideoTimelapse.cpp +++ b/src/objects/video/VideoTimelapse.cpp @@ -187,14 +187,11 @@ void VideoTimelapse::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/video/VideoTransform.cpp b/src/objects/video/VideoTransform.cpp index 843b5dc3..09586eb9 100644 --- a/src/objects/video/VideoTransform.cpp +++ b/src/objects/video/VideoTransform.cpp @@ -231,14 +231,11 @@ void VideoTransform::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/windowing/LivePatching.cpp b/src/objects/windowing/LivePatching.cpp index 78dd0dfa..9c7896ba 100644 --- a/src/objects/windowing/LivePatching.cpp +++ b/src/objects/windowing/LivePatching.cpp @@ -131,14 +131,11 @@ void LivePatching::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_inletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_inletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/windowing/OutputWindow.cpp b/src/objects/windowing/OutputWindow.cpp index 7771cfef..ba135371 100755 --- a/src/objects/windowing/OutputWindow.cpp +++ b/src/objects/windowing/OutputWindow.cpp @@ -331,14 +331,11 @@ void OutputWindow::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(this->inletsConnected[0] && static_cast(_inletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_inletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_inletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/objects/windowing/ProjectionMapping.cpp b/src/objects/windowing/ProjectionMapping.cpp index 671ea3f6..3ba81a95 100644 --- a/src/objects/windowing/ProjectionMapping.cpp +++ b/src/objects/windowing/ProjectionMapping.cpp @@ -228,14 +228,11 @@ void ProjectionMapping::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); - + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); if(static_cast(_outletParams[0])->isAllocated()){ calcTextureDims(*static_cast(_outletParams[0]), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); ImGui::Image((ImTextureID)(uintptr_t)static_cast(_outletParams[0])->getTextureData().textureID, ImVec2(drawW, drawH)); - }else{ - _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f))); } // get imgui node translated/scaled position/dimension for drawing textures in OF diff --git a/src/ofxVPConfig.h b/src/ofxVPConfig.h index 0ff3fb7f..70209616 100644 --- a/src/ofxVPConfig.h +++ b/src/ofxVPConfig.h @@ -62,6 +62,10 @@ #define MAX_OF_GUI_FONT_SIZE 36 #define MIN_IMGUI_FONT_SIZE 10 #define MAX_IMGUI_FONT_SIZE 56 +#define MIN_KNOB_SCALE 1 +#define MAX_KNOB_SCALE 126 +#define CANVAS_MIN_SCALE 0.2f +#define CANVAS_MAX_SCALE 2.0f #define OBJECT_WIDTH OBJECT_STANDARD_WIDTH #define OBJECT_HEIGHT OBJECT_STANDARD_HEIGHT diff --git a/src/ofxVisualProgramming.cpp b/src/ofxVisualProgramming.cpp index 9b39525e..879c316e 100755 --- a/src/ofxVisualProgramming.cpp +++ b/src/ofxVisualProgramming.cpp @@ -154,13 +154,6 @@ void ofxVisualProgramming::setup(ofxImGui::Gui* _guiRef, string release){ nodeCanvas.setRetina(isRetina,scaleFactor); profiler.setIsRetina(isRetina); - // Set pan-zoom canvas - canvas.disableMouseInput(); - canvas.setbMouseInputEnabled(true); - canvas.toggleOfCam(); - canvas.setUseScale(false); - easyCam.enableOrtho(); - // create failsafe window for always maintaining reference to shared context setupFailsafeWindow(); @@ -345,9 +338,6 @@ void ofxVisualProgramming::draw(){ ofPushStyle(); ofPushMatrix(); - // Init canvas - nodeCanvas.SetTransform( ImVec2(canvas.getTranslation().x,canvas.getTranslation().y), canvas.getScale() );//canvas.getScrollPosition(), canvas.getScale(true) ); - // DEBUG if(OFXVP_DEBUG){ ofSetColor(0,255,255,236); @@ -357,9 +347,6 @@ void ofxVisualProgramming::draw(){ ofDrawCircle(ofGetMouseX(), ofGetMouseY(), 6); } - - canvas.begin(canvasViewport); - ofEnableAlphaBlending(); ofSetCurveResolution(50); ofSetColor(255); @@ -367,7 +354,6 @@ void ofxVisualProgramming::draw(){ livePatchingObiID = -1; - ofxVPGui->begin(); // DEBUG @@ -414,6 +400,8 @@ void ofxVisualProgramming::draw(){ } + nodeCanvas.Update(); + // Close canvas nodeCanvas.End(); @@ -425,12 +413,6 @@ void ofxVisualProgramming::closeDrawMainMenu(){ // We're done drawing to IMGUI ofxVPGui->end(); - canvas.end(); - - if(OFXVP_DEBUG){ - canvas.drawDebug(); - } - // Draw Bottom Bar ofSetColor(0,0,0,60); ofDrawRectangle(0,ofGetHeight() - (20*scaleFactor),ofGetWidth(),(20*scaleFactor)); @@ -444,7 +426,6 @@ void ofxVisualProgramming::closeDrawMainMenu(){ // Graphical Context ofxVPGui->draw(); - canvas.update(); } //-------------------------------------------------------------- @@ -734,8 +715,6 @@ void ofxVisualProgramming::mouseDragged(ofMouseEventArgs &e){ if(ImGui::IsAnyItemActive() || nodeCanvas.isAnyNodeHovered() || ImGui::IsAnyItemHovered() ) return; - canvas.mouseDragged(e); - } //-------------------------------------------------------------- @@ -744,8 +723,6 @@ void ofxVisualProgramming::mousePressed(ofMouseEventArgs &e){ if(ImGui::IsAnyItemActive() || nodeCanvas.isAnyNodeHovered() || ImGui::IsAnyItemHovered() ) return; - canvas.mousePressed(e); - } //-------------------------------------------------------------- @@ -754,10 +731,8 @@ void ofxVisualProgramming::mouseReleased(ofMouseEventArgs &e){ if(ImGui::IsAnyItemActive() || nodeCanvas.isAnyNodeHovered() || ImGui::IsAnyItemHovered() ) return; - setPatchVariable("canvasTranslationX",canvas.getTranslation().x); - setPatchVariable("canvasTranslationY",canvas.getTranslation().y); - - canvas.mouseReleased(e); + setPatchVariable("canvasTranslationX",nodeCanvas.GetCanvasTranslation().x); + setPatchVariable("canvasTranslationY",nodeCanvas.GetCanvasTranslation().y); } @@ -767,7 +742,6 @@ void ofxVisualProgramming::mouseScrolled(ofMouseEventArgs &e){ if(ImGui::IsAnyItemActive() || nodeCanvas.isAnyNodeHovered() || ImGui::IsAnyItemHovered()) return; - canvas.mouseScrolled(e); } //-------------------------------------------------------------- @@ -1721,9 +1695,6 @@ void ofxVisualProgramming::preloadPatch(string patchFile){ } it->second->outPut.clear(); - - //glm::vec3 temp = canvas.screenToWorld(glm::vec3(ofGetWindowWidth()/2,ofGetWindowHeight()/2 + 100,0)); - //it->second->move(temp.x,temp.y); it->second->setWillErase(true); } } @@ -1783,10 +1754,9 @@ void ofxVisualProgramming::loadPatch(string patchFile){ output_width = XML.getValue("output_width",0); output_height = XML.getValue("output_height",0); // setup canvas - glm::vec3 tr = glm::vec3(XML.getValue("canvasTranslationX",0),XML.getValue("canvasTranslationY",0),0); + ImVec2 tr = ImVec2(XML.getValue("canvasTranslationX",0),XML.getValue("canvasTranslationY",0)); if(tr.x != 0 && tr.y != 0){ - canvas.setTranslation(tr); - canvas.initialTranslation = tr; + nodeCanvas.SetCanvasTranslation(tr); } // setup audio @@ -2477,8 +2447,7 @@ void ofxVisualProgramming::activateDSP(){ bool found = weAlreadyHaveObject("audio device"); if(!found){ - glm::vec3 temp = canvas.screenToWorld(glm::vec3((ofGetScreenWidth()/2 - OBJECT_WIDTH/2*scaleFactor)/scaleFactor,(ofGetScreenHeight()/2 + OBJECT_HEIGHT*scaleFactor)/scaleFactor,0)); - addObject("audio device",ofVec2f(temp.x,temp.y)); + addObject("audio device",ofVec2f((ofGetScreenWidth()/2 - OBJECT_WIDTH/2*scaleFactor)/scaleFactor,(ofGetScreenHeight()/2 + OBJECT_HEIGHT*scaleFactor)/scaleFactor)); } resetSystemObjects(); @@ -2500,5 +2469,5 @@ void ofxVisualProgramming::deactivateDSP(){ //-------------------------------------------------------------- void ofxVisualProgramming::resetCanvas(){ - canvas.resetTranslation(); + nodeCanvas.resetCanvas(); } diff --git a/src/ofxVisualProgramming.h b/src/ofxVisualProgramming.h index 250f3cc0..527a5fd7 100755 --- a/src/ofxVisualProgramming.h +++ b/src/ofxVisualProgramming.h @@ -36,7 +36,6 @@ #include "ofxVPConfig.h" -#include "ofxInfiniteCanvas.h" #include "ofxPDSP.h" #include "ofxImGui.h" #include "imgui_node_canvas.h" @@ -136,8 +135,6 @@ class ofxVisualProgramming : public pdsp::Wrapper { void resetCanvas(); // PATCH CANVAS - ofxInfiniteCanvas canvas; - ofEasyCam easyCam; ofRectangle canvasViewport; ofxImGui::Gui* ofxVPGui; ImGuiEx::NodeCanvas nodeCanvas; diff --git a/src/utils.h b/src/utils.h index cd1f7c27..66529385 100644 --- a/src/utils.h +++ b/src/utils.h @@ -443,22 +443,24 @@ inline void drawNodeOFTexture(ofTexture &tex, float &px, float &py, float &w, fl inline void calcTextureDims(ofTexture &tex, float &px, float &py, float &w, float &h, float originX, float originY, float scaledW, float scaledH, float zoom, float retinaScale=1.0f, bool hasInlets=true){ if(tex.isAllocated()){ - if(tex.getWidth()/tex.getHeight() >= scaledW/scaledH){ + float newScaledW = scaledW*zoom; + float newScaledH = scaledH*zoom; + if(tex.getWidth()/tex.getHeight() >= newScaledW/newScaledH){ if(tex.getWidth() > tex.getHeight()){ // horizontal texture - w = scaledW; - h = (scaledW/tex.getWidth())*tex.getHeight(); + w = newScaledW; + h = (newScaledW/tex.getWidth())*tex.getHeight(); px = 0; - py = (scaledH-h)/2.0f; + py = (newScaledH-h)/2.0f; }else{ // vertical texture - w = (tex.getWidth()*scaledH)/tex.getHeight(); - h = scaledH; - px = (scaledW-w)/2.0f; + w = (tex.getWidth()*newScaledH)/tex.getHeight(); + h = newScaledH; + px = (newScaledW-w)/2.0f; py = 0; } }else{ // always considered vertical texture - w = (tex.getWidth()*scaledH)/tex.getHeight(); - h = scaledH; - px = (scaledW-w)/2.0f; + w = (tex.getWidth()*newScaledH)/tex.getHeight(); + h = newScaledH; + px = (newScaledW-w)/2.0f; py = 0; } } From c728603a0c847137b0649137bd11bcdeb7b8fabd Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Thu, 2 Jan 2025 11:28:40 +0100 Subject: [PATCH 03/35] avoid canvas drag&zoom when over panel windows --- src/core/imgui_node_canvas.cpp | 2 ++ src/core/imgui_profiler.h | 3 +++ src/ofxVisualProgramming.cpp | 15 ++++++++++++++- src/ofxVisualProgramming.h | 4 ++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/core/imgui_node_canvas.cpp b/src/core/imgui_node_canvas.cpp index 7d01fd7f..4bdce31d 100644 --- a/src/core/imgui_node_canvas.cpp +++ b/src/core/imgui_node_canvas.cpp @@ -223,6 +223,7 @@ bool ImGuiEx::NodeCanvas::Begin(const char* _id){ canDrawNode = ret; isDrawingCanvas = true; isDrawingNode = false; + return ret; } @@ -233,6 +234,7 @@ void ImGuiEx::NodeCanvas::End(){ isAnyCanvasNodeHovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow); // not really needed anymore... + // reset cursor pos to canvas window ImGui::SetCursorPos(ImGui::GetContentRegionAvail()); ImGui::Dummy({1,1}); // Needed since ImGui 1.90 ?? diff --git a/src/core/imgui_profiler.h b/src/core/imgui_profiler.h index 06d24d5c..8bc0c4dc 100755 --- a/src/core/imgui_profiler.h +++ b/src/core/imgui_profiler.h @@ -356,6 +356,8 @@ class ProfilersWindow { ImGui::Begin(title.str().c_str(), active, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse); ImVec2 canvasSize = ImGui::GetContentRegionAvail(); + isMouseOver = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow) || ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows); + int sizeMargin = int(ImGui::GetStyle().ItemSpacing.y); int maxGraphHeight = 300*scaleFactor; int availableGraphHeight = (int(canvasSize.y) - sizeMargin) / 2; @@ -400,6 +402,7 @@ class ProfilersWindow { bool isRetina; float scaleFactor; + bool isMouseOver; }; diff --git a/src/ofxVisualProgramming.cpp b/src/ofxVisualProgramming.cpp index 879c316e..5fa9936d 100755 --- a/src/ofxVisualProgramming.cpp +++ b/src/ofxVisualProgramming.cpp @@ -112,6 +112,10 @@ ofxVisualProgramming::ofxVisualProgramming(){ inspectorActive = false; navigationActive = false; isCanvasVisible = false; + isCanvasActive = true; + isOverProfiler = false; + isOverInspector = false; + isOverSubpatchNavigator = false; inited = false; @@ -288,6 +292,7 @@ void ofxVisualProgramming::update(){ } profiler.cpuGraph.LoadFrameData(pt,leftToRightIndexOrder.size()); + isOverProfiler = profiler.isMouseOver; if(patchObjects[lastAddedObjectID] != nullptr){ nextObjectPosition = (patchObjects[lastAddedObjectID]->getPos()/ofPoint(scaleFactor,scaleFactor)) + (ofPoint(patchObjects[lastAddedObjectID]->getObjectWidth()+40,40)/ofPoint(scaleFactor,scaleFactor)); @@ -400,7 +405,11 @@ void ofxVisualProgramming::draw(){ } - nodeCanvas.Update(); + nodeCanvas.UpdateCanvasRect(); + if(isCanvasActive){ + nodeCanvas.UpdateCanvasScrollZoom(); + } + nodeCanvas.UpdateCanvasGrid(ImGui::GetWindowDrawList()); // Close canvas nodeCanvas.End(); @@ -436,6 +445,8 @@ void ofxVisualProgramming::drawInspector(){ ImGui::Begin(ICON_FA_ADJUST " Inspector", &inspectorActive, ImGuiWindowFlags_NoCollapse); + isOverInspector = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow) || ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows); + // if object id exists if(patchObjects.find(nodeCanvas.getActiveNode()) != patchObjects.end()){ @@ -487,6 +498,8 @@ void ofxVisualProgramming::drawSubpatchNavigation(){ ImGui::Begin(ICON_FA_NETWORK_WIRED " Patch Navigator", &navigationActive, ImGuiWindowFlags_NoCollapse); + isOverSubpatchNavigator = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow) || ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows); + ImGui::Spacing(); if(ImGui::Button(ICON_FA_PLUS_CIRCLE " Add Subpatch",ImVec2(-1,26*scaleFactor))){ newSubpatchName = ""; diff --git a/src/ofxVisualProgramming.h b/src/ofxVisualProgramming.h index 527a5fd7..97f3b722 100755 --- a/src/ofxVisualProgramming.h +++ b/src/ofxVisualProgramming.h @@ -141,6 +141,7 @@ class ofxVisualProgramming : public pdsp::Wrapper { ImGuiEx::ProfilersWindow profiler; ImGuiEx::ProfilerTask *pt; bool isCanvasVisible; + bool isCanvasActive; // PATCH DRAWING RESOURCES @@ -185,6 +186,9 @@ class ofxVisualProgramming : public pdsp::Wrapper { bool profilerActive; bool inspectorActive; bool navigationActive; + bool isOverProfiler; + bool isOverInspector; + bool isOverSubpatchNavigator; bool inited; // LIVE PATCHING From b991ea3e33f790dc7d97c09935ecdaff96e85926 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sat, 4 Jan 2025 19:32:51 +0100 Subject: [PATCH 04/35] Add canvas interaction from imgui ( select nodes for group drag, duplicate, delete ) ( select/deselect/delete and enable/disable links ) --- src/PatchObject.cpp | 15 +- src/core/imgui_node_canvas.cpp | 250 ++++++++++++++++++++++++++++++--- src/core/imgui_node_canvas.h | 98 ++++++++++--- src/ofxVisualProgramming.cpp | 55 +++++++- 4 files changed, 372 insertions(+), 46 deletions(-) diff --git a/src/PatchObject.cpp b/src/PatchObject.cpp index 0197a935..e4db768d 100644 --- a/src/PatchObject.cpp +++ b/src/PatchObject.cpp @@ -434,7 +434,7 @@ void PatchObject::drawImGuiNode(ImGuiEx::NodeCanvas& _nodeCanvas, mapdrawObjectNodeGui( _nodeCanvas ); @@ -1194,6 +1194,7 @@ void PatchObject::keyPressed(ofKeyEventArgs &e,map> //-------------------------------------------------------------- void PatchObject::keyReleased(ofKeyEventArgs &e,map> &patchObjects){ if(!willErase){ + // DELETE SELECTED OBJECTS if(e.key == OF_KEY_BACKSPACE){ for (int j=0;j(linksToDisconnect.size());j++){ disconnectLink(patchObjects,linksToDisconnect.at(j)); @@ -1202,16 +1203,20 @@ void PatchObject::keyReleased(ofKeyEventArgs &e,map> for(int j=0;j(objectsSelected.size());j++){ if(objectsSelected.at(j) == this->nId){ - ofNotifyEvent(removeEvent, objectsSelected.at(j)); - this->setWillErase(true); + if(this->getName() != "audio device"){ + ofNotifyEvent(removeEvent, objectsSelected.at(j)); + this->setWillErase(true); + } } } - objectsSelected.clear(); + //objectsSelected.clear(); // OSX: CMD-D, WIN/LINUX: CTRL-D (DUPLICATE SELECTED OBJECTS) }else if(e.hasModifier(MOD_KEY) && e.keycode == 68){ for(int j=0;j(objectsSelected.size());j++){ if(objectsSelected.at(j) == this->nId){ - ofNotifyEvent(duplicateEvent, objectsSelected.at(j)); + if(!this->getIsHardwareObject()){ + ofNotifyEvent(duplicateEvent, objectsSelected.at(j)); + } } } } diff --git a/src/core/imgui_node_canvas.cpp b/src/core/imgui_node_canvas.cpp index 4bdce31d..37a13079 100644 --- a/src/core/imgui_node_canvas.cpp +++ b/src/core/imgui_node_canvas.cpp @@ -43,6 +43,9 @@ ==============================================================================*/ #define IMGUI_DEFINE_MATH_OPERATORS + +#include "ofEvents.h" + #include "imgui_node_canvas.h" #include #include // bitset::count @@ -202,6 +205,10 @@ bool ImGuiEx::NodeCanvas::Begin(const char* _id){ ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMouseInputs ); + + isAnyCanvasNodeHovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow); + isAnyCanvasNodeFocused = ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow); + ImGui::PopStyleVar(); // Allow tinier windows for nodes. @@ -232,9 +239,6 @@ void ImGuiEx::NodeCanvas::End(){ IM_ASSERT(isDrawingCanvas == true); // // Begin() wasn't called IM_ASSERT(isDrawingNode == false); // Forgot to call EndNode() - isAnyCanvasNodeHovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow); // not really needed anymore... - - // reset cursor pos to canvas window ImGui::SetCursorPos(ImGui::GetContentRegionAvail()); ImGui::Dummy({1,1}); // Needed since ImGui 1.90 ?? @@ -249,10 +253,167 @@ void ImGuiEx::NodeCanvas::End(){ canvasDrawList = nullptr; } +void ImGuiEx::NodeCanvas::UserInteraction(){ + MouseMove(); + if (ImGui::IsMouseDoubleClicked(0)) + { + MouseLeftButtonDoubleClick(); + return; + } + if (ImGui::IsMouseDoubleClicked(1)) + { + MouseRightButtonDoubleClick(); + return; + } + if (ImGui::IsMouseClicked(0)) + { + MouseLeftButtonSingleClick(); // Set dragging states. + return; + } + if (ImGui::IsMouseDragging(0)) + { + MouseLeftButtonDrag(); // Set selecting state. + return; + } + if (ImGui::IsMouseReleased(0)) + { + MouseLeftButtonRelease(); + return; + } + if (ImGui::IsMouseReleased(1)) + { + MouseRightButtonRelease(); + return; + } +} + +void ImGuiEx::NodeCanvas::MouseMove(){ + bool condition = (canvasView.state == ImGuiExCanvasState::None) || (canvasView.state == ImGuiExCanvasState::Default) || (canvasView.state == ImGuiExCanvasState::HoveringNode) || + (canvasView.state == ImGuiExCanvasState::HoveringInput) || (canvasView.state == ImGuiExCanvasState::HoveringOutput); + if (condition == true){ + if (hoveredNode == nullptr){ + canvasView.state = ImGuiExCanvasState::Default; + interactedNode = nullptr; + }else{ + interactedNode = hoveredNode; + canvasView.state = ImGuiExCanvasState::HoveringNode; + } + } +} + +void ImGuiEx::NodeCanvas::MouseLeftButtonDoubleClick(){ + if (canvasView.state == ImGuiExCanvasState::HoveringNode){ + + }else if (canvasView.state == ImGuiExCanvasState::HoveringInput){ + + }else if (canvasView.state == ImGuiExCanvasState::HoveringOutput){ + + } +} + +void ImGuiEx::NodeCanvas::MouseRightButtonDoubleClick(){ + if (canvasView.state == ImGuiExCanvasState::HoveringNode){ + + }else if (canvasView.state == ImGuiExCanvasState::HoveringNode){ + + }else if (canvasView.state == ImGuiExCanvasState::HoveringInput){ + + } +} + +void ImGuiEx::NodeCanvas::MouseLeftButtonSingleClick(){ + + if (canvasView.state == ImGuiExCanvasState::Default){ + + }else if (canvasView.state == ImGuiExCanvasState::SelectedNode && !isAnyCanvasNodeHovered){ + // deselect nodes on clicking on patch + canvasView.state = ImGuiExCanvasState::Default; + }else if (canvasView.state == ImGuiExCanvasState::HoveringNode){ + canvasView.state = ImGuiExCanvasState::Draging; // SetState:Draging + + }else if (canvasView.state == ImGuiExCanvasState::HoveringInput){ + + }else if (canvasView.state == ImGuiExCanvasState::HoveringOutput){ + canvasView.state = ImGuiExCanvasState::DragingOutput; // SetState:DragingOutput + } + +} + +void ImGuiEx::NodeCanvas::MouseRightButtonSingleClick(){ + +} + +void ImGuiEx::NodeCanvas::MouseLeftButtonDrag(){ + const ImGuiIO& io = ImGui::GetIO(); + if (canvasView.state == ImGuiExCanvasState::Default){ + + canvasView.state = ImGuiExCanvasState::Selecting; // SetState:Selecting + }else if (canvasView.state == ImGuiExCanvasState::Selecting){ + const ImVec2 pos = canvasView.mousePos - ImGui::GetMouseDragDelta(0); + canvasView.rectSelecting.Min = ImMin(pos, canvasView.mousePos); + canvasView.rectSelecting.Max = ImMax(pos, canvasView.mousePos); + }else if (canvasView.state == ImGuiExCanvasState::Draging){ + + }else if (canvasView.state == ImGuiExCanvasState::DragingInput){ + + }else if (canvasView.state == ImGuiExCanvasState::DragingOutput){ + + } +} + +void ImGuiEx::NodeCanvas::MouseLeftButtonRelease(){ + if (canvasView.state == ImGuiExCanvasState::None){ + + }else if (canvasView.state == ImGuiExCanvasState::Default){ + + }else if (canvasView.state == ImGuiExCanvasState::Selecting){ + canvasView.rectSelecting = ImRect(); + canvasView.state = ImGuiExCanvasState::SelectedNode; + }else if (canvasView.state == ImGuiExCanvasState::SelectedNode && !isAnyCanvasNodeHovered){ + canvasView.state = ImGuiExCanvasState::Default; + }else if (canvasView.state == ImGuiExCanvasState::Draging){ + canvasView.state = ImGuiExCanvasState::HoveringNode; //SetState:HoveringNode + }else if (canvasView.state == ImGuiExCanvasState::DragingInput || canvasView.state == ImGuiExCanvasState::DragingOutput){ + canvasView.state = ImGuiExCanvasState::Default; + } +} + +void ImGuiEx::NodeCanvas::MouseRightButtonRelease(){ + // Open canvas selection popup menu. + const ImGuiIO& io = ImGui::GetIO(); + if (canvasView.state != ImGuiExCanvasState::None && canvasView.rectCanvas.Contains(canvasView.mousePos) && ImGui::IsMouseDown(0) == false && ImGui::IsMouseReleased(1)){ + if (io.MouseDragMaxDistanceSqr[1] < (io.MouseDragThreshold * io.MouseDragThreshold)){ + bool someObjectsSelected = false; + if(getSelectedNodesId().size()>0){ + someObjectsSelected = true; + } + if (someObjectsSelected){ + ImGui::OpenPopup("CanvasPopupMenu"); + } + } + } +} + +void ImGuiEx::NodeCanvas::CanvasPopupMenu(){ + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8)); + if (ImGui::BeginPopup("CanvasPopupMenu")){ + /*if (ImGui::MenuItem("Delete selection")){ + + } + if (ImGui::MenuItem("Duplicate selection")){ + + }*/ + + ImGui::EndPopup(); + } + ImGui::PopStyleVar(); +} + void ImGuiEx::NodeCanvas::Update(){ UpdateCanvasRect(); UpdateCanvasScrollZoom(); UpdateCanvasGrid(ImGui::GetWindowDrawList()); + UpdateNodesFlags(); } void ImGuiEx::NodeCanvas::UpdateCanvasRect(){ @@ -322,6 +483,45 @@ void ImGuiEx::NodeCanvas::UpdateCanvasGrid(ImDrawList* drawList) const{ } } +void ImGuiEx::NodeCanvas::UpdateNodesFlags(){ + hoveredNode = nullptr; // Important. + if (existingNodes.empty()) return; + + ImVec2 offset = canvasView.position + canvasView.scroll; + ImRect canvas(canvasView.position, canvasView.position + canvasView.size); + + for(std::map::iterator it = existingNodes.begin(); it != existingNodes.end(); it++ ){ + + // Unset hovered flag + if(canvasView.state == ImGuiExCanvasState::Default || canvasView.state == ImGuiExCanvasState::Selecting){ + it->second.flag = NodeFlag::Default; + } + + + // GET NODE AREA + ImRect nodeArea = it->second.nodeRect; + nodeArea.Min *= canvasView.scale; + nodeArea.Max *= canvasView.scale; + nodeArea.Translate(offset); + nodeArea.ClipWith(canvas); + + // Hovered Node Condition + if (canvasView.state != ImGuiExCanvasState::None && canvasView.state != ImGuiExCanvasState::SelectedNode && hoveredNode == nullptr && (nodeArea.Contains(canvasView.mousePos))){ + hoveredNode = &it->second; + hoveredNode->flag = NodeFlag::Hovered; + } + + // Selecting node + if (canvasView.state == ImGuiExCanvasState::Selecting){ + if (canvasView.rectSelecting.Overlaps(nodeArea)){ + it->second.flag = NodeFlag::Selected; + continue; + } + + } + } +} + void ImGuiEx::NodeCanvas::DrawFrameBorder(const bool& _drawOnForeground) const { // Only use between NodeCanvas::Begin() and End(). IM_ASSERT(isDrawingCanvas == true); // forgot to Begin(); @@ -338,13 +538,23 @@ void ImGuiEx::NodeCanvas::DrawFrameBorder(const bool& _drawOnForeground) const { ); } +void ImGuiEx::NodeCanvas::DrawSelecting() const{ + ImDrawList* drawList = ImGui::GetWindowDrawList(); + if (canvasView.state == ImGuiExCanvasState::Selecting){ + drawList->AddRectFilled(canvasView.rectSelecting.Min, canvasView.rectSelecting.Max, ImColor(140/255.0f,145/255.0f,216/255.0f, 0.05f)); + drawList->AddRect(canvasView.rectSelecting.Min, canvasView.rectSelecting.Max, ImColor(1.0f, 1.0f, 1.0f, 0.1f)); + } +} + // always use EndNode() even if returns false. Like ImGui Windows. bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name, ImVec2& _pos, ImVec2& _size, const int& _numLeftPins, const int& _numRightPins, const bool& canResize, const bool& isTextureNode ){ // Check callstack IM_ASSERT(isDrawingCanvas == true); // forgot to End(); IM_ASSERT(canDrawNode == true); // Don't call if Begin() returned false - IM_ASSERT(isDrawingNode == false); // Finish your previous node before staring a new one ! + IM_ASSERT(isDrawingNode == false); // Finish your previous node before staring a new one !77 + + //const ImGuiIO& io = ImGui::GetIO(); // Precalc some vars ImVec2 nodeScale = ImVec2(1,1)*canvasView.scale; @@ -352,6 +562,10 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name, isDrawingNode = true; // to allow End() call curNodeData.menuActions = ImGuiExNodeMenuActionFlags_None; // reset menu flags + // Set node rect + existingNodes[nId].nodeRect.Min = _pos; + existingNodes[nId].nodeRect.Max = _pos+_size; + // Is the node out of sight on canvas ? bool isNodeVisible = ImGui::IsRectVisible( curNodeData.outerContentBox.Min, curNodeData.outerContentBox.Max ); @@ -486,7 +700,7 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name, // Node border (surrounding) ImU32 _tempColor = IM_COL32(0,0,0,0); - if (std::find(selected_nodes.begin(), selected_nodes.end(),nId)!=selected_nodes.end()){ // selected + if (existingNodes[nId].flag == NodeFlag::Selected){ // selected _tempColor = IM_COL32(255,0,0,255); } nodeDrawList->AddRect( curNodeData.outerContentBox.Min, curNodeData.outerContentBox.Max, _tempColor ); @@ -524,17 +738,10 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name, ImGui::InvisibleButton( "headerGripBtn", ImMax(ImVec2( curNodeData.outerContentBox.GetSize().x-IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor, IMGUI_EX_NODE_HEADER_HEIGHT*scaleFactor ), ImVec2(1,1)) ); static ImVec2 mouseOffset(0,0); static bool isDraggingHeader = false; + static bool isDraggingSelection = false; if(ImGui::IsItemActive() && ImGui::IsItemClicked(ImGuiMouseButton_Left)){ activeNode = nId; - if(ImGui::GetIO().KeyShift && name != "audio device"){ - selected_nodes.push_back(nId); - } - } - - // deselect nodes on clicking on patch - if(ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !isAnyCanvasNodeHovered){ - selected_nodes.clear(); } if(ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left)){ @@ -548,9 +755,14 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name, ImGui::GetForegroundDrawList()->AddLine(curNodeData.outerContentBox.Min,curNodeData.outerContentBox.Min+mouseOffset,ImGui::ColorConvertFloat4ToU32(ImVec4(0,1,0,1.f))); # endif _pos = (ImGui::GetMousePos()-mouseOffset)*(1.f/canvasView.scale)-canvasView.translation*(1.f/canvasView.scale);// ImGui::GetMouseDragDelta(0); - } - else if(ImGui::IsItemDeactivated()){ + }else if(existingNodes[nId].flag == NodeFlag::Selected && canvasView.state == ImGuiExCanvasState::SelectedNode && ImGui::IsMouseDragging(ImGuiMouseButton_Left)){ + + existingNodes[nId].nodeRect.Translate(ImGui::GetIO().MouseDelta / canvasView.scale); + _pos = existingNodes[nId].nodeRect.Min; + + }else if(ImGui::IsItemDeactivated()){ if(isDraggingHeader) isDraggingHeader = false; + if(isDraggingSelection) isDraggingSelection = false; } @@ -645,7 +857,7 @@ bool ImGuiEx::NodeCanvas::BeginNode( int nId, const char* _id, std::string name, if(ImGui::MenuItem("Duplicate")) curNodeData.menuActions |= ImGuiExNodeMenuActionFlags_DuplicateNode; ImGui::Selectable("Drag to Subpatch"); // drag node id - if(name != "audio device" && name != "live patching"){ + if(name != "live patching"){ if (ImGui::BeginDragDropSource()){ ImGui::SetDragDropPayload("SUBPATCH_NAME", &nId, sizeof(int)); @@ -947,16 +1159,16 @@ ImGuiEx::NodeConnectData ImGuiEx::NodeCanvas::AddNodePin( const int nodeID, cons const bool is_hovered = is_mouse_hovering_near_link(link_data.bezier); if(ImGui::IsMouseClicked(0) && !isAnyCanvasNodeHovered){ - if (is_hovered && !ImGui::GetIO().KeyShift){ + if (is_hovered && ofGetKeyPressed(OF_KEY_CONTROL)){ if (std::find(selected_links.begin(), selected_links.end(),_linksData.at(i)._linkID)==selected_links.end()){ selected_links.push_back(_linksData.at(i)._linkID); } - }else if(!is_hovered && !ImGui::GetIO().KeyShift){ + }else if(!is_hovered && !ofGetKeyPressed(OF_KEY_SHIFT) && !ofGetKeyPressed(OF_KEY_CONTROL)){ std::vector::iterator it = std::find(selected_links.begin(), selected_links.end(),_linksData.at(i)._linkID); if (it!=selected_links.end()){ selected_links.erase(it); } - }else if(is_hovered && ImGui::GetIO().KeyShift){ + }else if(is_hovered && ofGetKeyPressed(OF_KEY_SHIFT)){ // deactivate if activated if (std::find(deactivated_links.begin(), deactivated_links.end(),_linksData.at(i)._linkID)==deactivated_links.end()){ deactivated_links.push_back(_linksData.at(i)._linkID); diff --git a/src/core/imgui_node_canvas.h b/src/core/imgui_node_canvas.h index c00a4b1e..8813bb4b 100644 --- a/src/core/imgui_node_canvas.h +++ b/src/core/imgui_node_canvas.h @@ -130,7 +130,8 @@ enum class ImGuiExCanvasState Draging, DragingInput, DragingOutput, - Selecting + Selecting, + SelectedNode }; // extend ImGui in ImGuiEx namespace @@ -235,15 +236,21 @@ struct NodeConnectData{ int toInletPinID; }; -struct NodeFlag { - NodeFlag() = delete; - static const unsigned int Default = 0; - static const unsigned int Visible = 1 << 0; - static const unsigned int Hovered = 1 << 1; - static const unsigned int Selected = 1 << 2; - static const unsigned int Collapsed = 1 << 3; - static const unsigned int Disabled = 1 << 4; - static const unsigned int Highlighted = 1 << 5; +enum NodeFlag { + Default = 0, + Visible = 1 << 0, + Hovered = 1 << 1, + Selected = 1 << 2, + Collapsed = 1 << 3, + Disabled = 1 << 4, + Highlighted = 1 << 5 +}; + +struct NodeInfo { + int id; + std::string name; + ImRect nodeRect; + NodeFlag flag; }; enum class ofxVPLinkPosition @@ -272,14 +279,30 @@ struct NodeCanvas { // Must be called only when Begin() returned true. void End(); + // User Interaction + void UserInteraction(); + void MouseMove(); + void MouseLeftButtonDoubleClick(); + void MouseRightButtonDoubleClick(); + void MouseLeftButtonSingleClick(); + void MouseRightButtonSingleClick(); + void MouseLeftButtonDrag(); + void MouseLeftButtonRelease(); + void MouseRightButtonRelease(); + void Update(); void UpdateCanvasRect(); void UpdateCanvasScrollZoom(); void UpdateCanvasGrid(ImDrawList* drawList) const; + void UpdateNodesFlags(); + + void CanvasPopupMenu(); // Draws the frame border void DrawFrameBorder(const bool& _drawOnForeground=true) const; + void DrawSelecting() const; + // Draw Child windows (aka Nodes) on the canvas. // position and size may change be updated after function call. bool BeginNode( int nId, const char* id, std::string name, ImVec2& _pos, ImVec2& _size, const int& _numLeftPins, const int& _numRightPins, const bool& canResize, const bool& isTextureNode ); @@ -315,12 +338,18 @@ struct NodeCanvas { scaleFactor = sf; } - // Query GUI if any nodes are hovered + // Query GUI if any nodes are focused bool isAnyNodeHovered() const { //IM_ASSERT(isDrawingCanvas == true); // dont call while drawing ! return isAnyCanvasNodeHovered; } + // Query GUI if any nodes are focused + bool isAnyNodeFocused() const { + //IM_ASSERT(isDrawingCanvas == true); // dont call while drawing ! + return isAnyCanvasNodeFocused; + } + // Returns current view data. const NodeCanvasView& GetCanvasView() const { IM_ASSERT( isDrawingCanvas == true ); // Only between BeginNode() and EndNode() @@ -349,9 +378,6 @@ struct NodeCanvas { return nodeDrawList; } - // Returns selected nodes - std::vector getSelectedNodes(){ return selected_nodes; } - // Returns selected links std::vector getSelectedLinks(){ return selected_links; } @@ -383,6 +409,38 @@ struct NodeCanvas { void setContext(ImGuiContext* _c){ context = _c; } ImGuiContext* getContext() { return context; } + void addNodeToMap(int _id, std::string _name) { + NodeInfo ni; ni.id = _id; + ni.name = _name; + ni.nodeRect = ImRect(0,0,IMGUI_EX_NODE_MIN_WIDTH,IMGUI_EX_NODE_MIN_HEIGHT); + ni.flag = NodeFlag::Default; existingNodes[_id]=ni; + } + void removeNodeFromMap(int _id) { existingNodes.erase(_id); } + void clearNodesMap() { existingNodes.clear(); } + void debugNodeMap() { + for(std::map::iterator it = existingNodes.begin(); it != existingNodes.end(); it++ ){ + std::cout << "NodeMap[" << it->first << "] --> " << it->second.id << " : " << it->second.name << " --> " << it->second.nodeRect.GetWidth() << "x" << it->second.nodeRect.GetHeight() << " at " << it->second.nodeRect.GetCenter().x << "," << it->second.nodeRect.GetCenter().y << std::endl; + } + } + + // Returns selected nodes + std::vector& getSelectedNodesId(){ + std::vector *temp = new std::vector(); + for(std::map::iterator it = existingNodes.begin(); it != existingNodes.end(); it++ ){ + if(it->second.flag == NodeFlag::Selected){ + temp->push_back(it->second.id); + } + } + return *temp; + } + + void setCanvasActive(bool ca) { isCanvasActive = ca; } + void setCanvasViewToDefault() { canvasView.state = ImGuiExCanvasState::Default; UpdateNodesFlags(); } + + // Events + ofEvent> removeSelectionEvent; + ofEvent> duplicateSelectionEvent; + private: // context @@ -394,7 +452,9 @@ struct NodeCanvas { bool canDrawNode = false; bool isDrawingMenu = false; bool isDrawingContent = false; + bool isCanvasActive = false; bool isAnyCanvasNodeHovered = false; + bool isAnyCanvasNodeFocused = false; // State data NodeLayoutData curNodeData; @@ -410,13 +470,17 @@ struct NodeCanvas { // Patch Control data std::map> inletPinsPositions; std::map> outletPinsPositions; - std::vector selected_nodes; // for group actions (copy, duplicate, delete) -- TO IMPLEMENT - std::vector selected_links; // for delete links (one or multiple) -- IMPLEMENTED - std::vector deactivated_links; // for activating/deactivating links (one or multiple) -- IMPLEMENTED + std::map existingNodes; + std::vector selected_links; // for delete links (one or multiple) + std::vector deactivated_links; // for activating/deactivating links (one or multiple) + NodeInfo* hoveredNode = nullptr; // Hovered node + NodeInfo* interactedNode = nullptr; // Node under interaction std::string activePin; std::string activePinType; int activeNode = 0; // for node inspector + + // retina stuff bool isRetina = false; float scaleFactor = 1.0f; diff --git a/src/ofxVisualProgramming.cpp b/src/ofxVisualProgramming.cpp index 5fa9936d..1c48a148 100755 --- a/src/ofxVisualProgramming.cpp +++ b/src/ofxVisualProgramming.cpp @@ -154,8 +154,8 @@ void ofxVisualProgramming::setup(ofxImGui::Gui* _guiRef, string release){ } nodeCanvas.setContext(ImGui::GetCurrentContext()); - nodeCanvas.setRetina(isRetina,scaleFactor); + profiler.setIsRetina(isRetina); // create failsafe window for always maintaining reference to shared context @@ -406,11 +406,21 @@ void ofxVisualProgramming::draw(){ } nodeCanvas.UpdateCanvasRect(); + nodeCanvas.setCanvasActive(isCanvasActive); if(isCanvasActive){ nodeCanvas.UpdateCanvasScrollZoom(); + if(!nodeCanvas.isAnyNodeFocused()){ + nodeCanvas.UserInteraction(); + nodeCanvas.DrawSelecting(); + nodeCanvas.UpdateNodesFlags(); + } + //nodeCanvas.CanvasPopupMenu(); + }else{ + nodeCanvas.setCanvasViewToDefault(); } nodeCanvas.UpdateCanvasGrid(ImGui::GetWindowDrawList()); + // Close canvas nodeCanvas.End(); @@ -580,7 +590,6 @@ void ofxVisualProgramming::drawSubpatchNavigation(){ _t.inOut = 0; subpatchesMap[move_to].push_back(_t); } - } ImGui::EndDragDropTarget(); } @@ -887,6 +896,14 @@ void ofxVisualProgramming::addObject(string name,ofVec2f pos){ } nodeCanvas.setActiveNode(lastAddedObjectID); + nodeCanvas.addNodeToMap(lastAddedObjectID,name); + + //nodeCanvas.debugNodeMap(); + + if(patchObjects[lastAddedObjectID] != nullptr){ + nextObjectPosition = (patchObjects[lastAddedObjectID]->getPos()/ofPoint(scaleFactor,scaleFactor)) + (ofPoint(patchObjects[lastAddedObjectID]->getObjectWidth()+40,40)/ofPoint(scaleFactor,scaleFactor)); + + } } bLoadingNewObject = false; @@ -1057,10 +1074,13 @@ void ofxVisualProgramming::reconnectObjectOutlets(int &id){ void ofxVisualProgramming::deleteObject(int id){ resetTime = ofGetElapsedTimeMillis(); - if ((id != -1) && (patchObjects[id] != nullptr)){ + if ((id != -1) && (patchObjects[id] != nullptr) && (patchObjects[id]->getName() != "audio device") ){ int targetID = id; bool found = false; + + if(targetID == lastAddedObjectID) lastAddedObjectID=0; + ofxXmlSettings XML; #if OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR < 12 if (XML.loadFile(currentPatchFile)){ @@ -1137,7 +1157,21 @@ void ofxVisualProgramming::deleteObject(int id){ } } + // check reference from subpatches map ( if the object was a wireless one ,sender or receiver ) + for(map>::iterator it = subpatchesMap.begin(); it != subpatchesMap.end(); it++ ){ + for(int z=0;zsecond.size();z++){ + if(it->second.at(z).objID == id){ + it->second.at(z).objID = -1; + break; + } + } + } + + nodeCanvas.removeNodeFromMap(id); + } + + bLoadingNewObject = false; } //-------------------------------------------------------------- @@ -1358,6 +1392,10 @@ void ofxVisualProgramming::removeObject(int &id){ } } } + + nodeCanvas.removeNodeFromMap(id); + + //nodeCanvas.debugNodeMap(); } bLoadingNewObject = false; @@ -1367,7 +1405,8 @@ void ofxVisualProgramming::removeObject(int &id){ void ofxVisualProgramming::duplicateObject(int &id){ // disable duplicate for hardware&system related objects if(!patchObjects[id]->getIsHardwareObject()){ - addObject(patchObjects[id]->getName(),nextObjectPosition); + ofVec3f tempPosition = (patchObjects[id]->getPos()/ofPoint(scaleFactor,scaleFactor)) + (ofPoint(patchObjects[id]->getObjectWidth()+40,40)/ofPoint(scaleFactor,scaleFactor)); + addObject(patchObjects[id]->getName(),tempPosition); }else{ ofLog(OF_LOG_NOTICE,"'%s' is one of the Mosaic objects that can't (for now) be duplicated due to hardware/system related issues.",patchObjects[id]->getName().c_str()); } @@ -1713,6 +1752,9 @@ void ofxVisualProgramming::preloadPatch(string patchFile){ } } + // clear canvas nodes map + nodeCanvas.clearNodesMap(); + // clear subpatch navigation data subpatchesMap.clear(); currentSubpatch = "root"; @@ -2023,6 +2065,7 @@ void ofxVisualProgramming::loadPatch(string patchFile){ patchObjects[tempObj->getId()] = tempObj; actualObjectID = tempObj->getId(); lastAddedObjectID = tempObj->getId(); + nodeCanvas.addNodeToMap(tempObj->getId(),tempObj->getName()); // if wireless object, add reference to subpatch data map if(objname == "sender"){ SubpatchConnection _t; @@ -2200,7 +2243,7 @@ void ofxVisualProgramming::loadPatchSharedContextObjects(){ patchObjects[tempObj->getId()] = tempObj; actualObjectID = tempObj->getId(); lastAddedObjectID = tempObj->getId(); - + nodeCanvas.addNodeToMap(tempObj->getId(),tempObj->getName()); #ifdef NDEBUG std::cout << "Loading "<< tempObj->getName() << std::endl; #endif @@ -2260,6 +2303,8 @@ void ofxVisualProgramming::loadPatchSharedContextObjects(){ } + //nodeCanvas.debugNodeMap(); + } } From 07f92053ace7d90fbf8cf549fab9e4a348e4fe21 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sat, 4 Jan 2025 20:09:50 +0100 Subject: [PATCH 05/35] Fix duplicate filepath in objects with loaded file when duplicate --- src/objects/graphics/ImageLoader.cpp | 12 ++++++------ src/ofxVisualProgramming.cpp | 12 ++++++++++-- src/ofxVisualProgramming.h | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/objects/graphics/ImageLoader.cpp b/src/objects/graphics/ImageLoader.cpp index 347b5d43..ebeb7a28 100644 --- a/src/objects/graphics/ImageLoader.cpp +++ b/src/objects/graphics/ImageLoader.cpp @@ -89,12 +89,6 @@ void ImageLoader::setupObjectContent(shared_ptr &mainWindow){ fileDialog.setIsRetina(this->isRetina); - if(filepath == "none"){ - isNewObject = true; - }else{ - loadImageFile(); - } - } //-------------------------------------------------------------- @@ -124,6 +118,12 @@ void ImageLoader::updateObjectContent(map> &patchObj prevH = this->getCustomVar("HEIGHT"); this->width = prevW; this->height = prevH; + + if(filepath == "none"){ + isNewObject = true; + }else{ + loadImageFile(); + } } } diff --git a/src/ofxVisualProgramming.cpp b/src/ofxVisualProgramming.cpp index 1c48a148..bf8987fd 100755 --- a/src/ofxVisualProgramming.cpp +++ b/src/ofxVisualProgramming.cpp @@ -831,7 +831,7 @@ void ofxVisualProgramming::audioProcess(float *input, int bufferSize, int nChann } //-------------------------------------------------------------- -void ofxVisualProgramming::addObject(string name,ofVec2f pos){ +void ofxVisualProgramming::addObject(string name,ofVec2f pos,std::string fp){ // check if object exists bool exists = isObjectInLibrary(name); @@ -869,6 +869,9 @@ void ofxVisualProgramming::addObject(string name,ofVec2f pos){ tempObj->setIsRetina(isRetina,scaleFactor); tempObj->move(static_cast(pos.x),static_cast(pos.y)); tempObj->setSubpatch(currentSubpatch); + if(fp != "none"){ + tempObj->setFilepath(fp); + } ofAddListener(tempObj->removeEvent ,this,&ofxVisualProgramming::removeObject); ofAddListener(tempObj->resetEvent ,this,&ofxVisualProgramming::resetObject); ofAddListener(tempObj->reconnectOutletsEvent ,this,&ofxVisualProgramming::reconnectObjectOutlets); @@ -1406,7 +1409,12 @@ void ofxVisualProgramming::duplicateObject(int &id){ // disable duplicate for hardware&system related objects if(!patchObjects[id]->getIsHardwareObject()){ ofVec3f tempPosition = (patchObjects[id]->getPos()/ofPoint(scaleFactor,scaleFactor)) + (ofPoint(patchObjects[id]->getObjectWidth()+40,40)/ofPoint(scaleFactor,scaleFactor)); - addObject(patchObjects[id]->getName(),tempPosition); + std::ifstream testPath(patchObjects[id]->getFilepath()); + if(testPath){ // object has a file in filepath + addObject(patchObjects[id]->getName(),tempPosition,patchObjects[id]->getFilepath()); + }else{ + addObject(patchObjects[id]->getName(),tempPosition); + } }else{ ofLog(OF_LOG_NOTICE,"'%s' is one of the Mosaic objects that can't (for now) be duplicated due to hardware/system related issues.",patchObjects[id]->getName().c_str()); } diff --git a/src/ofxVisualProgramming.h b/src/ofxVisualProgramming.h index 97f3b722..12b6f78a 100755 --- a/src/ofxVisualProgramming.h +++ b/src/ofxVisualProgramming.h @@ -92,7 +92,7 @@ class ofxVisualProgramming : public pdsp::Wrapper { void activeObject(int oid); shared_ptr selectObject(string objname); - void addObject(string name, ofVec2f pos); + void addObject(string name, ofVec2f pos,std::string fp="none"); shared_ptr getLastAddedObject(); void resetObject(int &id); From e70ba3982bfec33f340776996b4d8421145f23d6 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Mon, 6 Jan 2025 12:47:38 +0100 Subject: [PATCH 06/35] Add Piano keyboard object, to visualize MIDI notes from external devices and/or play notes ( outputs pitch ) --- src/core/imgui_node_canvas.h | 3 + src/objects/gui/moPianoKeyboard.cpp | 239 ++++++++++++++++++++++++++++ src/objects/gui/moPianoKeyboard.h | 79 +++++++++ 3 files changed, 321 insertions(+) create mode 100755 src/objects/gui/moPianoKeyboard.cpp create mode 100755 src/objects/gui/moPianoKeyboard.h diff --git a/src/core/imgui_node_canvas.h b/src/core/imgui_node_canvas.h index 8813bb4b..84c1e29a 100644 --- a/src/core/imgui_node_canvas.h +++ b/src/core/imgui_node_canvas.h @@ -365,6 +365,9 @@ struct NodeCanvas { void resetCanvas() { canvasView.scroll = ImVec2(0,0); canvasView.scale = 1.0f; } + // Get mouse position over canvas + ImVec2 GetMousePosition() { return canvasView.mousePos; } + // Returns data about the current node. // Useful inside: scale, niewName, scaleName, etc. const NodeLayoutData& GetNodeData() const { diff --git a/src/objects/gui/moPianoKeyboard.cpp b/src/objects/gui/moPianoKeyboard.cpp new file mode 100755 index 00000000..97a95845 --- /dev/null +++ b/src/objects/gui/moPianoKeyboard.cpp @@ -0,0 +1,239 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#include "moPianoKeyboard.h" + +static bool has_black(int key) { + return (!((key - 1) % 7 == 0 || (key - 1) % 7 == 3) && key != 51); +} + +//-------------------------------------------------------------- +moPianoKeyboard::moPianoKeyboard() : PatchObject("piano keyboard"){ + + this->numInlets = 2; + this->numOutlets = 2; + + _inletParams[0] = new float(); // pitch (index) + *(float *)&_inletParams[0] = 0.0f; + _inletParams[1] = new float(); // velocity + *(float *)&_inletParams[1] = 0.0f; + + _outletParams[0] = new float(); // pitch + *(float *)&_outletParams[0] = 0.0f; + _outletParams[1] = new float(); // velocity + *(float *)&_outletParams[1] = 0.0f; + + this->initInletsState(); + + pitch = 0; + loaded = false; + + this->width *= 6.74f; + +} + +//-------------------------------------------------------------- +void moPianoKeyboard::newObject(){ + PatchObject::setName( this->objectName ); + + this->addInlet(VP_LINK_NUMERIC,"pitch"); + this->addInlet(VP_LINK_NUMERIC,"velocity"); + + this->addOutlet(VP_LINK_NUMERIC,"pitch"); + this->addOutlet(VP_LINK_NUMERIC,"velocity"); + +} + +//-------------------------------------------------------------- +void moPianoKeyboard::setupObjectContent(shared_ptr &mainWindow){ + unusedArgs(mainWindow); + +} + +//-------------------------------------------------------------- +void moPianoKeyboard::updateObjectContent(map> &patchObjects){ + unusedArgs(patchObjects); + + if(this->inletsConnected[0] && this->inletsConnected[1]){ + key_states[static_cast(*(float *)&_inletParams[0])] = static_cast(*(float *)&_inletParams[1]); + *(float *)&_outletParams[0] = *(float *)&_inletParams[0]; + *(float *)&_outletParams[1] = *(float *)&_inletParams[1]; + + }else{ + *(float *)&_outletParams[0] = pitch; + *(float *)&_outletParams[1] = 127.0f; + } + + if(!loaded){ + loaded = true; + + } + +} + +//-------------------------------------------------------------- +void moPianoKeyboard::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ + unusedArgs(font,glRenderer); +} + +//-------------------------------------------------------------- +void moPianoKeyboard::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ + + // CONFIG GUI inside Menu + if(_nodeCanvas.BeginNodeMenu()){ + ImGui::Separator(); + ImGui::Separator(); + ImGui::Separator(); + + if (ImGui::BeginMenu("CONFIG")) + { + + drawObjectNodeConfig(); this->configMenuWidth = ImGui::GetWindowWidth(); + + + ImGui::EndMenu(); + } + _nodeCanvas.EndNodeMenu(); + } + + // Visualize (Object main view) + if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ + + + + ImDrawList *draw_list = ImGui::GetWindowDrawList(); + ImVec2 p = ImGui::GetCursorScreenPos(); + + int width = 20*_nodeCanvas.GetCanvasScale()*scaleFactor; + int cur_key = 21; + for (int key = 0; key < 52; key++) { + ImU32 col = White; + ImRect tecla = ImRect(ImVec2(p.x + key * width + (width/4), p.y),ImVec2(p.x + key * width + width - (width/4), p.y + ((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT))); + bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0] && !this->inletsConnected[1]; + + if ((key_states[cur_key] || is_segment_hovered)) { + if(ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)){ + col = Yellow; + pitch = cur_key; + }else{ + col = Gray; + pitch = 0; + } + } + draw_list->AddRectFilled( + ImVec2(p.x + key * width, p.y), + ImVec2(p.x + key * width + width, p.y + ((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)), + col, 0, ImDrawFlags_RoundCornersAll); + draw_list->AddRect( + ImVec2(p.x + key * width, p.y), + ImVec2(p.x + key * width + width, p.y + ((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)), + Black, 0, ImDrawFlags_RoundCornersAll); + cur_key++; + if (has_black(key)) { + cur_key++; + } + + } + cur_key = 22; + for (int key = 0; key < 52; key++) { + if (has_black(key)) { + ImU32 col = Black; + ImRect tecla = ImRect(ImVec2(p.x + key * width + width * 3 / 4, p.y),ImVec2(p.x + key * width + width * 5 / 4 + 1, p.y + (((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)/3*2))); + bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0] && !this->inletsConnected[1]; + + if ((key_states[cur_key] || is_segment_hovered)) { + if(ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)){ + col = Yellow; + pitch = cur_key; + }else{ + col = Gray; + pitch = 0; + } + } + draw_list->AddRectFilled( + ImVec2(p.x + key * width + width * 3 / 4, p.y), + ImVec2(p.x + key * width + width * 5 / 4 + 1, p.y + (((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)/3*2)), + col, 0, ImDrawFlags_RoundCornersAll); + draw_list->AddRect( + ImVec2(p.x + key * width + width * 3 / 4, p.y), + ImVec2(p.x + key * width + width * 5 / 4 + 1, p.y + (((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)/3*2)), + Black, 0, ImDrawFlags_RoundCornersAll); + + cur_key += 2; + } else { + cur_key++; + } + } + + _nodeCanvas.EndNodeContent(); + } + +} + +//-------------------------------------------------------------- +void moPianoKeyboard::drawObjectNodeConfig(){ + ImGuiEx::ObjectInfo( + "An interactive piano keyboard, it can be used to play notes or to visualize MIDI notes from an external MIDI device ( via midi receiver object )", + "https://mosaic.d3cod3.org/reference.php?r=piano-keyboard", scaleFactor); +} + +//-------------------------------------------------------------- +void moPianoKeyboard::removeObjectContent(bool removeFileFromData){ + unusedArgs(removeFileFromData); +} + +//-------------------------------------------------------------- +void moPianoKeyboard::keyup(int key) { + key_states[key] = 0; +} + +//-------------------------------------------------------------- +void moPianoKeyboard::keydown(int key, int velocity) { + key_states[key] = velocity; +} +//-------------------------------------------------------------- +std::vector moPianoKeyboard::current_notes() { + std::vector result{}; + for (int i = 0; i < 256; i++) { + if (key_states[i]) { + result.push_back(i); + } + } + return result; +} + + +OBJECT_REGISTER( moPianoKeyboard, "piano keyboard", OFXVP_OBJECT_CAT_GUI) + +#endif diff --git a/src/objects/gui/moPianoKeyboard.h b/src/objects/gui/moPianoKeyboard.h new file mode 100755 index 00000000..3647d5da --- /dev/null +++ b/src/objects/gui/moPianoKeyboard.h @@ -0,0 +1,79 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#pragma once + +#include "PatchObject.h" + +class moPianoKeyboard : public PatchObject { + +public: + + moPianoKeyboard(); + + void newObject() override; + void setupObjectContent(shared_ptr &mainWindow) override; + void updateObjectContent(map> &patchObjects) override; + + void drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer) override; + void drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ) override; + void drawObjectNodeConfig() override; + + void removeObjectContent(bool removeFileFromData=false) override; + + void keyup(int key); + void keydown(int key, int velocity); + std::vector current_notes(); + + + int pitch; + bool loaded; + + ImU32 Black = IM_COL32(0, 0, 0, 255); + ImU32 White = IM_COL32(255, 255, 255, 255); + ImU32 Red = IM_COL32(255,0,0,255); + ImU32 Gray = IM_COL32(120,120,120,255); + ImU32 Yellow = IM_COL32(190,134,60,255); + +protected: + + int key_states[256] = {0}; + +private: + + OBJECT_FACTORY_PROPS + +}; + +#endif From b61699468f5afcb6fc5c75314fc0da2c6762fc05 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Wed, 8 Jan 2025 00:25:39 +0100 Subject: [PATCH 07/35] fixed crash when input vector size < 2 --- src/objects/data/VectorExtract.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/objects/data/VectorExtract.cpp b/src/objects/data/VectorExtract.cpp index 1ab9956f..a21b6760 100755 --- a/src/objects/data/VectorExtract.cpp +++ b/src/objects/data/VectorExtract.cpp @@ -154,16 +154,25 @@ void VectorExtract::drawObjectNodeConfig(){ if(start < 0){ start = 0; } - if(start > static_cast(static_cast *>(_inletParams[0])->size())-2){ - start = static_cast *>(_inletParams[0])->size()-2; + if(static_cast *>(_inletParams[0])->size()>1){ + if(start > static_cast(static_cast *>(_inletParams[0])->size())-2){ + start = static_cast *>(_inletParams[0])->size()-2; + } + }else{ + start = 0; } + this->setCustomVar(static_cast(start),"START"); } ImGui::Spacing(); int prevEnd = end; if(ImGui::InputInt("Size",&end)){ - if(end > start && end <= static_cast(static_cast *>(_inletParams[0])->size())-1){ - this->setCustomVar(static_cast(end),"END"); + if(static_cast *>(_inletParams[0])->size()>1){ + if(end > start && end <= static_cast(static_cast *>(_inletParams[0])->size())-1){ + this->setCustomVar(static_cast(end),"END"); + }else{ + end = prevEnd; + } }else{ end = prevEnd; } From e3c674b8d4e4d59e1fc7dc353ebb9c2911eb858e Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Wed, 8 Jan 2025 18:57:53 +0100 Subject: [PATCH 08/35] Added scheme script object with live coding on output window --- addon_config.mk | 4 +- src/objects/scripting/SchemeScript.cpp | 594 +++++++++++++++++++++++++ src/objects/scripting/SchemeScript.h | 162 +++++++ 3 files changed, 758 insertions(+), 2 deletions(-) create mode 100644 src/objects/scripting/SchemeScript.cpp create mode 100644 src/objects/scripting/SchemeScript.h diff --git a/addon_config.mk b/addon_config.mk index 75fe4814..c9b51564 100644 --- a/addon_config.mk +++ b/addon_config.mk @@ -26,8 +26,8 @@ common: # or use += in several lines ADDON_DEPENDENCIES = ofxKinect ofxOpenCv ofxOsc ofxXmlSettings ADDON_DEPENDENCIES += ofxAudioFile ofxBTrack ofxCv ofxEasing ofxFFmpegRecorder ofxFft - ADDON_DEPENDENCIES += ofxJSON ofxImGui ofxLua ofxMidi ofxMtlMapping2D - ADDON_DEPENDENCIES += ofxOpenDHT ofxPd ofxPDSP ofxTimeline ofxWarp + ADDON_DEPENDENCIES += ofxGLEditor ofxJSON ofxImGui ofxLua ofxMidi ofxMtlMapping2D + ADDON_DEPENDENCIES += ofxOpenDHT ofxPd ofxPDSP ofxScheme ofxTimeline ofxWarp # include search paths, this will be usually parsed from the file system # but if the addon or addon libraries need special search paths they can be diff --git a/src/objects/scripting/SchemeScript.cpp b/src/objects/scripting/SchemeScript.cpp new file mode 100644 index 00000000..5a6dc923 --- /dev/null +++ b/src/objects/scripting/SchemeScript.cpp @@ -0,0 +1,594 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#include "SchemeScript.h" + +//-------------------------------------------------------------- +SchemeScript::SchemeScript() : PatchObject("scheme live coding"){ + + // SET YOUR INLETS/OUTLETS + this->numInlets = 1; + this->numOutlets = 0; + + _inletParams[0] = new vector(); // data IN + + this->initInletsState(); + + this->setIsTextureObj(true); + this->setIsSharedContextObj(true); + + isFullscreen = false; + thposX = thposY = thdrawW = thdrawH = 0.0f; + isNewScriptConnected = false; + + this->output_width = STANDARD_TEXTURE_WIDTH; + this->output_height = STANDARD_TEXTURE_HEIGHT; + + temp_width = this->output_width; + temp_height = this->output_height; + + window_actual_width = STANDARD_PROJECTOR_WINDOW_WIDTH; + window_actual_height = STANDARD_PROJECTOR_WINDOW_HEIGHT; + + needReset = false; + hideMouse = false; + loadRandExample = false; + + posX = posY = drawW = drawH = 0.0f; + + prevW = this->width; + prevH = this->height; + + schemeIcon = new ofImage(); + loadSchemeScriptFlag = false; + schemeScriptLoaded = false; + + emptyData.assign(1,0.0f); + + loaded = false; + autoRemove = false; + +} + +//-------------------------------------------------------------- +void SchemeScript::newObject(){ + // SET OBJECT NAME AND INLETS/OUTLETS TYPES/NAMES + PatchObject::setName( this->objectName ); + + this->addInlet(VP_LINK_ARRAY,"_mosaic_data_inlet"); + + this->setCustomVar(static_cast(isFullscreen),"FULLSCREEN"); + this->setCustomVar(static_cast(this->output_width),"OUTPUT_WIDTH"); + this->setCustomVar(static_cast(this->output_height),"OUTPUT_HEIGHT"); + this->setCustomVar(0.0f,"OUTPUT_POSX"); + this->setCustomVar(0.0f,"OUTPUT_POSY"); + this->setCustomVar(static_cast(hideMouse),"HIDE_MOUSE"); + this->setCustomVar(static_cast(prevW),"WIDTH"); + this->setCustomVar(static_cast(prevH),"HEIGHT"); + +} + +//-------------------------------------------------------------- +void SchemeScript::setupObjectContent(shared_ptr &mainWindow){ + + loadWindowSettings(); + + ofGLFWWindowSettings settings; + settings.setGLVersion(2,1); // NEEDED BY ofxGLEditor + settings.shareContextWith = mainWindow; + settings.decorated = true; + settings.resizable = true; + settings.stencilBits = 0; + // RETINA FIX + if(mainWindow->getPixelScreenCoordScale() > 1){ + if(ofGetScreenWidth() > 3360 && ofGetScreenHeight() > 2100){ + window_actual_width = STANDARD_PROJECTOR_WINDOW_WIDTH*2; + window_actual_height = STANDARD_PROJECTOR_WINDOW_HEIGHT*2; + } + settings.setPosition(ofDefaultVec2(mainWindow->getScreenSize().x-(window_actual_width+100),400)); + }else{ + settings.setPosition(ofDefaultVec2(mainWindow->getScreenSize().x-(STANDARD_PROJECTOR_WINDOW_WIDTH+50),200)); + } + settings.setSize(window_actual_width, window_actual_height); + + window = dynamic_pointer_cast(ofCreateWindow(settings)); + window->setVerticalSync(false); + window->setWindowPosition(this->getCustomVar("OUTPUT_POSX"),this->getCustomVar("OUTPUT_POSY")); + + glfwSetWindowCloseCallback(window->getGLFWWindow(),GL_FALSE); + + ofAddListener(window->events().draw,this,&SchemeScript::drawInWindow); + ofAddListener(window->events().keyPressed,this,&SchemeScript::keyPressed); + ofAddListener(window->events().keyReleased,this,&SchemeScript::keyReleased); + ofAddListener(window->events().mouseMoved ,this,&SchemeScript::mouseMoved); + ofAddListener(window->events().mouseDragged ,this,&SchemeScript::mouseDragged); + ofAddListener(window->events().mousePressed ,this,&SchemeScript::mousePressed); + ofAddListener(window->events().mouseReleased ,this,&SchemeScript::mouseReleased); + ofAddListener(window->events().mouseScrolled ,this,&SchemeScript::mouseScrolled); + ofAddListener(window->events().windowResized ,this,&SchemeScript::windowResized); + + // INIT Scheme and register API + scheme.setup(); + + // init drawing FBO + ofDisableArbTex(); + fbo = new ofFbo(); + fbo->allocate(ofGetScreenWidth(),ofGetScreenHeight() ,GL_RGBA32F_ARB,4); + fbo->begin(); + ofClear(0,0,0,255); + fbo->end(); + ofEnableArbTex(); + + isFullscreen = false; + thposX = thposY = thdrawW = thdrawH = 0.0f; + scaleTextureToWindow(fbo->getWidth(), fbo->getHeight(), 1280, 720); + scheme.setWindowDim(fbo->getWidth(), fbo->getHeight()); + + // load editor font + ofxEditor::loadFont("livecoding/scheme/fonts/PrintChar21.ttf", 24); + editor.setup(this); + + hideEditor = false; + // load scheme syntax + syntax = new ofxEditorSyntax(); + syntax->loadFile("livecoding/scheme/schemeSyntax.xml"); + editor.getSettings().addSyntax("Scheme", syntax); + for(size_t i =0;i<=9;i++){ + editor.setLangSyntax("Scheme",i); + } + // syntax highlighter colors + colorScheme.loadFile("livecoding/scheme/colorScheme.xml"); + editor.setColorScheme(&colorScheme); + + cursorColor = ofColor(255, 255, 0, 200); + + ofDisableArbTex(); + schemeIcon->load("images/scheme.png"); + ofEnableArbTex(); + + fileDialog.setIsRetina(this->isRetina); + + needToLoadScript = true; + scriptLoaded = false; + eval = true; + scriptError = false; + +} + +//-------------------------------------------------------------- +void SchemeScript::updateObjectContent(map> &patchObjects){ + unusedArgs(patchObjects); + + // receive external data + if(this->inletsConnected[0] && !static_cast *>(_inletParams[0])->empty()){ + scheme.setExternalData(*static_cast *>(_inletParams[0])); + }else{ + scheme.setExternalData(emptyData); + } + + // auto remove + if(window->getGLFWWindow() == nullptr && !autoRemove){ + autoRemove = true; + ofNotifyEvent(this->removeEvent, this->nId); + this->willErase = true; + } + + if(loadRandExample){ + loadRandExample = false; + scheme.clearScript(); + ofDirectory temp; + temp.listDir(ofToDataPath("livecoding/scheme/examples/")); + int rf = static_cast(floor(ofRandom(temp.getFiles().size()))); + + if(temp.getFiles().size() <= rf){ + rf = 0; + } + + ofFile rand(temp.getFile(rf).getAbsolutePath()); + + sketchContent = ofBufferFromFile(rand.getAbsolutePath()); + editor.setText(sketchContent); + eval = true; + scriptError = false; + editor.getSettings().setCursorColor(cursorColor); + + } + + if(schemeScriptLoaded){ + schemeScriptLoaded = false; + ofFile nf(lastScriptLoaded); + + sketchContent = ofBufferFromFile(nf.getAbsolutePath()); + editor.setText(sketchContent); + eval = true; + scriptError = false; + editor.getSettings().setCursorColor(cursorColor); + } + + if(!loaded){ + loaded = true; + temp_width = static_cast(floor(this->getCustomVar("OUTPUT_WIDTH"))); + temp_height = static_cast(floor(this->getCustomVar("OUTPUT_HEIGHT"))); + hideMouse = static_cast(floor(this->getCustomVar("HIDE_MOUSE"))); + prevW = this->getCustomVar("WIDTH"); + prevH = this->getCustomVar("HEIGHT"); + this->width = prevW; + this->height = prevH; + + // setup drawing dimensions + scaleTextureToWindow(STANDARD_TEXTURE_WIDTH, STANDARD_TEXTURE_HEIGHT, window->getWidth(),window->getHeight()); + + window->setWindowTitle("scheme live coding | id: "+ofToString(this->getId())); + + if(static_cast(floor(this->getCustomVar("FULLSCREEN"))) != isFullscreen){ + window->setWindowPosition(this->getCustomVar("OUTPUT_POSX"),this->getCustomVar("OUTPUT_POSY")); + toggleWindowFullscreen(); + } + + needReset = true; + } + +} + +//-------------------------------------------------------------- +void SchemeScript::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ + unusedArgs(font,glRenderer); + +} + +//-------------------------------------------------------------- +void SchemeScript::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ + + ImGui::SetCurrentContext(_nodeCanvas.getContext()); + + // CONFIG GUI inside Menu + if(_nodeCanvas.BeginNodeMenu()){ + + ImGui::Separator(); + ImGui::Separator(); + ImGui::Separator(); + + if (ImGui::BeginMenu("CONFIG")) + { + + drawObjectNodeConfig(); + + ImGui::EndMenu(); + } + + _nodeCanvas.EndNodeMenu(); + } + + // Visualize (Object main view) + if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ + + ImVec2 window_pos = ImGui::GetWindowPos()+ImVec2(IMGUI_EX_NODE_PINS_WIDTH_NORMAL, IMGUI_EX_NODE_HEADER_HEIGHT); + _nodeCanvas.getNodeDrawList()->AddRectFilled(window_pos,window_pos+ImVec2(scaledObjW*this->scaleFactor*_nodeCanvas.GetCanvasScale(), scaledObjH*this->scaleFactor*_nodeCanvas.GetCanvasScale()),ImGui::GetColorU32(ImVec4(34.0/255.0, 34.0/255.0, 34.0/255.0, 1.0f))); + + if(schemeIcon->getTexture().isAllocated()){ + calcTextureDims(schemeIcon->getTexture(), posX, posY, drawW, drawH, objOriginX, objOriginY, scaledObjW, scaledObjH, canvasZoom, this->scaleFactor); + ImGui::SetCursorPos(ImVec2(posX+(IMGUI_EX_NODE_PINS_WIDTH_NORMAL*this->scaleFactor), posY+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor))); + ImGui::Image((ImTextureID)(uintptr_t)schemeIcon->getTexture().getTextureData().textureID, ImVec2(drawW, drawH)); + } + + // get imgui node translated/scaled position/dimension for drawing textures in OF + //objOriginX = (ImGui::GetWindowPos().x + ((IMGUI_EX_NODE_PINS_WIDTH_NORMAL - 1)*this->scaleFactor) - _nodeCanvas.GetCanvasTranslation().x)/_nodeCanvas.GetCanvasScale(); + //objOriginY = (ImGui::GetWindowPos().y - _nodeCanvas.GetCanvasTranslation().y)/_nodeCanvas.GetCanvasScale(); + scaledObjW = this->width - (IMGUI_EX_NODE_PINS_WIDTH_NORMAL+IMGUI_EX_NODE_PINS_WIDTH_SMALL)*this->scaleFactor/_nodeCanvas.GetCanvasScale(); + scaledObjH = this->height - (IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor/_nodeCanvas.GetCanvasScale(); + + + _nodeCanvas.EndNodeContent(); + } + + // get imgui canvas zoom + canvasZoom = _nodeCanvas.GetCanvasScale(); + +} + +//-------------------------------------------------------------- +void SchemeScript::drawObjectNodeConfig(){ + + loadSchemeScriptFlag = false; + + ImGui::Spacing(); + ImGui::Text("Loaded Buffer:"); + if(filepath == "none"){ + ImGui::Text("%s",filepath.c_str()); + }else{ + ImGui::Text("%s",editor.getEditorFilename(editor.getCurrentEditor()).c_str()); + } + ImGui::Spacing(); + ImGui::Text("Rendering at: %.0fx%.0f",fbo->getWidth(),fbo->getHeight()); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + if(ImGui::Button(ICON_FA_RANDOM " Load Random Script",ImVec2(224*scaleFactor,26*scaleFactor))){ + loadRandExample = true; + } + ImGui::Spacing(); + ImGui::Spacing(); + if(ImGui::Button(ICON_FA_FILE_CODE " Load Script",ImVec2(224*scaleFactor,26*scaleFactor))){ + loadSchemeScriptFlag = true; + } + + ImGuiEx::ObjectInfo( + "Scheme Live Coding - A scheme language based graphical live coding environment with OF batteries.", + "https://github.com/d3cod3/ofxScheme", scaleFactor); + + // file dialog, load a scheme script in current buffer + if(ImGuiEx::getFileDialog(fileDialog, loadSchemeScriptFlag, "Select a scheme script", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".scm", "", scaleFactor)){ + schemeScriptLoaded = true; + lastScriptLoaded = fileDialog.selected_path; + } +} + +//-------------------------------------------------------------- +void SchemeScript::removeObjectContent(bool removeFileFromData){ + unusedArgs(removeFileFromData); + + ofRemoveListener(window->events().draw,this,&SchemeScript::drawInWindow); + + if(window->getGLFWWindow() != nullptr){ + window->finishRender(); +#ifdef TARGET_LINUX + glfwHideWindow(window->getGLFWWindow()); +#else + window->setWindowShouldClose(); +#endif + } +} + +//-------------------------------------------------------------- +void SchemeScript::scaleTextureToWindow(float texW, float texH, float winW, float winH){ + // wider texture than window + if(texW/texH >= winW/winH){ + thdrawW = winW; + thdrawH = (texH*winW) / texW; + thposX = 0; + thposY = (winH-thdrawH)/2.0f; + //ofLog(OF_LOG_NOTICE," |wider texture than window| Window: %fx%f, Texture[%fx%f] drawing %fx%f at %f,%f",winW,winH,texW,texH,thdrawW,thdrawH,thposX,thposY); + // wider window than texture + }else{ + thdrawW = (texW*winH) / texH; + thdrawH = winH; + thposX = (winW-thdrawW)/2.0f; + thposY = 0; + //ofLog(OF_LOG_NOTICE," |wider window than texture| Window: %fx%f, Texture[%fx%f] drawing %fx%f at %f,%f",winW,winH,texW,texH,thdrawW,thdrawH,thposX,thposY); + } + +} + +//-------------------------------------------------------------- +void SchemeScript::toggleWindowFullscreen(){ + isFullscreen = !isFullscreen; + ofToggleFullscreen(); + + this->setCustomVar(static_cast(isFullscreen),"FULLSCREEN"); + + if(!isFullscreen){ + window->setWindowShape(window_actual_width, window_actual_height); + scaleTextureToWindow(fbo->getWidth(), fbo->getHeight(), window_actual_width, window_actual_height); + }else{ + scaleTextureToWindow(fbo->getWidth(), fbo->getHeight(), window->getScreenSize().x,window->getScreenSize().y); + } + + this->setCustomVar(window->getWindowPosition().x,"OUTPUT_POSX"); + this->setCustomVar(window->getWindowPosition().y,"OUTPUT_POSY"); +} + +//-------------------------------------------------------------- +void SchemeScript::drawInWindow(ofEventArgs &e){ + unusedArgs(e); + + scheme.setMouse((window->events().getMouseX() - thposX)/thdrawW * fbo->getWidth(),(window->events().getMouseY() - thposY)/thdrawH * fbo->getHeight()); + scheme.update(); + scheme.setScreenTexture(fbo->getTexture()); + + if(needToLoadScript){ + needToLoadScript = false; + loadBuffers(); + } + + if(eval){ + eval = false; + scriptBuffer = editor.getText(); + } + + ofBackground(0); + + if(hideMouse){ + window->hideCursor(); + }else{ + window->showCursor(); + } + + if(scriptLoaded){ + fbo->begin(); + glPushAttrib(GL_ALL_ATTRIB_BITS); + glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA); + ofPushView(); + ofPushStyle(); + ofPushMatrix(); + + ofEnableAlphaBlending(); + + if(!scriptError){ + const char* res = scheme.evalScript(scriptBuffer); + if(res != nullptr){ + scriptError = true; + ofLog(OF_LOG_ERROR,"%s",res); + editor.getSettings().setCursorColor(ofColor::red); + } + } + + ofDisableAlphaBlending(); + + ofPopMatrix(); + ofPopStyle(); + ofPopView(); + glPopAttrib(); + fbo->end(); + + ofSetColor(255); + fbo->draw(thposX,thposY,thdrawW,thdrawH); + + if(window->getGLFWWindow() != nullptr && !hideEditor) { + editor.draw(); + } + } + +} + +//-------------------------------------------------------------- +void SchemeScript::loadWindowSettings(){ + this->output_width = static_cast(floor(this->getCustomVar("OUTPUT_WIDTH"))); + this->output_height = static_cast(floor(this->getCustomVar("OUTPUT_HEIGHT"))); + + temp_width = this->output_width; + temp_height = this->output_height; +} + +//-------------------------------------------------------------- +void SchemeScript::keyPressed(ofKeyEventArgs &e){ + + bool modifierPressed = ofxEditor::getSuperAsModifier() ? ofGetKeyPressed(OF_KEY_SUPER) : ofGetKeyPressed(OF_KEY_CONTROL); + if(modifierPressed) { + switch(e.key) { + case 's': + filepath = ofToDataPath(ofToString(editor.getCurrentEditor())+".scm",true); + editor.saveFile(filepath,editor.getCurrentEditor()); + return; + case 'e': + scheme.clearScript(); + eval = true; + scriptError = false; + editor.getSettings().setCursorColor(cursorColor); + return; + case 'f': + toggleWindowFullscreen(); + return; + case 'l': + editor.setLineWrapping(!editor.getLineWrapping()); + return; + case 'n': + editor.setLineNumbers(!editor.getLineNumbers()); + return; + case 't': + hideEditor = !hideEditor; + return; + case 'k': + editor.setAutoFocus(!editor.getAutoFocus()); + return; + + } + } + + // send regular key pressed to script if the editor is hidden + if(window->getGLFWWindow() != nullptr && !hideEditor) { + editor.keyPressed(e.key); + } + +} + +//-------------------------------------------------------------- +void SchemeScript::keyReleased(ofKeyEventArgs &e){ + +} + +//-------------------------------------------------------------- +void SchemeScript::mouseMoved(ofMouseEventArgs &e){ + +} + +//-------------------------------------------------------------- +void SchemeScript::mouseDragged(ofMouseEventArgs &e){ + +} + +//-------------------------------------------------------------- +void SchemeScript::mousePressed(ofMouseEventArgs &e){ + +} + +//-------------------------------------------------------------- +void SchemeScript::mouseReleased(ofMouseEventArgs &e){ + + this->setCustomVar(window->getWindowPosition().x,"OUTPUT_POSX"); + this->setCustomVar(window->getWindowPosition().y,"OUTPUT_POSY"); +} + +//-------------------------------------------------------------- +void SchemeScript::mouseScrolled(ofMouseEventArgs &e){ + +} + +//-------------------------------------------------------------- +void SchemeScript::windowResized(ofResizeEventArgs &e){ + scaleTextureToWindow(fbo->getWidth(), fbo->getHeight(), e.width,e.height); + editor.resize(e.width,e.height); + + this->setCustomVar(window->getWindowPosition().x,"OUTPUT_POSX"); + this->setCustomVar(window->getWindowPosition().y,"OUTPUT_POSY"); +} + +//-------------------------------------------------------------- +void SchemeScript::loadBuffers(){ + + for(size_t i=1;i<=9;i++){ + filepath = "livecoding/scheme/"+ofToString(i)+".scm"; + ofLog(OF_LOG_NOTICE,"%s",filepath.c_str()); + if(i == 1){ + ofFile temp(filepath); + string filesFolder = temp.getEnclosingDirectory()+"/files"; + scriptFolder.listDir(filesFolder); + scheme.clearScript(); + scheme.setScriptPath(scriptFolder.getAbsolutePath()); + currentScriptFile.open(filepath); + sketchContent = ofBufferFromFile(currentScriptFile.getAbsolutePath()); + + } + // open script files into editor buffers + editor.openFile(filepath,i); + } + + scriptLoaded = true; + +} + +// REGISTER THE OBJECT +OBJECT_REGISTER( SchemeScript, "scheme live coding", OFXVP_OBJECT_CAT_SCRIPTING) + +#endif diff --git a/src/objects/scripting/SchemeScript.h b/src/objects/scripting/SchemeScript.h new file mode 100644 index 00000000..67d60a86 --- /dev/null +++ b/src/objects/scripting/SchemeScript.h @@ -0,0 +1,162 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#pragma once + +#include "PatchObject.h" + +#include "ImGuiFileBrowser.h" +#include "imgui_node_canvas.h" +#include "IconsFontAwesome5.h" + +#include "ofxScheme.h" +#include "ofxGLEditor.h" + +// app key commands: +// MOD -> CTRL or Super (Windows Key, Mac CMD) +// +// MOD + e: execute script or selected text +// MOD + l: toggle line wrapping +// MOD + n: toggle line numbers +// MOD + f: toggle fullscreen +// MOD + k: toggle auto focus zooming +// MOD + t: show/hide editor +// MOD + 1 to MOD + 9: switch to editor 1 - 9 +// MOD + b: blow up the cursor +// MOD + a: select all text in the current editor +// MOD + a + SHIFT: clear all text in the current editor +// MOD + c: copy from system clipboard +// MOD + v: paste to system clipboard +// MOD + z: undo last key input action +// MOD + y: redo last key input action +// +// see ofxGLEditor.h for editor key commands +// + +class SchemeScript : public PatchObject, public ofxGLEditorListener { + +public: + + // CONSTRUCTOR + SchemeScript(); + + // BASIC METHODS + + // inlets/oulets instatiation + void newObject() override; + // object setup + void setupObjectContent(shared_ptr &mainWindow) override; + // object update + void updateObjectContent(map> &patchObjects) override; + // object draw + void drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer) override; + void drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ) override; + void drawObjectNodeConfig() override; + // call on remove object + void removeObjectContent(bool removeFileFromData=false) override; + + void drawInWindow(ofEventArgs &e); + + void loadWindowSettings(); + + void keyPressed(ofKeyEventArgs &e); + void keyReleased(ofKeyEventArgs &e); + void mouseMoved(ofMouseEventArgs &e); + void mouseDragged(ofMouseEventArgs &e); + void mousePressed(ofMouseEventArgs &e); + void mouseReleased(ofMouseEventArgs &e); + void mouseScrolled(ofMouseEventArgs &e); + void windowResized(ofResizeEventArgs &e); + + void loadBuffers(); + + + void scaleTextureToWindow(float texW, float texH, float winW, float winH); + void toggleWindowFullscreen(); + + + shared_ptr window; + bool isFullscreen; + bool isNewScriptConnected; + bool hideMouse; + + int temp_width, temp_height; + int window_actual_width, window_actual_height; + float posX, posY, drawW, drawH; + float thposX, thposY, thdrawW, thdrawH; + bool needReset; + + ofxScheme scheme; + std::string scriptBuffer; + ofFbo *fbo; + std::vector emptyData; + std::string lastScriptLoaded; + bool eval; + bool scriptError; + bool loadRandExample; + bool loadSchemeScriptFlag; + bool schemeScriptLoaded; + + ofxGLEditor editor; + ofxEditorSyntax* syntax; + ofxEditorColorScheme colorScheme; + ofColor cursorColor; + bool hideEditor; + + imgui_addons::ImGuiFileBrowser fileDialog; + ofFile currentScriptFile; + ofBuffer sketchContent; + string filepath; + bool needToLoadScript; + bool scriptLoaded; + + ofDirectory scriptFolder; + ofImage *schemeIcon; + + float scaledObjW, scaledObjH; + float objOriginX, objOriginY; + float canvasZoom; + + bool loaded; + float prevW, prevH; + bool autoRemove; + +private: + OBJECT_FACTORY_PROPS + +protected: + +}; + +#endif From a54b34786443977909775b0ac47e9b9c44b371e5 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Mon, 13 Jan 2025 16:32:50 +0100 Subject: [PATCH 09/35] added polyphonic oscillator, up to 16 voices --- src/objects/sound/PolyphonicOscillator.cpp | 498 +++++++++++++++++++++ src/objects/sound/PolyphonicOscillator.h | 122 +++++ 2 files changed, 620 insertions(+) create mode 100755 src/objects/sound/PolyphonicOscillator.cpp create mode 100755 src/objects/sound/PolyphonicOscillator.h diff --git a/src/objects/sound/PolyphonicOscillator.cpp b/src/objects/sound/PolyphonicOscillator.cpp new file mode 100755 index 00000000..16329518 --- /dev/null +++ b/src/objects/sound/PolyphonicOscillator.cpp @@ -0,0 +1,498 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#include "PolyphonicOscillator.h" + +//-------------------------------------------------------------- +PolyphonicOscillator::PolyphonicOscillator() : PatchObject("polyphonic oscillator"){ + + this->numInlets = 6; + this->numOutlets = 6; + + _inletParams[0] = new vector(); // pitch + + _inletParams[1] = new float(); // level + *(float *)&_inletParams[1] = 0.0f; + + _inletParams[2] = new float(); // sine + *(float *)&_inletParams[2] = 0.0f; + + _inletParams[3] = new float(); // triangle + *(float *)&_inletParams[3] = 0.0f; + + _inletParams[4] = new float(); // saw + *(float *)&_inletParams[4] = 0.0f; + + _inletParams[5] = new float(); // pulse + *(float *)&_inletParams[5] = 0.0f; + + _outletParams[0] = new ofSoundBuffer(); // osc output + _outletParams[1] = new ofSoundBuffer(); // sine output + _outletParams[2] = new ofSoundBuffer(); // triangle output + _outletParams[3] = new ofSoundBuffer(); // saw output + _outletParams[4] = new ofSoundBuffer(); // pulse output + _outletParams[5] = new vector(); // audio buffer + + this->initInletsState(); + + isAudioOUTObject = true; + isPDSPPatchableObject = true; + + loaded = false; + + level_float = 0.5f; + + detune_float = 0.0f; + fine_float = 0.0f; + pw_float = 0.5f; + + sine_float = 0.0f; + triangle_float = 0.0f; + saw_float = 0.0f; + pulse_float = 0.0f; + + this->width *= 1.85f; + this->height *= 3.1f; + +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::newObject(){ + PatchObject::setName( this->objectName ); + + this->addInlet(VP_LINK_ARRAY,"notes"); + this->addInlet(VP_LINK_NUMERIC,"level"); + this->addInlet(VP_LINK_NUMERIC,"sine level"); + this->addInlet(VP_LINK_NUMERIC,"triangle level"); + this->addInlet(VP_LINK_NUMERIC,"saw level"); + this->addInlet(VP_LINK_NUMERIC,"pulse level"); + + this->addOutlet(VP_LINK_AUDIO,"signal"); + this->addOutlet(VP_LINK_AUDIO,"sine"); + this->addOutlet(VP_LINK_AUDIO,"triangle"); + this->addOutlet(VP_LINK_AUDIO,"saw"); + this->addOutlet(VP_LINK_AUDIO,"pulse"); + this->addOutlet(VP_LINK_ARRAY,"dataBuffer"); + + this->setCustomVar(level_float,"LEVEL"); + this->setCustomVar(detune_float,"DETUNE_COARSE"); + this->setCustomVar(fine_float,"DETUNE_FINE"); + this->setCustomVar(pw_float,"PULSE_WIDTH"); + + this->setCustomVar(sine_float,"SINE_LEVEL"); + this->setCustomVar(triangle_float,"TRIANGLE_LEVEL"); + this->setCustomVar(saw_float,"SAW_LEVEL"); + this->setCustomVar(pulse_float,"PULSE_LEVEL"); +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::setupObjectContent(shared_ptr &mainWindow){ + unusedArgs(mainWindow); + + loadAudioSettings(); + +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::setupAudioOutObjectContent(pdsp::Engine &engine){ + + for(size_t i=0;i> level.at(i).in_mod(); + level_ctrl.at(i).set(level_float); + level_ctrl.at(i).enableSmoothing(50.0f); + + pw_ctrl >> osc.at(i).in_pw(); // pw (pulse width for the pulse waveform only) + + // pitches + pitch_ctrl.at(i).set(pitch_float.at(i)); + pitch_ctrl.at(i).enableSmoothing(50.0f); + + // mutes + voice_ctrl.at(i) >> voice_amp_sine.at(i).in_mod(); + voice_ctrl.at(i) >> voice_amp_triangle.at(i).in_mod(); + voice_ctrl.at(i) >> voice_amp_saw.at(i).in_mod(); + voice_ctrl.at(i) >> voice_amp_pulse.at(i).in_mod(); + voice_ctrl.at(i).set(voice_float.at(i)); + voice_ctrl.at(i).enableSmoothing(50.0f); + } + pw_ctrl.set(pw_float); // square wave + pw_ctrl.enableSmoothing(50.0f); + + // detune + detuneCoarse_ctrl.set(detune_float); + detuneCoarse_ctrl.enableSmoothing(50.0f); + detuneFine_ctrl.set(fine_float); + detuneFine_ctrl.enableSmoothing(50.0f); + + for(size_t i=0;i> osc.at(i).in_pitch(); + } + + + for(size_t i=0;i> sineLevel.at(i).in_mod(); + sine_ctrl.at(i).set(sine_float); + sine_ctrl.at(i).enableSmoothing(50.0f); + triangle_ctrl.at(i) >> triangleLevel.at(i).in_mod(); + triangle_ctrl.at(i).set(triangle_float); + triangle_ctrl.at(i).enableSmoothing(50.0f); + saw_ctrl.at(i) >> sawLevel.at(i).in_mod(); + saw_ctrl.at(i).set(saw_float); + saw_ctrl.at(i).enableSmoothing(50.0f); + pulse_ctrl.at(i) >> pulseLevel.at(i).in_mod(); + pulse_ctrl.at(i).set(pulse_float); + pulse_ctrl.at(i).enableSmoothing(50.0f); + + osc.at(i).out_sine() >> voice_amp_sine.at(i) >> sineLevel.at(i) >> level.at(i); + osc.at(i).out_triangle() >> voice_amp_triangle.at(i) >> triangleLevel.at(i) >> level.at(i); + osc.at(i).out_saw() >> voice_amp_saw.at(i) >> sawLevel.at(i) >> level.at(i); + osc.at(i).out_pulse() >> voice_amp_pulse.at(i) >> pulseLevel.at(i) >> level.at(i); + + level.at(i) >> this->pdspOut[0]; + level.at(i) >> scope >> engine.blackhole(); + + sineLevel.at(i) >> this->pdspOut[1]; + sineLevel.at(i) >> sine_scope >> engine.blackhole(); + triangleLevel.at(i) >> this->pdspOut[2]; + triangleLevel.at(i) >> triangle_scope >> engine.blackhole(); + sawLevel.at(i) >> this->pdspOut[3]; + sawLevel.at(i) >> saw_scope >> engine.blackhole(); + pulseLevel.at(i) >> this->pdspOut[4]; + pulseLevel.at(i) >> pulse_scope >> engine.blackhole(); + + } + + + +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::updateObjectContent(map> &patchObjects){ + unusedArgs(patchObjects); + + if(this->inletsConnected[0] && static_cast *>(_inletParams[0])->size()>0){ + for(size_t i=0;i *>(_inletParams[0])->size();i++){ + if(i *>(_inletParams[0])->at(i),0,127); + pitch_ctrl.at(i).set(pitch_float.at(i)); + voice_float.at(i) = 1.0f/static_cast *>(_inletParams[0])->size(); + voice_ctrl.at(i).set(voice_float.at(i)); + } + } + if(static_cast *>(_inletParams[0])->size() <= MAX_OSC_VOICES){ + for(size_t i=static_cast *>(_inletParams[0])->size()-1;iinletsConnected[1]){ + level_float = ofClamp(*(float *)&_inletParams[1],0.0f,1.0f); + for(size_t i=0;iinletsConnected[2]){ + sine_float = ofClamp(*(float *)&_inletParams[2],0.0f,1.0f); + for(size_t i=0;iinletsConnected[3]){ + triangle_float = ofClamp(*(float *)&_inletParams[3],0.0f,1.0f); + for(size_t i=0;iinletsConnected[4]){ + saw_float = ofClamp(*(float *)&_inletParams[4],0.0f,1.0f); + for(size_t i=0;iinletsConnected[5]){ + pulse_float = ofClamp(*(float *)&_inletParams[5],0.0f,1.0f); + for(size_t i=0;igetCustomVar("LEVEL"),0.0f,1.0f); + + detune_float = ofClamp(this->getCustomVar("DETUNE_COARSE"),-12.0f, 12.0f); + detuneCoarse_ctrl.set(detune_float); + fine_float = ofClamp(this->getCustomVar("DETUNE_FINE"),-1.0f,1.0f); + detuneFine_ctrl.set(fine_float); + pw_float = ofClamp(this->getCustomVar("PULSE_WIDTH"),0.0f,1.0f); + pw_ctrl.set(pw_float); + + sine_float = ofClamp(this->getCustomVar("SINE_LEVEL"),0.0f,1.0f); + triangle_float = ofClamp(this->getCustomVar("TRIANGLE_LEVEL"),0.0f,1.0f); + saw_float = ofClamp(this->getCustomVar("SAW_LEVEL"),0.0f,1.0f); + pulse_float = ofClamp(this->getCustomVar("PULSE_LEVEL"),0.0f,1.0f); + + for(size_t i=0;i& glRenderer){ + unusedArgs(font,glRenderer); + + ofSetColor(0); + +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ + + if(_nodeCanvas.BeginNodeMenu()){ + ImGui::Separator(); + ImGui::Separator(); + ImGui::Separator(); + + if (ImGui::BeginMenu("CONFIG")) + { + + drawObjectNodeConfig(); this->configMenuWidth = ImGui::GetWindowWidth(); + + ImGui::EndMenu(); + } + _nodeCanvas.EndNodeMenu(); + } + + // Visualize (Object main view) + if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ + + // draw waveform + ImGuiEx::drawWaveform(_nodeCanvas.getNodeDrawList(), ImVec2(ImGui::GetWindowSize().x,ImGui::GetWindowSize().y*0.3f), plot_data, bufferSize, 1.3f, IM_COL32(255,255,120,255), this->scaleFactor); + + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + + ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*scaleFactor)); + + if(ImGuiKnobs::Knob("level", &level_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + for(size_t i=0;isetCustomVar(level_float,"LEVEL"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("detune", &detune_float, -12.0f, 12.0f, 0.005f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + detuneCoarse_ctrl.set(detune_float); + this->setCustomVar(detune_float,"DETUNE_COARSE"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("fine", &fine_float, -1.0f, 1.0f, 0.005f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + detuneFine_ctrl.set(fine_float); + this->setCustomVar(fine_float,"DETUNE_FINE"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("pw", &pw_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + pw_ctrl.set(pw_float); + this->setCustomVar(pw_float,"PULSE_WIDTH"); + } + + ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); + if(ImGuiKnobs::Knob("sine", &sine_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + for(size_t i=0;isetCustomVar(sine_float,"SINE_LEVEL"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("triangle", &triangle_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + for(size_t i=0;isetCustomVar(triangle_float,"TRIANGLE_LEVEL"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("saw", &saw_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + for(size_t i=0;isetCustomVar(saw_float,"SAW_LEVEL"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("pulse", &pulse_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + for(size_t i=0;isetCustomVar(pulse_float,"PULSE_LEVEL"); + } + + _nodeCanvas.EndNodeContent(); + + } + +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::drawObjectNodeConfig(){ + + ImGui::Spacing(); + + ImGuiEx::ObjectInfo( + "Polyphonic Oscillator, with up to 16 voices, with antialiased waveforms", + "https://mosaic.d3cod3.org/reference.php?r=polyphonic-oscillator", scaleFactor); +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::removeObjectContent(bool removeFileFromData){ + unusedArgs(removeFileFromData); + + for(map::iterator it = this->pdspOut.begin(); it != this->pdspOut.end(); it++ ){ + it->second.disconnectAll(); + } +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::loadAudioSettings(){ + ofxXmlSettings XML; + +#if OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR < 12 + if (XML.loadFile(patchFile)){ +#else + if (XML.load(patchFile)){ +#endif + if (XML.pushTag("settings")){ + sampleRate = XML.getValue("sample_rate_in",0); + bufferSize = XML.getValue("buffer_size",0); + + plot_data = new float[bufferSize]; + for(int i=0;i *>(_outletParams[5])->push_back(0.0f); + plot_data[i] = 0.0f; + } + + XML.popTag(); + } + } +} + +//-------------------------------------------------------------- +void PolyphonicOscillator::audioOutObject(ofSoundBuffer &outputBuffer){ + unusedArgs(outputBuffer); + + for(size_t i = 0; i < scope.getBuffer().size(); i++) { + float sample = scope.getBuffer().at(i); + plot_data[i] = hardClip(sample); + + // SIGNAL BUFFER DATA + static_cast *>(_outletParams[5])->at(i) = sample; + } + // SIGNALS BUFFERS + static_cast(_outletParams[0])->copyFrom(scope.getBuffer().data(), bufferSize, 1, sampleRate); + static_cast(_outletParams[1])->copyFrom(sine_scope.getBuffer().data(), bufferSize, 1, sampleRate); + static_cast(_outletParams[2])->copyFrom(triangle_scope.getBuffer().data(), bufferSize, 1, sampleRate); + static_cast(_outletParams[3])->copyFrom(saw_scope.getBuffer().data(), bufferSize, 1, sampleRate); + static_cast(_outletParams[4])->copyFrom(pulse_scope.getBuffer().data(), bufferSize, 1, sampleRate); +} + +OBJECT_REGISTER( PolyphonicOscillator, "polyphonic oscillator", OFXVP_OBJECT_CAT_SOUND) + +#endif diff --git a/src/objects/sound/PolyphonicOscillator.h b/src/objects/sound/PolyphonicOscillator.h new file mode 100755 index 00000000..89d6316c --- /dev/null +++ b/src/objects/sound/PolyphonicOscillator.h @@ -0,0 +1,122 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#pragma once + +#include "PatchObject.h" + +#include "imgui-knobs.h" + +#define MAX_OSC_VOICES 16 + +class PolyphonicOscillator : public PatchObject{ + +public: + + PolyphonicOscillator(); + + void newObject() override; + void setupObjectContent(shared_ptr &mainWindow) override; + void setupAudioOutObjectContent(pdsp::Engine &engine) override; + void updateObjectContent(map> &patchObjects) override; + + void drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer) override; + void drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ) override; + void drawObjectNodeConfig() override; + + void removeObjectContent(bool removeFileFromData=false) override; + + void audioOutObject(ofSoundBuffer &outputBuffer) override; + + void loadAudioSettings(); + + + std::vector osc; + std::vector level; + std::vector voice_amp_sine; + std::vector voice_amp_triangle; + std::vector voice_amp_saw; + std::vector voice_amp_pulse; + pdsp::Scope scope; + pdsp::Scope sine_scope; + pdsp::Scope triangle_scope; + pdsp::Scope saw_scope; + pdsp::Scope pulse_scope; + + std::vector level_ctrl; + std::vector pitch_ctrl; + pdsp::ValueControl detuneCoarse_ctrl; + pdsp::ValueControl detuneFine_ctrl; + pdsp::ValueControl pw_ctrl; + + std::vector sine_ctrl; + std::vector triangle_ctrl; + std::vector saw_ctrl; + std::vector pulse_ctrl; + std::vector noise_ctrl; + std::vector voice_ctrl; + + std::vector sineLevel; + std::vector triangleLevel; + std::vector sawLevel; + std::vector pulseLevel; + + float level_float; + std::vector voice_float; + std::vector pitch_float; + float detune_float; + float fine_float; + float pw_float; + + float sine_float; + float triangle_float; + float saw_float; + float pulse_float; + + float *plot_data; + int bufferSize; + int sampleRate; + + bool loaded; + +protected: + + +private: + + OBJECT_FACTORY_PROPS + +}; + +#endif From ac09cfd24989ee7c8827ed39101c95dacd035f6c Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Mon, 13 Jan 2025 16:51:42 +0100 Subject: [PATCH 10/35] small fixes --- src/objects/gui/moPianoKeyboard.cpp | 2 -- src/objects/sound/pdspSynthsCollection.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/objects/gui/moPianoKeyboard.cpp b/src/objects/gui/moPianoKeyboard.cpp index 97a95845..a13c78d6 100755 --- a/src/objects/gui/moPianoKeyboard.cpp +++ b/src/objects/gui/moPianoKeyboard.cpp @@ -130,8 +130,6 @@ void moPianoKeyboard::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // Visualize (Object main view) if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ - - ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 p = ImGui::GetCursorScreenPos(); diff --git a/src/objects/sound/pdspSynthsCollection.h b/src/objects/sound/pdspSynthsCollection.h index 1dcb64b1..8f9b729b 100755 --- a/src/objects/sound/pdspSynthsCollection.h +++ b/src/objects/sound/pdspSynthsCollection.h @@ -45,7 +45,7 @@ struct BassPattern : public pdsp::Sequence{ // helper routine to add notes to the score - // this routin also add a message for stopping the note + // this routine also add a message for stopping the note // so we have to be careful that notes durations don't overlap void note(double step16, float gate, float pitch, float slew, double duration){ message( step16 , gate, 0 ); // adds a trigger on to the gate output From cd19da7ae126625765779dfa1fa88243d5dc3175 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Mon, 13 Jan 2025 17:06:50 +0100 Subject: [PATCH 11/35] Add external panning control for mixer object --- src/objects/sound/Mixer.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/objects/sound/Mixer.cpp b/src/objects/sound/Mixer.cpp index 82ea9918..62a8544e 100755 --- a/src/objects/sound/Mixer.cpp +++ b/src/objects/sound/Mixer.cpp @@ -105,7 +105,7 @@ void Mixer::newObject(){ } static_cast *>(_inletParams[0])->clear(); - static_cast *>(_inletParams[0])->assign(signalInlets,0.0f); + static_cast *>(_inletParams[0])->assign(signalInlets*2,0.0f); } @@ -133,7 +133,6 @@ void Mixer::setupAudioOutObjectContent(pdsp::Engine &engine){ this->pdspIn[i+1] >> levelsL[i] >> mixL; this->pdspIn[i+1] >> levelsR[i] >> mixR; - } mixL >> this->pdspOut[0]; @@ -148,8 +147,10 @@ void Mixer::updateObjectContent(map> &patchObjects){ if(this->inletsConnected[0] && !static_cast *>(_inletParams[0])->empty()){ for(int i=0;i(static_cast *>(_inletParams[0])->size());i++){ - if(i < signalInlets){ + if(i < signalInlets){ // volumes levels_float[i] = static_cast *>(_inletParams[0])->at(i); + }else if(i >= signalInlets && i < signalInlets*2){ // pans + pans_float[i-signalInlets] = static_cast *>(_inletParams[0])->at(i); } } } @@ -262,7 +263,7 @@ void Mixer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ //-------------------------------------------------------------- void Mixer::drawObjectNodeConfig(){ ImGui::Spacing(); - if(ImGui::InputInt("Inlets",&signalInlets)){ + if(ImGui::InputInt("Channels",&signalInlets)){ if(signalInlets > MAX_INLETS-1){ signalInlets = MAX_INLETS-1; } @@ -270,7 +271,7 @@ void Mixer::drawObjectNodeConfig(){ signalInlets = 2; } } - ImGui::SameLine(); ImGuiEx::HelpMarker("You can set 31 inlets max."); + ImGui::SameLine(); ImGuiEx::HelpMarker("You can set 31 channels max."); ImGui::Spacing(); if(ImGui::Button("APPLY",ImVec2(224*scaleFactor,26*scaleFactor))){ this->setCustomVar(static_cast(signalInlets),"NUM_INLETS"); @@ -278,7 +279,7 @@ void Mixer::drawObjectNodeConfig(){ } ImGuiEx::ObjectInfo( - "Line mixer, mix up to 31 audio signals", + "Line mixer, mix up to 31 audio signals. Volumes and panning can be controlled from the first data inlet, for example with a 6 channels mixer, the first inlet can receive a data cable ( green ) with 12 numbers, the first 6 will control volumes, and the last 6 will control panning.)", "https://mosaic.d3cod3.org/reference.php?r=mixer", scaleFactor); } @@ -346,7 +347,7 @@ void Mixer::resetInletsSettings(){ _inletParams[0] = new vector(); static_cast *>(_inletParams[0])->clear(); - static_cast *>(_inletParams[0])->assign(signalInlets,0.0f); + static_cast *>(_inletParams[0])->assign(signalInlets*2,0.0f); for(int i=1;inumInlets;i++){ _inletParams[i] = new ofSoundBuffer(); From c8d2c569fae60bbe48d78d973c6586d5727543d0 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sun, 19 Jan 2025 08:19:10 +0100 Subject: [PATCH 12/35] testing gitsponsor badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f3e51bc4..352dd5d1 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ ![Mosaic 0.6.9](https://github.com/d3cod3/Mosaic/raw/master/process/img/31_sintax03.jpg) Screenshot from project [Mosaic](http://mosaic.d3cod3.org/), embedding ofxVisualProgramming +[](https://api.gitsponsors.com/api/badge/link?p=tgnYu66qaW28hhsub8U73h/4TnJi8aLTLGgzmMfYEZ7DY8cNqS2Un7vgPqVX7SlYqFwRY5qd+e2oo6aDUARjNSjzZDoQLpPOhgddP/VgXVmErTr5zRyPCS9nC9xEO7Uz) + Table of Contents ================= From 0c4d8ac5f6f2ee1217676417635ba6fd429fd717 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sun, 19 Jan 2025 18:05:02 +0100 Subject: [PATCH 13/35] removing spammers badge --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 352dd5d1..f3e51bc4 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ ![Mosaic 0.6.9](https://github.com/d3cod3/Mosaic/raw/master/process/img/31_sintax03.jpg) Screenshot from project [Mosaic](http://mosaic.d3cod3.org/), embedding ofxVisualProgramming -[](https://api.gitsponsors.com/api/badge/link?p=tgnYu66qaW28hhsub8U73h/4TnJi8aLTLGgzmMfYEZ7DY8cNqS2Un7vgPqVX7SlYqFwRY5qd+e2oo6aDUARjNSjzZDoQLpPOhgddP/VgXVmErTr5zRyPCS9nC9xEO7Uz) - Table of Contents ================= From 8a65c9a0e5d8d3c817aa7f9e7a891f0f54d23a8a Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Mon, 20 Jan 2025 16:06:10 +0100 Subject: [PATCH 14/35] updated midi receiver to receive multiple simultanously midi messages, for piano keyboard and polyphonic oscillator objects --- src/objects/communications/MidiReceiver.cpp | 84 ++++++++++++++++++++- src/objects/communications/MidiReceiver.h | 19 +++-- src/objects/communications/MidiSender.cpp | 2 +- src/objects/gui/moPianoKeyboard.cpp | 63 ++++++++++------ src/objects/gui/moPianoKeyboard.h | 1 + src/objects/sound/PolyphonicOscillator.cpp | 27 +++++-- 6 files changed, 155 insertions(+), 41 deletions(-) diff --git a/src/objects/communications/MidiReceiver.cpp b/src/objects/communications/MidiReceiver.cpp index 50ad3342..95913c95 100644 --- a/src/objects/communications/MidiReceiver.cpp +++ b/src/objects/communications/MidiReceiver.cpp @@ -38,7 +38,7 @@ MidiReceiver::MidiReceiver() : PatchObject("midi receiver"){ this->numInlets = 0; - this->numOutlets = 5; + this->numOutlets = 6; _outletParams[0] = new float(); // channel *(float *)&_outletParams[0] = 0.0f; @@ -50,10 +50,12 @@ MidiReceiver::MidiReceiver() : PatchObject("midi receiver"){ *(float *)&_outletParams[3] = 0.0f; _outletParams[4] = new float(); // velocity *(float *)&_outletParams[4] = 0.0f; + _outletParams[5] = new vector(); // midi notes array ( polyphony ) this->initInletsState(); midiDeviceID = 0; + isLogging = false; this->width *= 2; @@ -70,6 +72,7 @@ void MidiReceiver::newObject(){ this->addOutlet(VP_LINK_NUMERIC,"value"); this->addOutlet(VP_LINK_NUMERIC,"pitch"); this->addOutlet(VP_LINK_NUMERIC,"velocity"); + this->addOutlet(VP_LINK_ARRAY,"midi notes"); this->setCustomVar(static_cast(midiDeviceID),"DEVICE_ID"); } @@ -81,6 +84,8 @@ void MidiReceiver::setupObjectContent(shared_ptr &mainWindow){ midiIn.listInPorts(); midiDevicesList = midiIn.getInPortList(); + emptyVec.assign(1,0.0f); + } //-------------------------------------------------------------- @@ -88,17 +93,57 @@ void MidiReceiver::updateObjectContent(map> &patchOb if(midiDevicesList.size() > 0){ if(midiIn.isOpen()){ + /// queued message handling + if(midiIn.hasWaitingMessages()) { + ofxMidiMessage message; + + // add the latest message to the message queue + while(midiIn.getNextMessage(message)) { + midiMessages.push_back(message); + } + + // remove any old messages if we have too many + while(midiMessages.size() > maxMessages) { + midiMessages.erase(midiMessages.begin()); + } + } + // last message data *(float *)&_outletParams[0] = lastMessage.channel; *(float *)&_outletParams[1] = lastMessage.control; *(float *)&_outletParams[2] = lastMessage.value; *(float *)&_outletParams[3] = lastMessage.pitch; *(float *)&_outletParams[4] = lastMessage.velocity; + // message queue data + static_cast *>(_outletParams[5])->clear(); + static_cast *>(_outletParams[5])->push_back(0); // vector first position save number of notes ON + + for(size_t i=0;i::iterator it = midinotes.begin(); it != midinotes.end(); it++ ){ + if(it->second > 0){ + static_cast *>(_outletParams[5])->at(0) += 1; + static_cast *>(_outletParams[5])->push_back(it->first); + static_cast *>(_outletParams[5])->push_back(it->second); + } + } + + }else{ *(float *)&_outletParams[0] = 0.0f; *(float *)&_outletParams[1] = 0.0f; *(float *)&_outletParams[2] = 0.0f; *(float *)&_outletParams[3] = 0.0f; *(float *)&_outletParams[4] = 0.0f; + + *static_cast *>(_outletParams[5]) = emptyVec; } } @@ -185,6 +230,9 @@ void MidiReceiver::drawObjectNodeConfig(){ } ImGui::EndCombo(); } + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Checkbox("Log MIDI",&isLogging); }else{ ImGui::Text("No MIDI devices found!"); @@ -197,7 +245,7 @@ void MidiReceiver::drawObjectNodeConfig(){ ImGuiEx::ObjectInfo( - "Receive data from a physical midi interface", + "Receive data from a physical/virtual midi interface", "https://mosaic.d3cod3.org/reference.php?r=midi-receiver", scaleFactor); } @@ -254,6 +302,38 @@ void MidiReceiver::rescanMIDI(){ void MidiReceiver::newMidiMessage(ofxMidiMessage& msg){ //ofLog(OF_LOG_NOTICE,"%s",msg.toString().c_str()); lastMessage = msg; + + if(isLogging){ + if(msg.status < MIDI_SYSEX) { + if(msg.status == MIDI_NOTE_ON || msg.status == MIDI_NOTE_OFF) { + ofLog(OF_LOG_NOTICE,"MIDI Message STATUS: %s, PITCH: %i, VELOCITY: %i",ofxMidiMessage::getStatusString(msg.status).c_str(),msg.pitch,msg.velocity); + } + } + if(msg.status == MIDI_CONTROL_CHANGE) { + ofLog(OF_LOG_NOTICE,"MIDI Message STATUS: %s, CONTROL: %i, VALUE: %i",ofxMidiMessage::getStatusString(msg.status).c_str(),msg.control,msg.value); + } + else if(msg.status == MIDI_PROGRAM_CHANGE) { + ofLog(OF_LOG_NOTICE,"MIDI Message STATUS: %s, VALUE: %i",ofxMidiMessage::getStatusString(msg.status).c_str(),msg.value); + } + else if(msg.status == MIDI_PITCH_BEND) { + ofLog(OF_LOG_NOTICE,"MIDI Message STATUS: %s, VALUE: %i",ofxMidiMessage::getStatusString(msg.status).c_str(),msg.value); + } + else if(msg.status == MIDI_AFTERTOUCH) { + ofLog(OF_LOG_NOTICE,"MIDI Message STATUS: %s, VALUE: %i",ofxMidiMessage::getStatusString(msg.status).c_str(),msg.value); + } + else if(msg.status == MIDI_POLY_AFTERTOUCH) { + ofLog(OF_LOG_NOTICE,"MIDI Message STATUS: %s, PITCH: %i, VALUE: %i",ofxMidiMessage::getStatusString(msg.status).c_str(),msg.pitch,msg.value); + } + + } + + // add the latest message to the message queue + midiMessages.push_back(msg); + + // remove any old messages if we have too many + while(midiMessages.size() > maxMessages) { + midiMessages.erase(midiMessages.begin()); + } } OBJECT_REGISTER( MidiReceiver, "midi receiver", OFXVP_OBJECT_CAT_COMMUNICATIONS) diff --git a/src/objects/communications/MidiReceiver.h b/src/objects/communications/MidiReceiver.h index ce5b618e..355cf270 100644 --- a/src/objects/communications/MidiReceiver.h +++ b/src/objects/communications/MidiReceiver.h @@ -60,13 +60,18 @@ class MidiReceiver : public PatchObject, public ofxMidiListener { void newMidiMessage(ofxMidiMessage& msg) override; - ofxMidiIn midiIn; - ofxMidiMessage lastMessage; - - vector midiDevicesList; - int midiDeviceID; - - bool loaded; + ofxMidiIn midiIn; + ofxMidiMessage lastMessage; + std::vector midiMessages; ///< received messages + std::size_t maxMessages = 16; ///< max number of messages to keep track of + std::map midinotes; + + std::vector midiDevicesList; + int midiDeviceID; + + std::vector emptyVec; + bool isLogging; + bool loaded; protected: diff --git a/src/objects/communications/MidiSender.cpp b/src/objects/communications/MidiSender.cpp index 80c346ab..60a4d77b 100644 --- a/src/objects/communications/MidiSender.cpp +++ b/src/objects/communications/MidiSender.cpp @@ -201,7 +201,7 @@ void MidiSender::drawObjectNodeConfig(){ ImGuiEx::ObjectInfo( - "Send data to a physical ( or virtual ) midi interface", + "Send data to a physical/virtual midi interface", "https://mosaic.d3cod3.org/reference.php?r=midi-sender", scaleFactor); } diff --git a/src/objects/gui/moPianoKeyboard.cpp b/src/objects/gui/moPianoKeyboard.cpp index a13c78d6..4ce8608a 100755 --- a/src/objects/gui/moPianoKeyboard.cpp +++ b/src/objects/gui/moPianoKeyboard.cpp @@ -41,18 +41,12 @@ static bool has_black(int key) { //-------------------------------------------------------------- moPianoKeyboard::moPianoKeyboard() : PatchObject("piano keyboard"){ - this->numInlets = 2; - this->numOutlets = 2; + this->numInlets = 1; + this->numOutlets = 1; - _inletParams[0] = new float(); // pitch (index) - *(float *)&_inletParams[0] = 0.0f; - _inletParams[1] = new float(); // velocity - *(float *)&_inletParams[1] = 0.0f; + _inletParams[0] = new vector(); // midi notes array ( polyphony ) - _outletParams[0] = new float(); // pitch - *(float *)&_outletParams[0] = 0.0f; - _outletParams[1] = new float(); // velocity - *(float *)&_outletParams[1] = 0.0f; + _outletParams[0] = new vector(); // notes this->initInletsState(); @@ -67,11 +61,9 @@ moPianoKeyboard::moPianoKeyboard() : PatchObject("piano keyboard"){ void moPianoKeyboard::newObject(){ PatchObject::setName( this->objectName ); - this->addInlet(VP_LINK_NUMERIC,"pitch"); - this->addInlet(VP_LINK_NUMERIC,"velocity"); + this->addInlet(VP_LINK_ARRAY,"midi notes"); - this->addOutlet(VP_LINK_NUMERIC,"pitch"); - this->addOutlet(VP_LINK_NUMERIC,"velocity"); + this->addOutlet(VP_LINK_ARRAY,"notes"); } @@ -79,20 +71,41 @@ void moPianoKeyboard::newObject(){ void moPianoKeyboard::setupObjectContent(shared_ptr &mainWindow){ unusedArgs(mainWindow); + static_cast *>(_outletParams[0])->assign(128,0.0f); } //-------------------------------------------------------------- void moPianoKeyboard::updateObjectContent(map> &patchObjects){ unusedArgs(patchObjects); - if(this->inletsConnected[0] && this->inletsConnected[1]){ - key_states[static_cast(*(float *)&_inletParams[0])] = static_cast(*(float *)&_inletParams[1]); - *(float *)&_outletParams[0] = *(float *)&_inletParams[0]; - *(float *)&_outletParams[1] = *(float *)&_inletParams[1]; + if(this->inletsConnected[0]){ + for(size_t i =0;i<256;i++){ + key_states[i] = 0; + } + for(size_t i=0;i *>(_outletParams[0])->size();i++){ + static_cast *>(_outletParams[0])->at(i) = 0; + } + if(static_cast *>(_inletParams[0])->size()>2){ + for(size_t i=0;i *>(_inletParams[0])->size()-2;i++){ + key_states[static_cast(static_cast *>(_inletParams[0])->at(i+1))] = static_cast(static_cast *>(_inletParams[0])->at(i+2)); + if(static_cast(static_cast *>(_inletParams[0])->at(i+1)) >= 21 && static_cast(static_cast *>(_inletParams[0])->at(i+1)) <= 108){ + static_cast *>(_outletParams[0])->at(static_cast(static_cast *>(_inletParams[0])->at(i+1))) = static_cast(static_cast *>(_inletParams[0])->at(i+2)); + }else{ + static_cast *>(_outletParams[0])->at(static_cast(static_cast *>(_inletParams[0])->at(i+1))) = 0; + } + i++; + } + } }else{ - *(float *)&_outletParams[0] = pitch; - *(float *)&_outletParams[1] = 127.0f; + for(size_t i=0;i *>(_outletParams[0])->size();i++){ + if(i == pitch && pitch >= 21 && pitch <= 108){ + static_cast *>(_outletParams[0])->at(i) = 127; + }else{ + static_cast *>(_outletParams[0])->at(i) = 0; + } + } + } if(!loaded){ @@ -138,12 +151,13 @@ void moPianoKeyboard::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ for (int key = 0; key < 52; key++) { ImU32 col = White; ImRect tecla = ImRect(ImVec2(p.x + key * width + (width/4), p.y),ImVec2(p.x + key * width + width - (width/4), p.y + ((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT))); - bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0] && !this->inletsConnected[1]; + bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0]; if ((key_states[cur_key] || is_segment_hovered)) { - if(ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)){ + if(ofGetMousePressed(OF_MOUSE_BUTTON_LEFT) && is_segment_hovered){ col = Yellow; pitch = cur_key; + }else{ col = Gray; pitch = 0; @@ -168,12 +182,13 @@ void moPianoKeyboard::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ if (has_black(key)) { ImU32 col = Black; ImRect tecla = ImRect(ImVec2(p.x + key * width + width * 3 / 4, p.y),ImVec2(p.x + key * width + width * 5 / 4 + 1, p.y + (((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)/3*2))); - bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0] && !this->inletsConnected[1]; + bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0]; if ((key_states[cur_key] || is_segment_hovered)) { - if(ofGetMousePressed(OF_MOUSE_BUTTON_LEFT)){ + if(ofGetMousePressed(OF_MOUSE_BUTTON_LEFT) && is_segment_hovered){ col = Yellow; pitch = cur_key; + }else{ col = Gray; pitch = 0; diff --git a/src/objects/gui/moPianoKeyboard.h b/src/objects/gui/moPianoKeyboard.h index 3647d5da..140326d0 100755 --- a/src/objects/gui/moPianoKeyboard.h +++ b/src/objects/gui/moPianoKeyboard.h @@ -56,6 +56,7 @@ class moPianoKeyboard : public PatchObject { void keydown(int key, int velocity); std::vector current_notes(); + std::vector emptyVec; int pitch; bool loaded; diff --git a/src/objects/sound/PolyphonicOscillator.cpp b/src/objects/sound/PolyphonicOscillator.cpp index 16329518..2fd31bd1 100755 --- a/src/objects/sound/PolyphonicOscillator.cpp +++ b/src/objects/sound/PolyphonicOscillator.cpp @@ -245,16 +245,29 @@ void PolyphonicOscillator::updateObjectContent(map> unusedArgs(patchObjects); if(this->inletsConnected[0] && static_cast *>(_inletParams[0])->size()>0){ + size_t counter = 0; + size_t activeVoices = 0; for(size_t i=0;i *>(_inletParams[0])->size();i++){ - if(i *>(_inletParams[0])->at(i),0,127); - pitch_ctrl.at(i).set(pitch_float.at(i)); - voice_float.at(i) = 1.0f/static_cast *>(_inletParams[0])->size(); - voice_ctrl.at(i).set(voice_float.at(i)); + if(static_cast *>(_inletParams[0])->at(i) > 0){ + activeVoices++; + } + } + if(activeVoices > MAX_OSC_VOICES){ + activeVoices = MAX_OSC_VOICES; + } + for(size_t i=0;i *>(_inletParams[0])->size();i++){ + if(static_cast *>(_inletParams[0])->at(i) > 0){ + if(counter *>(_inletParams[0])->size() <= MAX_OSC_VOICES){ - for(size_t i=static_cast *>(_inletParams[0])->size()-1;i Date: Tue, 21 Jan 2025 16:14:41 +0100 Subject: [PATCH 15/35] added parametric equalizer object --- src/core/imgui_plot.cpp | 58 ++++++++++++ src/core/imgui_plot.h | 6 ++ src/objects/sound/pdspParametricEQ.cpp | 124 +++++++++++++++++++++---- src/objects/sound/pdspParametricEQ.h | 5 + 4 files changed, 176 insertions(+), 17 deletions(-) diff --git a/src/core/imgui_plot.cpp b/src/core/imgui_plot.cpp index dbe278ff..03ce372f 100644 --- a/src/core/imgui_plot.cpp +++ b/src/core/imgui_plot.cpp @@ -427,4 +427,62 @@ void PlotBands(ImDrawList* drawList, float width, float height, std::vector *data, float max, bool useCanvas, ImU32 color){ + + ImGuiWindow* Window = ImGui::GetCurrentWindow(); + + // prepare canvas + const float dim = width > 0 ? width : ImGui::GetContentRegionAvail().x; + ImVec2 Canvas(dim, height); + + ImRect bb(Window->DC.CursorPos, Window->DC.CursorPos + Canvas); + if(useCanvas) ImGui::ItemSize(bb); + + float bin_w = Canvas.x / data->size(); + int data_size = data->size()+3; + + ImVec2 *points = new ImVec2[data_size]; + points[0] = ImVec2(bb.Min.x,bb.Max.y); + for(unsigned int i=0;isize();i++){ + points[i+1] = ImVec2( bb.Min.x + (bin_w*i),bb.Min.y+(Canvas.y*(max-data->at(i))) ); + } + points[data->size()+1] = ImVec2(bb.Max.x,bb.Max.y); + points[data->size()+2] = ImVec2(bb.Min.x,bb.Max.y); + + drawList->AddConcavePolyFilled(points,data_size,color); +} + +void PlotEQFilter(ImDrawList* drawList, float width, float height, std::vector *data, float max, bool useCanvas, ImU32 color){ + + ImGuiWindow* Window = ImGui::GetCurrentWindow(); + + // prepare canvas + const float dim = width > 0 ? width : ImGui::GetContentRegionAvail().x; + ImVec2 Canvas(dim, height); + + ImRect bb(Window->DC.CursorPos, Window->DC.CursorPos + Canvas); + if(useCanvas) ImGui::ItemSize(bb); + + float bin_w = Canvas.x / data->size(); + + ImVec2 *points = new ImVec2[data->size()]; + for(unsigned int i=0;isize();i++){ + points[i] = ImVec2( bb.Min.x + (bin_w*i),bb.Min.y+(Canvas.y*(data->at(i)*-1*max)) - height/2 ); + } + drawList->AddPolyline(points,data->size(),color,0,3); +} + +void PlotEQPoint(ImDrawList* drawList,ImVec2 pos,float width, float height, float max,ImU32 color){ + ImGuiWindow* Window = ImGui::GetCurrentWindow(); + + // prepare canvas + const float dim = width > 0 ? width : ImGui::GetContentRegionAvail().x; + ImVec2 Canvas(dim, height); + + ImRect bb(Window->DC.CursorPos, Window->DC.CursorPos + Canvas); + //ImGui::ItemSize(bb); + + drawList->AddCircleFilled(ImVec2(bb.Min.x + pos.x,bb.Min.y + (Canvas.y*pos.y*-1*max) - height/2), 4, color,20); +} + } diff --git a/src/core/imgui_plot.h b/src/core/imgui_plot.h index c1242f2f..f29f8bf9 100644 --- a/src/core/imgui_plot.h +++ b/src/core/imgui_plot.h @@ -117,4 +117,10 @@ void VUMeter(ImDrawList* drawList, float width, float height,float _vol, bool ho void PlotBands(ImDrawList* drawList, float width, float height, std::vector *data, float max=1.0f, ImU32 color=IM_COL32(255,255,120,255)); +void PlotSpectrum(ImDrawList* drawList, float width, float height, std::vector *data, float max=1.0f, bool useCanvas=true, ImU32 color=IM_COL32(255,255,255,150)); + +void PlotEQFilter(ImDrawList* drawList, float width, float height, std::vector *data, float max=1.0f, bool useCanvas=true, ImU32 color=IM_COL32(255,255,255,255)); + +void PlotEQPoint(ImDrawList* drawList,ImVec2 pos,float width, float height,float max,ImU32 color=IM_COL32(255,255,255,255)); + } diff --git a/src/objects/sound/pdspParametricEQ.cpp b/src/objects/sound/pdspParametricEQ.cpp index 5835ae4b..30349fa9 100755 --- a/src/objects/sound/pdspParametricEQ.cpp +++ b/src/objects/sound/pdspParametricEQ.cpp @@ -34,6 +34,30 @@ #include "pdspParametricEQ.h" +//-------------------------------------------------------------- +static inline float lowShelfFn(float x, float amplitude, float center, float width){ + float base = (x - center) / width; // divide top by bottom + base *= base * -.5; // square top and bottom, multiply by -1/2 + base = exp(base); // take pow(e, base) + if(x < center){ + return amplitude; + }else{ + return amplitude * base; + } +} + +//-------------------------------------------------------------- +static inline float hiShelfFn(float x, float amplitude, float center, float width){ + float base = (x - center) / width; // divide top by bottom + base *= base * -.5; // square top and bottom, multiply by -1/2 + base = exp(base); // take pow(e, base) + if(x > center){ + return amplitude; + }else{ + return amplitude * base; + } +} + //-------------------------------------------------------------- pdspParametricEQ::pdspParametricEQ() : PatchObject("parametric EQ"){ @@ -64,8 +88,8 @@ pdspParametricEQ::pdspParametricEQ() : PatchObject("parametric EQ"){ float_h1Q = 1.0f; float_h1gain = 0.0f; - this->width *= 2.5; - this->height *= 2.0f; + this->width *= 2.7f; + this->height *= 3.2f; loaded = false; @@ -153,9 +177,8 @@ void pdspParametricEQ::setupAudioOutObjectContent(pdsp::Engine &engine){ h1_gain.set(float_h1gain); h1_gain.enableSmoothing(50.0f); - // equalizers modules not working -- NEED FIXING - this->pdspIn[0] >> l1 >> this->pdspOut[0]; // >> l1 >> m1 >> m2 >> h1 - this->pdspIn[0] >> l1 >> scope >> engine.blackhole(); + this->pdspIn[0] >> l1 >> m1 >> m2 >> h1 >> this->pdspOut[0]; // + this->pdspIn[0] >> l1 >> m1 >> m2 >> h1 >> scope >> engine.blackhole(); } @@ -164,19 +187,19 @@ void pdspParametricEQ::updateObjectContent(map> &pat unusedArgs(patchObjects); l1_freq.set(float_l1freq); - l1_Q >> l1.in_Q(); + l1_Q.set(float_l1Q); l1_gain.set(float_l1gain); m1_freq.set(float_m1freq); - m1_Q >> m1.in_Q(); + m1_Q.set(float_m1Q); m1_gain.set(float_m1gain); m2_freq.set(float_m2freq); - m2_Q >> m2.in_Q(); + m2_Q.set(float_m2Q); m2_gain.set(float_m2gain); h1_freq.set(float_h1freq); - h1_Q >> h1.in_Q(); + h1_Q.set(float_h1Q); h1_gain.set(float_h1gain); @@ -218,28 +241,76 @@ void pdspParametricEQ::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*2*scaleFactor)); // Signal FFT - ImGuiEx::PlotBands(_nodeCanvas.getNodeDrawList(), 0, (ImGui::GetWindowSize().y/2) - 26*scaleFactor, static_cast *>(_outletParams[1]),1.0f,IM_COL32(255,255,120,255)); - // parametric eq points -- TODO - + ImGuiEx::PlotSpectrum(_nodeCanvas.getNodeDrawList(), 0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor, static_cast *>(_outletParams[1]),1.0f,true,IM_COL32(90,90,80,235)); + // parametric eq points + //ImGuiEx::PlotEQPoint(_nodeCanvas.getNodeDrawList(),ImVec2((float_l1freq/27000.0f)*this->width*scaleFactor*_nodeCanvas.GetCanvasScale(),float_l1gain/20.0f),0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor,0.3,IM_COL32(118,57,52,255)); + //ImGuiEx::PlotEQPoint(_nodeCanvas.getNodeDrawList(),ImVec2((float_m1freq/27000.0f)*this->width*scaleFactor*_nodeCanvas.GetCanvasScale(),float_m1gain/20.0f),0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor,0.3,IM_COL32(38,95,90,255)); + //ImGuiEx::PlotEQPoint(_nodeCanvas.getNodeDrawList(),ImVec2((float_m2freq/27000.0f)*this->width*scaleFactor*_nodeCanvas.GetCanvasScale(),float_m2gain/20.0f),0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor,0.3,IM_COL32(60,80,100,255)); + //ImGuiEx::PlotEQPoint(_nodeCanvas.getNodeDrawList(),ImVec2((float_h1freq/27000.0f)*this->width*scaleFactor*_nodeCanvas.GetCanvasScale(),float_h1gain/20.0f),0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor,0.3,IM_COL32(84,70,84,255)); + // parametric eq func + ImGuiEx::PlotEQFilter(_nodeCanvas.getNodeDrawList(), 0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor, l1Filter, 0.5f, false, IM_COL32(88,27,22,245)); + ImGuiEx::PlotEQFilter(_nodeCanvas.getNodeDrawList(), 0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor, m1Filter, 0.5f, false, IM_COL32(8,65,60,245)); + ImGuiEx::PlotEQFilter(_nodeCanvas.getNodeDrawList(), 0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor, m2Filter, 0.5f, false, IM_COL32(30,50,70,245)); + ImGuiEx::PlotEQFilter(_nodeCanvas.getNodeDrawList(), 0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor, h1Filter, 0.5f, false, IM_COL32(54,40,54,245)); + ImGuiEx::PlotEQFilter(_nodeCanvas.getNodeDrawList(), 0, (ImGui::GetWindowSize().y/3) - 26*scaleFactor, parametricFilter, 1.5f, true, IM_COL32(190,190,190,215)); + + ImGui::SetCursorPos(ImVec2(0, (ImGui::GetWindowSize().y/3))); // LF - if(ImGuiKnobs::Knob("Freq Hz", &float_l1freq, 20.0f, 500.0f, 1.0f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + ImGui::Dummy(ImVec2(-1,14*scaleFactor)); + if(ImGuiKnobs::Knob("LF Freq", &float_l1freq, 20.0f, 500.0f, 1.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(float_l1freq,"LF_FREQ"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("Q", &float_l1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + if(ImGuiKnobs::Knob("LF Q", &float_l1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(float_l1Q,"LF_Q"); } ImGui::SameLine(); - if(ImGuiKnobs::Knob("Gain dB", &float_l1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + if(ImGuiKnobs::Knob("LF Gain", &float_l1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ this->setCustomVar(float_l1gain,"LF_GAIN"); } // LMF + ImGui::SameLine(); + if(ImGuiKnobs::Knob("LMF Freq", &float_m1freq, 30.0f, 2000.0f, 10.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_m1freq,"LMF_FREQ"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("LMF Q", &float_m1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_m1Q,"LMF_Q"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("LMF Gain", &float_m1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_m1gain,"LMF_GAIN"); + } // HMF + ImGui::Dummy(ImVec2(-1,14*scaleFactor)); + if(ImGuiKnobs::Knob("HMF Freq", &float_m2freq, 500.0f, 5000.0f, 10.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_m2freq,"HMF_FREQ"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("HMF Q", &float_m2Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_m2Q,"HMF_Q"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("HMF Gain", &float_m2gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_m2gain,"HMF_GAIN"); + } // HF + ImGui::SameLine(); + if(ImGuiKnobs::Knob("HF Freq", &float_h1freq, 1000.0f, 20000.0f, 10.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_h1freq,"HF_FREQ"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("HF Q", &float_h1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_h1Q,"HF_Q"); + } + ImGui::SameLine(); + if(ImGuiKnobs::Knob("HF Gain", &float_h1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(float_h1gain,"HF_GAIN"); + } _nodeCanvas.EndNodeContent(); @@ -284,9 +355,20 @@ void pdspParametricEQ::loadAudioSettings(){ fft = ofxFft::create(bufferSize, OF_FFT_WINDOW_HAMMING); spectrum = new float[fft->getBinSize()]; + l1Filter = new std::vector; + m1Filter = new std::vector; + m2Filter = new std::vector; + h1Filter = new std::vector; + parametricFilter = new std::vector; for(int i=0;igetBinSize();i++){ static_cast *>(_outletParams[1])->push_back(0.0f); + + l1Filter->push_back(0.0f); + m1Filter->push_back(0.0f); + m2Filter->push_back(0.0f); + h1Filter->push_back(0.0f); + parametricFilter->push_back(0.0f); } } } @@ -305,11 +387,19 @@ void pdspParametricEQ::audioOutObject(ofSoundBuffer &outputBuffer){ // SPECTRUM for(size_t i = 0; i < fft->getBinSize(); i++){ - static_cast *>(_outletParams[1])->at(i) = spectrum[i]; + size_t pos = static_cast(floor((std::log(i+20 / 20.f) / std::log(512.f))*fft->getBinSize())); + if(pos < fft->getBinSize()){ + static_cast *>(_outletParams[1])->at(pos) = spectrum[i]; + } + l1Filter->at(i) = lowShelfFn(i, float_l1gain/20.0f, (std::log(float_l1freq / 20.f) / std::log(1000.f))*this->width, float_l1Q); + m1Filter->at(i) = gaussianFn(i, float_m1gain/20.0f, (std::log(float_m1freq / 20.f) / std::log(1000.f))*this->width, float_m1Q); + m2Filter->at(i) = gaussianFn(i, float_m2gain/20.0f, (std::log(float_m2freq / 20.f) / std::log(1000.f))*this->width, float_m2Q); + h1Filter->at(i) = hiShelfFn(i, float_h1gain/20.0f, (std::log(float_h1freq / 20.f) / std::log(1000.f))*this->width, float_h1Q); + parametricFilter->at(i) = (l1Filter->at(i)+m1Filter->at(i)+m2Filter->at(i)+h1Filter->at(i))/4.0f; } } -//OBJECT_REGISTER( pdspParametricEQ, "parametric EQ", OFXVP_OBJECT_CAT_SOUND) +OBJECT_REGISTER( pdspParametricEQ, "parametric EQ", OFXVP_OBJECT_CAT_SOUND) #endif diff --git a/src/objects/sound/pdspParametricEQ.h b/src/objects/sound/pdspParametricEQ.h index e503e4e7..1e51eb0b 100755 --- a/src/objects/sound/pdspParametricEQ.h +++ b/src/objects/sound/pdspParametricEQ.h @@ -83,6 +83,11 @@ class pdspParametricEQ : public PatchObject{ float float_m2freq, float_m2Q, float_m2gain; float float_h1freq, float_h1Q, float_h1gain; + std::vector *l1Filter; + std::vector *m1Filter; + std::vector *m2Filter; + std::vector *h1Filter; + std::vector *parametricFilter; int bufferSize; int sampleRate; From 04b08d6d7950b785812729f30f050bdfaaf11e1a Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Thu, 23 Jan 2025 11:39:42 +0100 Subject: [PATCH 16/35] mute oscillator on pitch 0.0 --- src/objects/sound/Oscillator.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/objects/sound/Oscillator.cpp b/src/objects/sound/Oscillator.cpp index 9c8f9894..26e6ae2a 100755 --- a/src/objects/sound/Oscillator.cpp +++ b/src/objects/sound/Oscillator.cpp @@ -201,13 +201,23 @@ void Oscillator::setupAudioOutObjectContent(pdsp::Engine &engine){ void Oscillator::updateObjectContent(map> &patchObjects){ unusedArgs(patchObjects); + // silence pitch 0 + if(pitch_float <= 0.0f){ + level_float = 0.0f; + level_ctrl.set(level_float); + } + if(this->inletsConnected[0]){ pitch_float = ofClamp(*(float *)&_inletParams[0],0,127); pitch_ctrl.set(pitch_float); } if(this->inletsConnected[1]){ - level_float = ofClamp(*(float *)&_inletParams[1],0.0f,1.0f); + if(pitch_float > 0.0f){ + level_float = ofClamp(*(float *)&_inletParams[1],0.0f,1.0f); + }else{ + level_float = 0.0f; + } level_ctrl.set(level_float); } @@ -314,8 +324,12 @@ void Oscillator::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ } ImGui::SameLine(); if(ImGuiKnobs::Knob("level", &level_float, 0.0f, 1.0f, 0.01f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ - level_ctrl.set(level_float); - this->setCustomVar(level_float,"LEVEL"); + if(pitch_float > 0.0f){ + level_ctrl.set(level_float); + this->setCustomVar(level_float,"LEVEL"); + }else{ + level_float = 0.0f; + } } ImGui::SameLine(); if(ImGuiKnobs::Knob("detune", &detune_float, -12.0f, 12.0f, 0.005f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ From 02e76eae7200643a81a0d758a242d693a14e4c16 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Thu, 23 Jan 2025 12:04:24 +0100 Subject: [PATCH 17/35] added debug code to visualize dataflow pointer addresses --- src/PatchObject.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/PatchObject.cpp b/src/PatchObject.cpp index e4db768d..ce6ab6bb 100644 --- a/src/PatchObject.cpp +++ b/src/PatchObject.cpp @@ -339,7 +339,9 @@ void PatchObject::drawImGuiNode(ImGuiEx::NodeCanvas& _nodeCanvas, map Date: Thu, 23 Jan 2025 16:02:19 +0100 Subject: [PATCH 18/35] elegant cast template for inlets/outlets data proposal from @Daandelange, already tested and running with number and spigot objects --- src/objects/logic/Spigot.cpp | 26 +++++++++++++------------- src/objects/math/Constant.cpp | 20 +++++++++++--------- src/utils.h | 24 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/objects/logic/Spigot.cpp b/src/objects/logic/Spigot.cpp index 9f2ad4f1..0a73abbc 100644 --- a/src/objects/logic/Spigot.cpp +++ b/src/objects/logic/Spigot.cpp @@ -43,10 +43,10 @@ Spigot::Spigot() : PatchObject("spigot"){ _inletParams[0] = new vector(); // state _inletParams[1] = new float(); // float - *(float *)&_inletParams[1] = 0.0f; + *ofxVP_CAST_PIN_PTR(this->_inletParams[1]) = 0.0f; _inletParams[2] = new string(); // string - *static_cast(_inletParams[2]) = ""; + *ofxVP_CAST_PIN_PTR(this->_inletParams[2]) = ""; _inletParams[3] = new vector(); // vector @@ -55,10 +55,10 @@ Spigot::Spigot() : PatchObject("spigot"){ _inletParams[5] = new ofSoundBuffer(); // signal _outletParams[0] = new float(); // output numeric - *(float *)&_outletParams[0] = 0.0f; + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = 0.0f; _outletParams[1] = new string(); // string - *static_cast(_outletParams[1]) = ""; + *ofxVP_CAST_PIN_PTR(this->_outletParams[1]) = ""; _outletParams[2] = new vector(); // vector @@ -146,24 +146,24 @@ void Spigot::updateObjectContent(map> &patchObjects) } if(isOpen[0]){ - *(float *)&_outletParams[0] = *(float *)&_inletParams[1]; + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = *ofxVP_CAST_PIN_PTR(this->_inletParams[1]); }else{ - *(float *)&_outletParams[0] = -1.0f; + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = -1.0f; } if(isOpen[1]){ - *static_cast(_outletParams[1]) = *static_cast(_inletParams[2]); + *ofxVP_CAST_PIN_PTR(this->_outletParams[1]) = *ofxVP_CAST_PIN_PTR(this->_inletParams[2]); }else{ - *static_cast(_outletParams[1]) = "empty"; + *ofxVP_CAST_PIN_PTR(this->_outletParams[1]) = "empty"; } if(isOpen[2] && !static_cast *>(_inletParams[3])->empty()){ - *static_cast *>(_outletParams[2]) = *static_cast *>(_inletParams[3]); + *ofxVP_CAST_PIN_PTR>(this->_outletParams[2]) = *ofxVP_CAST_PIN_PTR>(this->_inletParams[3]); }else{ - *static_cast *>(_outletParams[2]) = *empty; + *ofxVP_CAST_PIN_PTR>(this->_outletParams[2]) = *empty; } if(isOpen[3]){ - *static_cast(_outletParams[3]) = *static_cast(_inletParams[4]); + *ofxVP_CAST_PIN_PTR(this->_outletParams[3]) = *ofxVP_CAST_PIN_PTR(this->_inletParams[4]); }else{ - *static_cast(_outletParams[3]) = kuro->getTexture(); + *ofxVP_CAST_PIN_PTR(this->_outletParams[3]) = kuro->getTexture(); } } @@ -268,7 +268,7 @@ void Spigot::audioOutObject(ofSoundBuffer &outputBuffer){ if(isOpen[4]){ if(this->inletsConnected[5] && !static_cast(_inletParams[5])->getBuffer().empty()){ - *static_cast(_outletParams[4]) = *static_cast(_inletParams[5]); + *ofxVP_CAST_PIN_PTR(this->_outletParams[4]) = *ofxVP_CAST_PIN_PTR(this->_inletParams[5]); }else{ static_cast(_outletParams[4])->set(0.0f); } diff --git a/src/objects/math/Constant.cpp b/src/objects/math/Constant.cpp index 6271aabf..e7821dc0 100755 --- a/src/objects/math/Constant.cpp +++ b/src/objects/math/Constant.cpp @@ -46,15 +46,17 @@ Constant::Constant() : // Bind Inlets to values _inletParams[0] = new float(); // bang - *(float *)&_inletParams[0] = 0.0f; + *ofxVP_CAST_PIN_PTR(this->_inletParams[0]) = 0.0f; - *(float *)&_inletParams[1] = inputValueNew.get(); // value + _inletParams[1] = new float(); + *ofxVP_CAST_PIN_PTR(this->_inletParams[1]) = inputValueNew.get(); // value // Bind outlets to values - *(float *)&_outletParams[0] = inputValueNew.get(); // float output + _outletParams[0] = new float(); + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = inputValueNew.get(); // float output _outletParams[1] = new string(); // string output - *static_cast(_outletParams[1]) = ""; + *ofxVP_CAST_PIN_PTR(this->_outletParams[1]) = ""; this->initInletsState(); @@ -92,7 +94,7 @@ void Constant::updateObjectContent(map> &patchObject unusedArgs(patchObjects); if(this->inletsConnected[0] && !isON){ - if(*(float *)&_inletParams[0] < 1.0){ + if(*ofxVP_CAST_PIN_PTR(this->_inletParams[0]) < 1.0){ bang = false; }else{ bang = true; @@ -100,18 +102,18 @@ void Constant::updateObjectContent(map> &patchObject } if(this->inletsConnected[1]){ - inputValueNew = *(float *)&_inletParams[1]; + inputValueNew = *ofxVP_CAST_PIN_PTR(this->_inletParams[1]); } if(!nextFrame){ nextFrame = true; - *(float *)&_outletParams[0] = inputValueNew; + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = inputValueNew; } if(bang){ nextFrame = false; - *(float *)&_outletParams[0] = inputValueNew+0.00001f; - *static_cast(_outletParams[1]) = ofToString( inputValueNew.get() ); + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = inputValueNew+0.00001f; + *ofxVP_CAST_PIN_PTR(this->_outletParams[1]) = ofToString( inputValueNew.get() ); } if(!loaded){ diff --git a/src/utils.h b/src/utils.h index 66529385..6b612afd 100644 --- a/src/utils.h +++ b/src/utils.h @@ -38,6 +38,10 @@ #include #endif +#if __cplusplus>=202002L +# include +#endif + #include #include #include @@ -54,6 +58,26 @@ // this macro is used to silent unused variables warnings on virtual functions template void unusedArgs(const Ts&...) {} +// Normal cast for almost any type +template +inline TYPE* ofxVP_CAST_PIN_PTR(void*& _pinData){ + return static_cast(_pinData); +} +// Specialisations/Exceptions : only float is using bit-cast style type-punning +// Basically it reads/writes the address of a pointer as a value using a bitswap, instead of writing the value to the pointed address. +// Note: Accessing the pointer normally will naturally crash the program; it's accessing an invalid memory address. +// Info: https://tttapa.github.io/Pages/Programming/Cpp/Practices/type-punning.html +template<> +inline float* ofxVP_CAST_PIN_PTR(void*& _pinData){ + // Compile-time check, will warn on platforms where this technique doesn't work ! + static_assert(sizeof(float) == sizeof(uint32_t)); +#if __cplusplus>=202002L // C++20 brings native bitcast support ! + return std::bit_cast(&_pinData); +#else + return reinterpret_cast(&_pinData); +#endif +}; + //-------------------------------------------------------------- inline std::string random_string( size_t length ){ From 1fd0d586e88d2935407493302aae8fc2077ca550 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Thu, 23 Jan 2025 23:47:19 +0100 Subject: [PATCH 19/35] fix crash when fail to scan plugin folder by @Daandelange --- src/ofxVisualProgramming.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/ofxVisualProgramming.cpp b/src/ofxVisualProgramming.cpp index bf8987fd..726ee629 100755 --- a/src/ofxVisualProgramming.cpp +++ b/src/ofxVisualProgramming.cpp @@ -175,14 +175,25 @@ void ofxVisualProgramming::setup(ofxImGui::Gui* _guiRef, string release){ #elif defined(TARGET_WIN32) pluginsDir.allowExt("dll"); #endif - pluginsDir.listDir(ofToDataPath(PLUGINS_FOLDER)); - pluginsDir.sort(); + + bool hasPlugins = false; + try{ + pluginsDir.listDir(ofToDataPath(PLUGINS_FOLDER)); + pluginsDir.sort(); + hasPlugins = pluginsDir.size() > 0; + } + catch(std::exception& e){ + // This can throw with OS file permission problems. + ofLog(OF_LOG_WARNING,"Loading plugins: Can't load the plugins folder `%s`. Error: %s", pluginsDir.getOriginalDirectory().c_str(), e.what()); + } // load all plugins - for(unsigned int i = 0; i < pluginsDir.size(); i++){ - ofLog(OF_LOG_NOTICE,"Loading plugin: %s",pluginsDir.getFile(i).getFileName().c_str()); - string tmpPlugPath = pluginsDir.getFile(i).getAbsolutePath(); - plugins_kernel.load_plugin(tmpPlugPath); + if(hasPlugins){ + for(unsigned int i = 0; i < pluginsDir.size(); i++){ + ofLog(OF_LOG_NOTICE,"Loading plugin: %s",pluginsDir.getFile(i).getFileName().c_str()); + string tmpPlugPath = pluginsDir.getFile(i).getAbsolutePath(); + plugins_kernel.load_plugin(tmpPlugPath); + } } // Create new empty file patch From ad5ff7c0b7474663c011389e46acac060f48a069 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Fri, 24 Jan 2025 20:07:37 +0100 Subject: [PATCH 20/35] reordered code --- src/objects/sound/pdspBitCruncher.cpp | 2 +- src/utils.h | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/objects/sound/pdspBitCruncher.cpp b/src/objects/sound/pdspBitCruncher.cpp index 3d35b604..a7fd83f5 100755 --- a/src/objects/sound/pdspBitCruncher.cpp +++ b/src/objects/sound/pdspBitCruncher.cpp @@ -108,7 +108,7 @@ void pdspBitCruncher::updateObjectContent(map> &patc //-------------------------------------------------------------- void pdspBitCruncher::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ - ofSetColor(255); + unusedArgs(font,glRenderer); } //-------------------------------------------------------------- diff --git a/src/utils.h b/src/utils.h index 6b612afd..a1da9b22 100644 --- a/src/utils.h +++ b/src/utils.h @@ -281,6 +281,30 @@ static inline float gaussianFn(float x, float amplitude, float center, float wid return amplitude * base; } +//-------------------------------------------------------------- +static inline float lowShelfFn(float x, float amplitude, float center, float width){ + float base = (x - center) / width; // divide top by bottom + base *= base * -.5; // square top and bottom, multiply by -1/2 + base = exp(base); // take pow(e, base) + if(x < center){ + return amplitude; + }else{ + return amplitude * base; + } +} + +//-------------------------------------------------------------- +static inline float hiShelfFn(float x, float amplitude, float center, float width){ + float base = (x - center) / width; // divide top by bottom + base *= base * -.5; // square top and bottom, multiply by -1/2 + base = exp(base); // take pow(e, base) + if(x > center){ + return amplitude; + }else{ + return amplitude * base; + } +} + //-------------------------------------------------------------- inline std::string execCmd(const char* cmd){ char buffer[128]; From 81aed6f341be9f59fbf0343f3577f2983a83d5cd Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Fri, 24 Jan 2025 20:08:14 +0100 Subject: [PATCH 21/35] added quantizer object --- src/objects/sound/Quantizer.cpp | 398 ++++++++++++++++++++++++++++++++ src/objects/sound/Quantizer.h | 395 +++++++++++++++++++++++++++++++ 2 files changed, 793 insertions(+) create mode 100755 src/objects/sound/Quantizer.cpp create mode 100755 src/objects/sound/Quantizer.h diff --git a/src/objects/sound/Quantizer.cpp b/src/objects/sound/Quantizer.cpp new file mode 100755 index 00000000..757e8234 --- /dev/null +++ b/src/objects/sound/Quantizer.cpp @@ -0,0 +1,398 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#include "Quantizer.h" + +static bool has_black(int key) { + return (key == 0 || key == 1 || key == 3 || key == 4 || key == 5); +} + +//-------------------------------------------------------------- +Quantizer::Quantizer() : PatchObject("quantizer"){ + + this->numInlets = 2; + this->numOutlets = 1; + + _inletParams[0] = new float(); // pitch + *ofxVP_CAST_PIN_PTR(this->_inletParams[0]) = 0.0f; + + _inletParams[1] = new float(); // octave + *ofxVP_CAST_PIN_PTR(this->_inletParams[1]) = 4; + + _outletParams[0] = new float(); // quantized pitch + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = 0.0f; + + this->initInletsState(); + + selectedScale = 0; + octave = 4; + + this->width *= 1.48f; + + loaded = false; + +} + +//-------------------------------------------------------------- +void Quantizer::newObject(){ + PatchObject::setName( this->objectName ); + + this->addInlet(VP_LINK_NUMERIC,"pitch"); + this->addInlet(VP_LINK_NUMERIC,"octave"); + + this->addOutlet(VP_LINK_NUMERIC,"quantized pitch"); + + this->setCustomVar(static_cast(selectedScale),"SCALE"); + this->setCustomVar(static_cast(octave),"OCTAVE"); + +} + +//-------------------------------------------------------------- +void Quantizer::setupObjectContent(shared_ptr &mainWindow){ + unusedArgs(mainWindow); + + quant.Init(); + quantScale = {1,0,0,0,0,0,0,0,0,0,0,0}; + quant.UpdateScale(quantScale); + quant.SetBaseFrequency(440.0f); + + scalesOptions.push_back("None"); + scalesOptions.push_back("Major"); + scalesOptions.push_back("Dorian"); + scalesOptions.push_back("Phrygian"); + scalesOptions.push_back("Lydian"); + scalesOptions.push_back("Myxolodian"); + scalesOptions.push_back("Aeolian - natural Minor"); + scalesOptions.push_back("Locrian"); + scalesOptions.push_back("Acoustic"); + scalesOptions.push_back("Altered"); + scalesOptions.push_back("Augmented"); + scalesOptions.push_back("Bebop dom."); + scalesOptions.push_back("Blues"); + scalesOptions.push_back("Chromatic"); + scalesOptions.push_back("Enigmatic"); + scalesOptions.push_back("Flamenco"); + scalesOptions.push_back("Gypsy"); + scalesOptions.push_back("Half diminished"); + scalesOptions.push_back("harmonic Major"); + scalesOptions.push_back("harmonic Minor"); + scalesOptions.push_back("Hirajoshi"); + scalesOptions.push_back("Hungarian"); + scalesOptions.push_back("Miyako-bushi"); + scalesOptions.push_back("Insen"); + scalesOptions.push_back("Iwato"); + scalesOptions.push_back("Lydian augmented"); + scalesOptions.push_back("Bebop Major"); + scalesOptions.push_back("Locrian Major"); + scalesOptions.push_back("Pentatonic Major"); + scalesOptions.push_back("melodic Minor"); + scalesOptions.push_back("Pentatonic Minor"); + scalesOptions.push_back("Neapolitan Major"); + scalesOptions.push_back("Neapolitan Minor"); + scalesOptions.push_back("Octatonic 1"); + scalesOptions.push_back("Octatonic 2"); + scalesOptions.push_back("Persian"); + scalesOptions.push_back("Phrygian dominant"); + scalesOptions.push_back("Prometheus"); + scalesOptions.push_back("Harmonics"); + scalesOptions.push_back("Tritone"); + scalesOptions.push_back("Tritone 2S"); + scalesOptions.push_back("Ukranian Dorian"); + scalesOptions.push_back("Wholetone"); + +} + +//-------------------------------------------------------------- +void Quantizer::updateObjectContent(map> &patchObjects){ + unusedArgs(patchObjects); + + if(this->inletsConnected[0]){ + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = pdsp::f2p(quant.Process(pdsp::p2f(*ofxVP_CAST_PIN_PTR(this->_inletParams[0])))); + }else{ + *ofxVP_CAST_PIN_PTR(this->_outletParams[0]) = 0; + } + + if(this->inletsConnected[1]){ + if(ofClamp(static_cast(floor(*ofxVP_CAST_PIN_PTR(this->_inletParams[1]))),0,8) != octave){ + quant.SetOctaveModifier(octave-4); + } + octave = ofClamp(static_cast(floor(*ofxVP_CAST_PIN_PTR(this->_inletParams[1]))),0,8); + + } + + if(!loaded){ + loaded = true; + + selectedScale = static_cast(this->getCustomVar("SCALE")); + octave = static_cast(this->getCustomVar("OCTAVE")); + + quant.SetOctaveModifier(octave-4); + updateScale(scalesOptions.at(selectedScale)); + } + +} + +//-------------------------------------------------------------- +void Quantizer::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ + unusedArgs(font,glRenderer); +} + +//-------------------------------------------------------------- +void Quantizer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ + + // CONFIG GUI inside Menu + if(_nodeCanvas.BeginNodeMenu()){ + ImGui::Separator(); + ImGui::Separator(); + ImGui::Separator(); + + if (ImGui::BeginMenu("CONFIG")) + { + + drawObjectNodeConfig(); this->configMenuWidth = ImGui::GetWindowWidth(); + + + ImGui::EndMenu(); + } + _nodeCanvas.EndNodeMenu(); + } + + // Visualize (Object main view) + if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ + + ImDrawList *draw_list = ImGui::GetWindowDrawList(); + ImVec2 p = ImGui::GetCursorScreenPos(); + + int width = 28*_nodeCanvas.GetCanvasScale()*scaleFactor; + int cur_key = 0; + for (int key = 0; key < 7; key++) { + ImU32 col; + ImRect tecla = ImRect(ImVec2(p.x + key * width + (width/4), p.y),ImVec2(p.x + key * width + width - (width/4), p.y + ((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT))); + bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0]; + + if(quantScale[cur_key]) { + col = Yellow; + }else{ + col = Gray; + } + + if(is_segment_hovered){ + if(ImGui::IsMouseReleased(ImGuiMouseButton_Left)){ + quantScale[cur_key] = !quantScale[cur_key]; + quant.UpdateScale(quantScale); + } + } + draw_list->AddRectFilled( + ImVec2(p.x + key * width, p.y), + ImVec2(p.x + key * width + width, p.y + ((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)), + col, 0, ImDrawFlags_RoundCornersAll); + draw_list->AddRect( + ImVec2(p.x + key * width, p.y), + ImVec2(p.x + key * width + width, p.y + ((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)), + Black, 0, ImDrawFlags_RoundCornersAll); + cur_key++; + if (has_black(key)) { + cur_key++; + } + + } + cur_key = 1; + for (int key = 0; key < 7; key++) { + if (has_black(key)) { + ImU32 col; + ImRect tecla = ImRect(ImVec2(p.x + key * width + width * 3 / 4, p.y),ImVec2(p.x + key * width + width * 5 / 4 + 1, p.y + (((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)/3*2))); + bool is_segment_hovered = tecla.Contains(ImGui::GetIO().MousePos) && !this->inletsConnected[0]; + + if(quantScale[cur_key]) { + col = Yellow; + }else{ + col = Gray; + } + + if(is_segment_hovered){ + if(ImGui::IsMouseReleased(ImGuiMouseButton_Left)){ + quantScale[cur_key] = !quantScale[cur_key]; + quant.UpdateScale(quantScale); + } + } + draw_list->AddRectFilled( + ImVec2(p.x + key * width + width * 3 / 4, p.y), + ImVec2(p.x + key * width + width * 5 / 4 + 1, p.y + (((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)/3*2)), + col, 0, ImDrawFlags_RoundCornersAll); + draw_list->AddRect( + ImVec2(p.x + key * width + width * 3 / 4, p.y), + ImVec2(p.x + key * width + width * 5 / 4 + 1, p.y + (((this->height*_nodeCanvas.GetCanvasScale()*scaleFactor)-IMGUI_EX_NODE_HEADER_HEIGHT-IMGUI_EX_NODE_FOOTER_HEIGHT)/3*2)), + Black, 0, ImDrawFlags_RoundCornersAll); + + cur_key += 2; + } else { + cur_key++; + } + } + + _nodeCanvas.EndNodeContent(); + } + +} + +//-------------------------------------------------------------- +void Quantizer::drawObjectNodeConfig(){ + ImGui::Spacing(); + ImGui::Text("Using scale: %s",scalesOptions.at(selectedScale).c_str()); + ImGui::Spacing(); + if(ImGui::BeginCombo("Scales", scalesOptions.at(selectedScale).c_str(),ImGuiComboFlags_HeightLargest )){ + for(int i=0; i < static_cast(scalesOptions.size()); ++i){ + bool is_selected = (selectedScale == i ); + if (ImGui::Selectable(scalesOptions.at(i).c_str(), is_selected)){ + selectedScale = i; + updateScale(scalesOptions.at(selectedScale)); + this->setCustomVar(static_cast(selectedScale),"SCALE"); + } + if (is_selected) ImGui::SetItemDefaultFocus(); + } + + ImGui::EndCombo(); + } + ImGui::Spacing(); + if(ImGui::SliderInt("Octave",&octave,0,8)){ + quant.SetOctaveModifier(octave-4); + this->setCustomVar(static_cast(octave),"OCTAVE"); + } + + ImGuiEx::ObjectInfo( + "Pitch quantizer, select your desired scale and octave to quantize notes", + "https://mosaic.d3cod3.org/reference.php?r=quantizer", scaleFactor); +} + +//-------------------------------------------------------------- +void Quantizer::removeObjectContent(bool removeFileFromData){ + unusedArgs(removeFileFromData); +} + +//-------------------------------------------------------------- +void Quantizer::updateScale(string scalename){ + if(scalename == "None"){ + quantScale = {1,0,0,0,0,0,0,0,0,0,0,0}; + }else if(scalename == "Major"){ + quantScale = {1,0,1,0,1,1,0,1,0,1,0,1}; + }else if(scalename == "Dorian"){ + quantScale = {1,0,1,1,0,1,0,1,0,1,1,0}; + }else if(scalename == "Phrygian"){ + quantScale = {1,1,0,1,0,1,0,1,1,0,1,0}; + }else if(scalename == "Lydian"){ + quantScale = {1,0,1,0,1,0,1,1,0,1,0,1}; + }else if(scalename == "Myxolodian"){ + quantScale = {1,0,1,0,1,1,0,1,0,1,1,0}; + }else if(scalename == "Aeolian - natural Minor"){ + quantScale = {1,0,1,1,0,1,0,1,1,0,1,0}; + }else if(scalename == "Locrian"){ + quantScale = {1,1,0,1,0,1,1,0,1,0,1,0}; + }else if(scalename == "Acoustic"){ + quantScale = {1,0,1,0,1,0,1,1,0,1,1,0}; + }else if(scalename == "Altered"){ + quantScale = {1,1,0,1,1,0,1,0,1,0,1,0}; + }else if(scalename == "Augmented"){ + quantScale = {1,0,0,1,1,0,0,1,1,0,0,1}; + }else if(scalename == "Bebop dom."){ + quantScale = {1,0,1,0,1,1,0,1,0,1,1,1}; + }else if(scalename == "Blues"){ + quantScale = {1,0,0,1,0,1,1,1,0,0,1,0}; + }else if(scalename == "Chromatic"){ + quantScale = {1,1,1,1,1,1,1,1,1,1,1,1}; + }else if(scalename == "Enigmatic"){ + quantScale = {1,1,0,0,1,0,1,0,1,0,1,1}; + }else if(scalename == "Flamenco"){ + quantScale = {1,1,0,0,1,1,0,1,1,0,0,1}; + }else if(scalename == "Gypsy"){ + quantScale = {1,0,1,1,0,0,1,1,1,0,1,0}; + }else if(scalename == "Half diminished"){ + quantScale = {1,0,1,1,0,1,1,0,1,0,1,0}; + }else if(scalename == "harmonic Major"){ + quantScale = {1,0,1,0,1,1,0,1,1,0,0,1}; + }else if(scalename == "harmonic Minor"){ + quantScale = {1,0,1,1,0,1,0,1,1,0,0,1}; + }else if(scalename == "Hirajoshi"){ + quantScale = {1,0,0,0,1,0,1,1,0,0,0,1}; + }else if(scalename == "Hungarian"){ + quantScale = {1,0,1,1,0,0,1,1,1,0,0,1}; + }else if(scalename == "Miyako-bushi"){ + quantScale = {1,1,0,0,0,1,0,1,1,0,0,0}; + }else if(scalename == "Insen"){ + quantScale = {1,1,0,0,0,1,0,1,0,0,1,0}; + }else if(scalename == "Iwato"){ + quantScale = {1,1,0,0,0,1,1,0,0,0,1,0}; + }else if(scalename == "Lydian augmented"){ + quantScale = {1,0,1,0,1,0,1,0,1,1,0,1}; + }else if(scalename == "Bebop Major"){ + quantScale = {1,0,1,0,1,1,0,1,1,0,1,1}; + }else if(scalename == "Locrian Major"){ + quantScale = {1,0,1,0,1,1,1,0,1,0,1,0}; + }else if(scalename == "Pentatonic Major"){ + quantScale = {1,0,1,0,1,0,0,1,0,1,0,0}; + }else if(scalename == "melodic Minor"){ + quantScale = {1,0,1,1,0,1,0,1,0,1,0,1}; + }else if(scalename == "Pentatonic Minor"){ + quantScale = {1,0,0,1,0,1,0,1,0,0,1,0}; + }else if(scalename == "Neapolitan Major"){ + quantScale = {1,1,0,1,0,1,0,1,0,1,0,1}; + }else if(scalename == "Neapolitan Minor"){ + quantScale = {1,1,0,1,0,1,0,1,1,0,0,1}; + }else if(scalename == "Octatonic 1"){ + quantScale = {1,0,1,1,0,1,1,0,1,1,0,1}; + }else if(scalename == "Octatonic 2"){ + quantScale = {1,1,0,1,1,0,1,1,0,1,1,0}; + }else if(scalename == "Persian"){ + quantScale = {1,1,0,0,1,1,1,0,1,0,0,1}; + }else if(scalename == "Phrygian dominant"){ + quantScale = {1,1,0,0,1,1,0,1,1,0,1,0}; + }else if(scalename == "Prometheus"){ + quantScale = {1,0,1,0,1,0,1,0,0,1,1,0}; + }else if(scalename == "Harmonics"){ + quantScale = {1,0,0,1,1,1,0,1,0,1,0,0}; + }else if(scalename == "Tritone"){ + quantScale = {1,1,0,0,1,0,1,1,0,0,1,0}; + }else if(scalename == "Tritone 2S"){ + quantScale = {1,1,1,0,0,0,1,1,1,0,0,0}; + }else if(scalename == "Ukranian Dorian"){ + quantScale = {1,0,1,1,0,0,1,1,0,1,1,0}; + }else if(scalename == "Wholetone"){ + quantScale = {1,0,1,0,1,0,1,0,1,0,1,0}; + } + + quant.UpdateScale(quantScale); +} + +OBJECT_REGISTER( Quantizer, "quantizer", OFXVP_OBJECT_CAT_SOUND) + +#endif diff --git a/src/objects/sound/Quantizer.h b/src/objects/sound/Quantizer.h new file mode 100755 index 00000000..028efaf7 --- /dev/null +++ b/src/objects/sound/Quantizer.h @@ -0,0 +1,395 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#pragma once + +#include "PatchObject.h" + +class ScaleQuantizer +{ + + // ScaleQuantizer Class + // Copyright 2024 Craig Corvin + // + // Author: Craig Corvin + // github: https://github.com/craigcorvin + // + // 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. + // + // See http://creativecommons.org/licenses/MIT/ for more information. + +public: + ScaleQuantizer() {} + ~ScaleQuantizer() {} + void Init() + { + // initialize as a Major scale + // {C, C#, D, D#, E, F, F#, G, G#, A, A#, B} + bool initScale[12] = {1,0,1,0,1,1,0,1,0,1,0,1}; + // update scale to + UpdateScale(initScale); + // update base frequency to C4 + basefrequency_ = 261.625580f; + // standard 12 notes per octave + // can be set to any EDO (Equal Divisions of the Octave) + // initScale array can then be used to create multi-octave poly chords, et cetera + semitonesperoctave_ = 12.0f; + // set to true to not repeat notes in scale until all others have been used + uniquenotes_ = 0; + // octave range of quantization + // range = 0 will only return frequencies in base octave + octaverange_ = 0; + // shift up octaves from basefequency + // octave modifier set to 0 + octavemodifier_ = 0; + // the scale ends with octave of first note + scalewithoctave_ = 0; + } + float Process(float f) + { + + // f is the frequency to be quantized to the scale set in UpdateScale + + int scaleLength = scaleSize; + + // 1 less than scaleLength, done for clarity in reading the code + int scaleLengthSub = scaleLength - 1; + + // convert to chromatic + // starting at 0 + int fincrement = round((logf(f / basefrequency_) / logf(2.0f)) * semitonesperoctave_); + + int increment = fincrement; + + // octave modifier + int octmod = octavemodifier_; + + if (increment > 0) + { + // while (increment > 11) for semitonesperoctave_ of 12 + while (increment > (scaleLength - 1)) + { + // increment = increment - 12 for semitonesperoctave_ of 12 + increment = increment - scaleLength; + if (octmod < octaverange_) + { + ++octmod; + } + } + } else { + + while (increment < 0) + { + // increment = increment + 12 for semitonesperoctave_ of 12 + increment = increment + scaleLength; + if (octmod > (octaverange_ * -1)) + { + --octmod; + } + } + + } + + int octincrement; + + // octave incremnet + // int octincrement = octmod * 12 for semitonesperoctave_ of 12 + if (scalewithoctave_) + { + octincrement = octmod * scaleLengthSub; + } + else + { + octincrement = octmod * scaleLength; + } + + // that's a good bingo, return increment frequency + if (scale[increment]) { + LimitScalePlayback(increment); + // increment = 0 will return 1 + return powf(2.0f, (octincrement + increment) / semitonesperoctave_) * basefrequency_; + } + + // flip increment if less than zero + if (increment < 0) { + // increment = increment + 12 for semitonesperoctave_ of 12 + increment = increment + scaleLength; + } + + // find lower match + int subincrement = increment; + + while (!scale[subincrement]) + { + if (subincrement > 0) + { + --subincrement; + } + else + { + // subincrement = 11 for semitonesperoctave_ of 12, done for clarity + subincrement = scaleLengthSub; + } + } + + // superincrement = 0 will return 1 + float subpitch = powf(2.0f, (octincrement + subincrement) / semitonesperoctave_) * basefrequency_; + + float subdifference = f - subpitch; + + if (subdifference < 0) + { + subdifference = subdifference * -1; + } + + // find upper + int superincrement = increment; + + while (!scale[superincrement]) + { + // if (superincrement < 11) for semitonesperoctave_ of 12 + if (superincrement < scaleLengthSub) + { + ++superincrement; + } + else + { + superincrement = 0; + } + } + + // superincrement = 0 will return 1 + float superpitch = powf(2.0f, (octincrement + superincrement) / semitonesperoctave_) * basefrequency_; + + // this will be a negative number if we are below the basefrequency + float superdifference = f - superpitch; + + if (superdifference < 0) + { + superdifference = superdifference * -1; + } + + if (subdifference < superdifference) { + // does a return powf(2.0f, (octincrement + subincrement) / 12.0f) * basefrequency; + LimitScalePlayback(subincrement); + return subpitch; + } else { + // does a return powf(2.0f, (octincrement + superincrement) / 12.0f) * basefrequency; + LimitScalePlayback(superincrement); + return superpitch; + } + + } + template + void UpdateScale(bool (&newscale)[N]) + { + // size of scale + scaleSize = sizeof(newscale); + + // clear previous scale + scale.clear(); + scaleReference.clear(); + + scaleNoteCounter = 0; + + // does what a for loop scale.push_back would do, but we need more + // scale.insert(scale.begin(), newscale, newscale + sizeof(newscale)); + for (int x = 0; x < scaleSize; ++x) + { + scale.push_back(newscale[x]); + scaleReference.push_back(newscale[x]); + if (newscale[x]) + { + ++scaleNoteCounter; + } + } + + scaleNoteCounterReference = scaleNoteCounter; + + // could add a check to see if the last element is an octave of the first? + + } + void UpdateScale(vector newscale){ + // size of scale + scaleSize = newscale.size(); + + // clear previous scale + scale.clear(); + scaleReference.clear(); + + scaleNoteCounter = 0; + + // does what a for loop scale.push_back would do, but we need more + // scale.insert(scale.begin(), newscale, newscale + sizeof(newscale)); + for (int x = 0; x < scaleSize; ++x) + { + scale.push_back(newscale[x]); + scaleReference.push_back(newscale[x]); + if (newscale[x]) + { + ++scaleNoteCounter; + } + } + + scaleNoteCounterReference = scaleNoteCounter; + } + void LimitScalePlayback(int current_increment) + { + if (uniquenotes_) + { + // record that a note has been used + scale.at(current_increment) = 0; + --scaleNoteCounter; + + if (scaleNoteCounter < 1) + { + // reset scaleNoteCounter + scaleNoteCounter = scaleNoteCounterReference; + + // reset + scale.clear(); + bool current_value = 0; + + for (int x = 0; x < scaleSize; ++x) + { + current_value = scaleReference[x]; + + // prevent same to note + if (x == current_increment) + { + current_value = 0; + // update scaleNoteCounter for missing current_value + --scaleNoteCounter; + } + + // reset + scale.push_back(current_value); + } + + } + } + } + // basefrequency_ + inline void SetBaseFrequency(float basefrequency) { basefrequency_ = basefrequency; } + inline float GetBaseFrequency() { return basefrequency_; } + // semitonesperoctave_ + inline void SetSemitonesPerOctave(float semitonesperoctave) { semitonesperoctave_ = semitonesperoctave; } + inline float GetSemitonesPerOctave() { return semitonesperoctave_; } + // uniquenotes_ + inline void OnUniqueNotes() { uniquenotes_ = 1; } + inline void OffUniqueNotes() { uniquenotes_ = 0; } + // octaverange_ + inline void SetOctaveRange(int octaverange) { octaverange_ = octaverange; } + inline int GetOctaveRange() { return octaverange_; } + // octavemodifier_ + inline void SetOctaveModifier(int octavemodifier) { octavemodifier_ = octavemodifier; } + inline int GetOctaveModifier() { return octavemodifier_; } + // scalewithoctave_ + inline void OnScaleEndsWithOctave() { scalewithoctave_ = 1; } + inline void OffScaleEndsWithOctave() { scalewithoctave_ = 0; } + private: + // set within UpdateScale, should these be accessible or modify-able outside class? + std::vector scale; + std::vector scaleReference; + int scaleSize; + int scaleNoteCounter; + int scaleNoteCounterReference; + // Set and Get methods for the following + float basefrequency_; + float semitonesperoctave_; + bool uniquenotes_; + int octaverange_; + int octavemodifier_; + bool scalewithoctave_; +}; + +class Quantizer : public PatchObject { + +public: + + Quantizer(); + + void newObject() override; + void setupObjectContent(shared_ptr &mainWindow) override; + void updateObjectContent(map> &patchObjects) override; + + void drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer) override; + void drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ) override; + void drawObjectNodeConfig() override; + + void removeObjectContent(bool removeFileFromData=false) override; + + void updateScale(string scalename); + + bool loaded; + + + ScaleQuantizer quant; + vector quantScale; + + vector scalesOptions; + int selectedScale; + int octave; + + + ImU32 Black = IM_COL32(0,0,0,255); + ImU32 Gray = IM_COL32(80,80,80,255); + ImU32 Yellow = IM_COL32(190,134,60,255); + +protected: + + +private: + + OBJECT_FACTORY_PROPS + +}; + +#endif From 7dd439a4d7b5083d760766c47fb0c72e7ce619ce Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sat, 25 Jan 2025 12:39:41 +0100 Subject: [PATCH 22/35] updated README --- README.md | 94 +++++++++++++++---------------------------------------- 1 file changed, 25 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index f3e51bc4..dca646fd 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Table of Contents * [INSTALLING](#installing) * [USAGE](#usage) * [CONTRIBUTING](#contributing) + * [COLLECTIONS](#collections) * [OBJECTS LIST](#objects_list) * [LICENSE](#license) * [CREDITS](#credits) @@ -135,55 +136,8 @@ git clone https://github.com/d3cod3/ofxVisualProgramming # USAGE -In ofApp.h include the ofxVisualProgramming addon: +Check [Mosaic](https://github.com/d3cod3/Mosaic) project to look at a ofxVisualProgramming addon usage and implementation -```c - -#include "ofMain.h" - -#include "ofxVisualProgramming.h" - -class ofApp : public ofBaseApp{ - -public: - void setup(); - void update(); - void draw(); - // .... - // .... - - ofxVisualProgramming *visualProgramming; /**/ - -}; - -``` - -then in ofApp.cpp: - -```c - -#include "ofApp.h" - -//-------------------------------------------------------------- -void ofApp::setup(){ - ofSetWindowTitle("ofxVisualProgramming Example"); - - visualProgramming = new ofxVisualProgramming(); - visualProgramming->setup(); -} - -//-------------------------------------------------------------- -void ofApp::update(){ - visualProgramming->update(); -} - -//-------------------------------------------------------------- -void ofApp::draw(){ - ofBackground(20); - visualProgramming->draw(); -} - -``` # CONTRIBUTING @@ -191,6 +145,11 @@ Contributing to the project adding new objects is relatively easy, as ofxVisualP You can find the repo of the plugin template here: [ofxMosaicPlugin](https://github.com/d3cod3/ofxMosaicPlugin), with some generic objects templates and more detailed info in the readme. +# COLLECTIONS + +A list of contributed collections of new objects + +- [ofxVPObjectsDaan](https://github.com/Daandelange/ofxVPObjectsDaan) by [@Daandelange](https://github.com/Daandelange) # OBJECTS LIST @@ -198,20 +157,10 @@ Audio Analysis | Ready ---------- | ---------- audio analyzer | X | bpm extractor | X | -centroid extractor | X | -dissonance extractor | X | fft extractor | X | -hfc extractor | X | -hpcp extractor | X | -inharmonicity extractor | X | mel bands extractor | X | -mfcc extractor | X | -onset extractor | X | pitch extractor | X | -power extractor | X | rms extractor | X | -rolloff extractor | X | -tristimulus extractor | X | Communications | Ready ---------- | ---------- @@ -229,7 +178,6 @@ osc sender | X | Computer Vision | Ready ---------- | ---------- background subtraction | X | -chroma key | X | color tracking | X | contour tracking | X | haar tracking | X | @@ -241,10 +189,13 @@ Data | Ready bang multiplexer | X | bang to float | X | color palette | X | +data to file | X | data to texture | X | file to data | X | float multiplexer | X | floats to vector | X | +receiver | X | +sender | X | texture to data | X | vector at | X | vector concat | X | @@ -259,6 +210,9 @@ bang | X | comment | X | data viewer | X | message | X | +multislider | X | +multitoggle | X | +piano keyboard | X | player controls | X | signal viewer | X | slider | X | @@ -286,10 +240,10 @@ Math | Ready ---------- | ---------- 1D noise | X | clamp | X | -constant | X | cosine generator | X | map | X | metronome | X | +number | X | operator | X | simple random | X | sine generator | X | @@ -300,8 +254,7 @@ Scripting | Ready bash script | X | glsl shader | X | lua script | X | -python script | X | -scheme script | | +scheme live coding | X | Sound | Ready @@ -319,6 +272,7 @@ data oscillator | X | decimator | X | delay | X | dimension chorus | X | +frequency to note | X | high pass | X | kick | X | lfo | X | @@ -327,13 +281,15 @@ mixer | X | note to frequency | X | oscillator | X | panner | X | -parametric EQ | | X +parametric EQ | X | pd patch | X | +polyphonic oscillator | X | quad panner | X | -quantizer | | X +quantizer | X | resonant filter | X | reverb | X | sample and hold | | X +sample player | X | saturator | | X sequencer | X | sidechain compressor | X | @@ -349,20 +305,20 @@ image loader | X | kinect grabber | X | pixels to texture | X | texture crop | X | +texture gate | X | texture information | X | texture mixer | X | texture to pixels | X | texture transform | X | to grayscale texture | X | -syphon sender | X | -syphon receiver | X | +syphon sender ( osx only ) | X | +syphon receiver ( osx only ) | X | video exporter | X | video feedback | X | -video gate | X | video grabber | X | video player | X | -video receiver | X | -video sender | X | +video receiver ( osx only ) | X | +video sender ( osx only ) | X | video streaming | X | video timedelay | X | From e63b785cb50fb074a00d015dad9af5d3084dbe24 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sun, 26 Jan 2025 08:24:00 +0100 Subject: [PATCH 23/35] added code reference --- src/utils.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils.h b/src/utils.h index a1da9b22..62556e34 100644 --- a/src/utils.h +++ b/src/utils.h @@ -58,6 +58,9 @@ // this macro is used to silent unused variables warnings on virtual functions template void unusedArgs(const Ts&...) {} +// --------------------------------------------- +// ofxVP_CAST_PIN_PTR template by @Daandelange + // Normal cast for almost any type template inline TYPE* ofxVP_CAST_PIN_PTR(void*& _pinData){ @@ -77,6 +80,7 @@ inline float* ofxVP_CAST_PIN_PTR(void*& _pinData){ return reinterpret_cast(&_pinData); #endif }; +// --------------------------------------------- //-------------------------------------------------------------- From 723868b32d9c017d2e1cc016ba808c647396934e Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sun, 26 Jan 2025 08:28:13 +0100 Subject: [PATCH 24/35] fixed debug vars --- src/ofxVisualProgramming.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ofxVisualProgramming.cpp b/src/ofxVisualProgramming.cpp index 726ee629..932b1de0 100755 --- a/src/ofxVisualProgramming.cpp +++ b/src/ofxVisualProgramming.cpp @@ -1586,7 +1586,7 @@ bool ofxVisualProgramming::connect(int fromID, int fromOutlet, int toID,int toIn checkSpecialConnection(fromID,toID,linkType); -#ifdef NDEBUG +#ifdef MOSAIC_DEBUG std::cout << "Connect from " << patchObjects[fromID]->getName() << " to " << patchObjects[toID]->getName() << std::endl; #endif @@ -1716,12 +1716,12 @@ void ofxVisualProgramming::newTempPatchFromFile(string patchFile){ // remove previous data content ofDirectory oldData; oldData.listDir(ofToDataPath("temp/data/",true)); -#ifdef NDEBUG +#ifdef MOSAIC_DEBUG std::cout << "Removing content from directory: " << oldData.getAbsolutePath() << std::endl; #endif for(size_t i=0;igetName() << std::endl; #endif @@ -2218,7 +2218,7 @@ void ofxVisualProgramming::loadPatch(string patchFile){ //-------------------------------------------------------------- void ofxVisualProgramming::loadPatchSharedContextObjects(){ -#ifdef NDEBUG +#ifdef MOSAIC_DEBUG std::cout << "Loading GL sharing context objects" << std::endl; #endif @@ -2263,7 +2263,7 @@ void ofxVisualProgramming::loadPatchSharedContextObjects(){ actualObjectID = tempObj->getId(); lastAddedObjectID = tempObj->getId(); nodeCanvas.addNodeToMap(tempObj->getId(),tempObj->getName()); -#ifdef NDEBUG +#ifdef MOSAIC_DEBUG std::cout << "Loading "<< tempObj->getName() << std::endl; #endif From 558f9bd6cde25eefda67b8601a4d45a5781256a8 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Sun, 26 Jan 2025 08:39:46 +0100 Subject: [PATCH 25/35] fixed debug vars --- src/ofxVisualProgramming.cpp | 34 +++++++++++++++++----------------- src/ofxVisualProgramming.h | 2 -- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/ofxVisualProgramming.cpp b/src/ofxVisualProgramming.cpp index 932b1de0..6b1b7a97 100755 --- a/src/ofxVisualProgramming.cpp +++ b/src/ofxVisualProgramming.cpp @@ -355,13 +355,13 @@ void ofxVisualProgramming::draw(){ ofPushMatrix(); // DEBUG - if(OFXVP_DEBUG){ - ofSetColor(0,255,255,236); - ofNoFill(); - ofDrawRectangle( canvasViewport.x, canvasViewport.y, canvasViewport.width, canvasViewport.height); - ofFill(); - ofDrawCircle(ofGetMouseX(), ofGetMouseY(), 6); - } +#ifdef OFXVP_DEBUG + ofSetColor(0,255,255,236); + ofNoFill(); + ofDrawRectangle( canvasViewport.x, canvasViewport.y, canvasViewport.width, canvasViewport.height); + ofFill(); + ofDrawCircle(ofGetMouseX(), ofGetMouseY(), 6); +#endif ofEnableAlphaBlending(); ofSetCurveResolution(50); @@ -373,9 +373,9 @@ void ofxVisualProgramming::draw(){ ofxVPGui->begin(); // DEBUG - if(OFXVP_DEBUG){ - ImGui::ShowMetricsWindow(); - } +#ifdef OFXVP_DEBUG + ImGui::ShowMetricsWindow(); +#endif // Try to begin ImGui Canvas. // Should always return true, except if window is minimised or somehow not rendered. @@ -1586,7 +1586,7 @@ bool ofxVisualProgramming::connect(int fromID, int fromOutlet, int toID,int toIn checkSpecialConnection(fromID,toID,linkType); -#ifdef MOSAIC_DEBUG +#ifdef OFXVP_DEBUG std::cout << "Connect from " << patchObjects[fromID]->getName() << " to " << patchObjects[toID]->getName() << std::endl; #endif @@ -1716,12 +1716,12 @@ void ofxVisualProgramming::newTempPatchFromFile(string patchFile){ // remove previous data content ofDirectory oldData; oldData.listDir(ofToDataPath("temp/data/",true)); -#ifdef MOSAIC_DEBUG +#ifdef OFXVP_DEBUG std::cout << "Removing content from directory: " << oldData.getAbsolutePath() << std::endl; #endif for(size_t i=0;igetName() << std::endl; #endif @@ -2218,7 +2218,7 @@ void ofxVisualProgramming::loadPatch(string patchFile){ //-------------------------------------------------------------- void ofxVisualProgramming::loadPatchSharedContextObjects(){ -#ifdef MOSAIC_DEBUG +#ifdef OFXVP_DEBUG std::cout << "Loading GL sharing context objects" << std::endl; #endif @@ -2263,7 +2263,7 @@ void ofxVisualProgramming::loadPatchSharedContextObjects(){ actualObjectID = tempObj->getId(); lastAddedObjectID = tempObj->getId(); nodeCanvas.addNodeToMap(tempObj->getId(),tempObj->getName()); -#ifdef MOSAIC_DEBUG +#ifdef OFXVP_DEBUG std::cout << "Loading "<< tempObj->getName() << std::endl; #endif diff --git a/src/ofxVisualProgramming.h b/src/ofxVisualProgramming.h index 12b6f78a..278fdd12 100755 --- a/src/ofxVisualProgramming.h +++ b/src/ofxVisualProgramming.h @@ -47,8 +47,6 @@ #include "PatchObject.h" -#define OFXVP_DEBUG 0 - struct SubpatchConnection{ int objID; string name; From 873849e70770918236323581668c5be40ec4bec2 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Tue, 28 Jan 2025 09:57:00 +0100 Subject: [PATCH 26/35] adjustments on parametric EQ object --- src/objects/sound/pdspParametricEQ.cpp | 128 +++++++++++++------------ src/objects/sound/pdspParametricEQ.h | 11 ++- 2 files changed, 71 insertions(+), 68 deletions(-) diff --git a/src/objects/sound/pdspParametricEQ.cpp b/src/objects/sound/pdspParametricEQ.cpp index 30349fa9..5d751239 100755 --- a/src/objects/sound/pdspParametricEQ.cpp +++ b/src/objects/sound/pdspParametricEQ.cpp @@ -34,30 +34,6 @@ #include "pdspParametricEQ.h" -//-------------------------------------------------------------- -static inline float lowShelfFn(float x, float amplitude, float center, float width){ - float base = (x - center) / width; // divide top by bottom - base *= base * -.5; // square top and bottom, multiply by -1/2 - base = exp(base); // take pow(e, base) - if(x < center){ - return amplitude; - }else{ - return amplitude * base; - } -} - -//-------------------------------------------------------------- -static inline float hiShelfFn(float x, float amplitude, float center, float width){ - float base = (x - center) / width; // divide top by bottom - base *= base * -.5; // square top and bottom, multiply by -1/2 - base = exp(base); // take pow(e, base) - if(x > center){ - return amplitude; - }else{ - return amplitude * base; - } -} - //-------------------------------------------------------------- pdspParametricEQ::pdspParametricEQ() : PatchObject("parametric EQ"){ @@ -97,7 +73,7 @@ pdspParametricEQ::pdspParametricEQ() : PatchObject("parametric EQ"){ //-------------------------------------------------------------- void pdspParametricEQ::newObject(){ - PatchObject::setName( "parametric EQ" ); + PatchObject::setName( this->objectName ); this->addInlet(VP_LINK_AUDIO,"signal"); @@ -105,21 +81,21 @@ void pdspParametricEQ::newObject(){ this->addOutlet(VP_LINK_ARRAY,"spectrum data"); // LF, LMF, HMF, HF - this->setCustomVar(float_l1freq,"LF_FREQ"); - this->setCustomVar(float_l1Q,"LF_Q"); - this->setCustomVar(float_l1gain,"LF_GAIN"); + this->setCustomVar(static_cast(float_l1freq),"LF_FREQ"); + this->setCustomVar(static_cast(float_l1Q),"LF_Q"); + this->setCustomVar(static_cast(float_l1gain),"LF_GAIN"); - this->setCustomVar(float_m1freq,"LMF_FREQ"); - this->setCustomVar(float_m1Q,"LMF_Q"); - this->setCustomVar(float_m1gain,"LMF_GAIN"); + this->setCustomVar(static_cast(float_m1freq),"LMF_FREQ"); + this->setCustomVar(static_cast(float_m1Q),"LMF_Q"); + this->setCustomVar(static_cast(float_m1gain),"LMF_GAIN"); - this->setCustomVar(float_m2freq,"HMF_FREQ"); - this->setCustomVar(float_m2Q,"HMF_Q"); - this->setCustomVar(float_m2gain,"HMF_GAIN"); + this->setCustomVar(static_cast(float_m2freq),"HMF_FREQ"); + this->setCustomVar(static_cast(float_m2Q),"HMF_Q"); + this->setCustomVar(static_cast(float_m2gain),"HMF_GAIN"); - this->setCustomVar(float_h1freq,"HF_FREQ"); - this->setCustomVar(float_h1Q,"HF_Q"); - this->setCustomVar(float_h1gain,"HF_GAIN"); + this->setCustomVar(static_cast(float_h1freq),"HF_FREQ"); + this->setCustomVar(static_cast(float_h1Q),"HF_Q"); + this->setCustomVar(static_cast(float_h1gain),"HF_GAIN"); } //-------------------------------------------------------------- @@ -177,8 +153,8 @@ void pdspParametricEQ::setupAudioOutObjectContent(pdsp::Engine &engine){ h1_gain.set(float_h1gain); h1_gain.enableSmoothing(50.0f); - this->pdspIn[0] >> l1 >> m1 >> m2 >> h1 >> this->pdspOut[0]; // - this->pdspIn[0] >> l1 >> m1 >> m2 >> h1 >> scope >> engine.blackhole(); + this->pdspIn[0] >> l1 >> m1 >> m2 >> h1 >> this->pdspOut[0]; + h1 >> scope >> engine.blackhole(); } @@ -186,36 +162,43 @@ void pdspParametricEQ::setupAudioOutObjectContent(pdsp::Engine &engine){ void pdspParametricEQ::updateObjectContent(map> &patchObjects){ unusedArgs(patchObjects); - l1_freq.set(float_l1freq); - l1_Q.set(float_l1Q); - l1_gain.set(float_l1gain); - - m1_freq.set(float_m1freq); - m1_Q.set(float_m1Q); - m1_gain.set(float_m1gain); - - m2_freq.set(float_m2freq); - m2_Q.set(float_m2Q); - m2_gain.set(float_m2gain); - - h1_freq.set(float_h1freq); - h1_Q.set(float_h1Q); - h1_gain.set(float_h1gain); - - if(!loaded){ loaded = true; - float_l1freq=this->getCustomVar("LF_FREQ"), float_l1Q=this->getCustomVar("LF_Q"), float_l1gain=this->getCustomVar("LF_GAIN"); - float_m1freq=this->getCustomVar("LMF_FREQ"), float_m1Q=this->getCustomVar("LMF_Q"), float_m1gain=this->getCustomVar("LMF_GAIN"); - float_m2freq=this->getCustomVar("HMF_FREQ"), float_m2Q=this->getCustomVar("HMF_Q"), float_m2gain=this->getCustomVar("HMF_GAIN"); - float_h1freq=this->getCustomVar("HF_FREQ"), float_h1Q=this->getCustomVar("HF_Q"), float_h1gain=this->getCustomVar("HF_GAIN"); + + float_l1freq = static_cast(this->getCustomVar("LF_FREQ")); + float_l1Q = static_cast(this->getCustomVar("LF_Q")); + float_l1gain = static_cast(this->getCustomVar("LF_GAIN")); + float_m1freq = static_cast(this->getCustomVar("LMF_FREQ")); + float_m1Q = static_cast(this->getCustomVar("LMF_Q")); + float_m1gain = static_cast(this->getCustomVar("LMF_GAIN")); + float_m2freq = static_cast(this->getCustomVar("HMF_FREQ")); + float_m2Q = static_cast(this->getCustomVar("HMF_Q")); + float_m2gain = static_cast(this->getCustomVar("HMF_GAIN")); + float_h1freq = static_cast(this->getCustomVar("HF_FREQ")); + float_h1Q = static_cast(this->getCustomVar("HF_Q")); + float_h1gain = static_cast(this->getCustomVar("HF_GAIN")); + + l1_freq.set(float_l1freq); + l1_Q.set(float_l1Q); + l1_gain.set(float_l1gain); + + m1_freq.set(float_m1freq); + m1_Q.set(float_m1Q); + m1_gain.set(float_m1gain); + + m2_freq.set(float_m2freq); + m2_Q.set(float_m2Q); + m2_gain.set(float_m2gain); + + h1_freq.set(float_h1freq); + h1_Q.set(float_h1Q); + h1_gain.set(float_h1gain); } } //-------------------------------------------------------------- void pdspParametricEQ::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ unusedArgs(font,glRenderer); - } //-------------------------------------------------------------- @@ -259,56 +242,68 @@ void pdspParametricEQ::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ // LF ImGui::Dummy(ImVec2(-1,14*scaleFactor)); if(ImGuiKnobs::Knob("LF Freq", &float_l1freq, 20.0f, 500.0f, 1.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + l1_freq.set(float_l1freq); this->setCustomVar(float_l1freq,"LF_FREQ"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("LF Q", &float_l1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + l1_Q.set(float_l1Q); this->setCustomVar(float_l1Q,"LF_Q"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("LF Gain", &float_l1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + l1_gain.set(float_l1gain); this->setCustomVar(float_l1gain,"LF_GAIN"); } // LMF ImGui::SameLine(); if(ImGuiKnobs::Knob("LMF Freq", &float_m1freq, 30.0f, 2000.0f, 10.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + m1_freq.set(float_m1freq); this->setCustomVar(float_m1freq,"LMF_FREQ"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("LMF Q", &float_m1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + m1_Q.set(float_m1Q); this->setCustomVar(float_m1Q,"LMF_Q"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("LMF Gain", &float_m1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + m1_gain.set(float_m1gain); this->setCustomVar(float_m1gain,"LMF_GAIN"); } // HMF ImGui::Dummy(ImVec2(-1,14*scaleFactor)); if(ImGuiKnobs::Knob("HMF Freq", &float_m2freq, 500.0f, 5000.0f, 10.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + m2_freq.set(float_m2freq); this->setCustomVar(float_m2freq,"HMF_FREQ"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("HMF Q", &float_m2Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + m2_Q.set(float_m2Q); this->setCustomVar(float_m2Q,"HMF_Q"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("HMF Gain", &float_m2gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + m2_gain.set(float_m2gain); this->setCustomVar(float_m2gain,"HMF_GAIN"); } // HF ImGui::SameLine(); if(ImGuiKnobs::Knob("HF Freq", &float_h1freq, 1000.0f, 20000.0f, 10.0f, "%.2fHz", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + h1_freq.set(float_h1freq); this->setCustomVar(float_h1freq,"HF_FREQ"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("HF Q", &float_h1Q, 0.3f, 20.0f, 0.1f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + h1_Q.set(float_h1Q); this->setCustomVar(float_h1Q,"HF_Q"); } ImGui::SameLine(); if(ImGuiKnobs::Knob("HF Gain", &float_h1gain, -20.0f, 20.0f, 0.1f, "%.2fdB", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + h1_gain.set(float_h1gain); this->setCustomVar(float_h1gain,"HF_GAIN"); } @@ -321,7 +316,7 @@ void pdspParametricEQ::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ //-------------------------------------------------------------- void pdspParametricEQ::drawObjectNodeConfig(){ ImGuiEx::ObjectInfo( - "Parametric Equalizer.", + "Multiband Parametric Equalizer.", "https://mosaic.d3cod3.org/reference.php?r=parametric-eq", scaleFactor); } @@ -369,10 +364,17 @@ void pdspParametricEQ::loadAudioSettings(){ m2Filter->push_back(0.0f); h1Filter->push_back(0.0f); parametricFilter->push_back(0.0f); + + spectrum[i] = 0.0f; } } } +//-------------------------------------------------------------- +void pdspParametricEQ::audioInObject(ofSoundBuffer &inputBuffer){ + unusedArgs(inputBuffer); +} + //-------------------------------------------------------------- void pdspParametricEQ::audioOutObject(ofSoundBuffer &outputBuffer){ unusedArgs(outputBuffer); @@ -387,7 +389,7 @@ void pdspParametricEQ::audioOutObject(ofSoundBuffer &outputBuffer){ // SPECTRUM for(size_t i = 0; i < fft->getBinSize(); i++){ - size_t pos = static_cast(floor((std::log(i+20 / 20.f) / std::log(512.f))*fft->getBinSize())); + size_t pos = static_cast(floor((std::log(i+20 / 20.f) / std::log(1024.f))*fft->getBinSize())); if(pos < fft->getBinSize()){ static_cast *>(_outletParams[1])->at(pos) = spectrum[i]; } diff --git a/src/objects/sound/pdspParametricEQ.h b/src/objects/sound/pdspParametricEQ.h index 1e51eb0b..141c60bc 100755 --- a/src/objects/sound/pdspParametricEQ.h +++ b/src/objects/sound/pdspParametricEQ.h @@ -58,12 +58,18 @@ class pdspParametricEQ : public PatchObject{ void removeObjectContent(bool removeFileFromData=false) override; + void audioInObject(ofSoundBuffer &inputBuffer) override; void audioOutObject(ofSoundBuffer &outputBuffer) override; void loadAudioSettings(); + ofxFft *fft; + float *spectrum; + + pdsp::Scope scope; + pdsp::LowShelfEQ l1; pdsp::PeakEQ m1, m2; pdsp::HighShelfEQ h1; @@ -73,11 +79,6 @@ class pdspParametricEQ : public PatchObject{ pdsp::ValueControl m2_freq, m2_Q, m2_gain; pdsp::ValueControl h1_freq, h1_Q, h1_gain; - pdsp::Scope scope; - - ofxFft *fft; - float *spectrum; - float float_l1freq, float_l1Q, float_l1gain; float float_m1freq, float_m1Q, float_m1gain; float float_m2freq, float_m2Q, float_m2gain; From 93800041e94f93883595654089c8eed282849058 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Wed, 29 Jan 2025 19:23:12 +0100 Subject: [PATCH 27/35] added simple imgui toggle button --- src/core/imgui_controls.cpp | 21 +++++++++++++++++++++ src/core/imgui_controls.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/core/imgui_controls.cpp b/src/core/imgui_controls.cpp index c97322bd..d5126b27 100644 --- a/src/core/imgui_controls.cpp +++ b/src/core/imgui_controls.cpp @@ -446,4 +446,25 @@ SmartButtonState BangButton(const char* label, ImVec4& color, ImVec2 size) { return state; } +void ToggleButton(const char* str_id, bool* v) +{ + ImVec4* colors = ImGui::GetStyle().Colors; + ImVec2 p = ImGui::GetCursorScreenPos(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + float height = ImGui::GetFrameHeight()/3*2; + float width = height * 1.55f; + float radius = height * 0.50f; + + ImGui::InvisibleButton(str_id, ImVec2(width, height)); + if (ImGui::IsItemClicked()) *v = !*v; + + if (ImGui::IsItemHovered()) + draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), ImGui::GetColorU32(*v ? colors[ImGuiCol_ButtonActive] : ImVec4(0.78f, 0.78f, 0.78f, 1.0f)), height * 0.5f); + else + draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), ImGui::GetColorU32(*v ? colors[ImGuiCol_Button] : ImVec4(0.85f, 0.85f, 0.85f, 1.0f)), height * 0.50f); + + draw_list->AddCircleFilled(ImVec2(p.x + radius + (*v ? 1 : 0) * (width - radius * 2.0f), p.y + radius), radius - 1.5f, IM_COL32(255, 255, 255, 255)); +} + } diff --git a/src/core/imgui_controls.h b/src/core/imgui_controls.h index e869603d..dbc33d12 100644 --- a/src/core/imgui_controls.h +++ b/src/core/imgui_controls.h @@ -32,4 +32,6 @@ SmartButtonState SmartButton(const char* label, ImVec2 size = {0, 0}); SmartButtonState BangButton(const char* label, ImVec4& color, ImVec2 size = {0, 0}); +void ToggleButton(const char* str_id, bool* v); + } From ad627c354486e9ba54dd866b04b34fc1a3d83c7a Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Wed, 29 Jan 2025 19:23:51 +0100 Subject: [PATCH 28/35] added 8 step address sequencer object --- src/objects/sound/pdspAddressSequencer.cpp | 364 +++++++++++++++++++++ src/objects/sound/pdspAddressSequencer.h | 87 +++++ 2 files changed, 451 insertions(+) create mode 100755 src/objects/sound/pdspAddressSequencer.cpp create mode 100755 src/objects/sound/pdspAddressSequencer.h diff --git a/src/objects/sound/pdspAddressSequencer.cpp b/src/objects/sound/pdspAddressSequencer.cpp new file mode 100755 index 00000000..6f77b478 --- /dev/null +++ b/src/objects/sound/pdspAddressSequencer.cpp @@ -0,0 +1,364 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#include "pdspAddressSequencer.h" + +//-------------------------------------------------------------- +pdspAddressSequencer::pdspAddressSequencer() : PatchObject("address sequencer"){ + + this->numInlets = 4; + this->numOutlets = 2; + + _inletParams[0] = new vector(); // values + _inletParams[1] = new float(); // ratio + *(float *)&_inletParams[1] = 1.0f; + _inletParams[2] = new float(); // steps + *(float *)&_inletParams[2] = 8.0f; + _inletParams[3] = new float(); // sync + *(float *)&_inletParams[3] = 0.0f; + + _outletParams[0] = new float(); // bang + *(float *)&_outletParams[0] = 0.0f; + + _outletParams[1] = new float(); // value + *(float *)&_outletParams[1] = 0.0f; + + + this->initInletsState(); + + isAudioOUTObject = true; + isPDSPPatchableObject = true; + + loaded = false; + + meter_step = 0; + manualSteps = 8; + actualSteps = manualSteps; + + scaleMode = Scale_Mode_x1; + scaleMultiplier = 1.0f; + + rev = false; + + this->width *= 3.5f; + this->height *= 1.62f; + +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::newObject(){ + PatchObject::setName( this->objectName ); + + this->addInlet(VP_LINK_ARRAY,"values"); + this->addInlet(VP_LINK_NUMERIC,"ratio"); + this->addInlet(VP_LINK_NUMERIC,"steps"); + this->addInlet(VP_LINK_NUMERIC,"sync"); + + this->addOutlet(VP_LINK_NUMERIC,"bang"); + this->addOutlet(VP_LINK_NUMERIC,"value"); + + this->setCustomVar(static_cast(actualSteps),"MANUAL_STEPS"); + this->setCustomVar(static_cast(rev),"REVERSE"); + this->setCustomVar(static_cast(scaleMode),"SCALE_MODE"); + + for(size_t i=0;i<8;i++){ + this->setCustomVar(0.0f,"S_"+ofToString(i+1)); + } + +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::setupObjectContent(shared_ptr &mainWindow){ + unusedArgs(mainWindow); + + for(size_t i=0;i<8;i++){ + seqSteps[i] = 0.0f; + static_cast *>(_inletParams[0])->push_back(0.0f); + } + + scaleModesString.push_back("/4"); + scaleModesString.push_back("/3"); + scaleModesString.push_back("/2.5"); + scaleModesString.push_back("/2"); + scaleModesString.push_back("/1.5"); + scaleModesString.push_back("x1"); + scaleModesString.push_back("x1.5"); + scaleModesString.push_back("x2"); + scaleModesString.push_back("x2.5"); + scaleModesString.push_back("x3"); + scaleModesString.push_back("x4"); +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::setupAudioOutObjectContent(pdsp::Engine &engine){ + unusedArgs(engine); + + // ---- this code runs in the audio thread ---- + + seq.timing = 48; + + // + seq.code = [&]() noexcept { + // actual sequencer step + if(rev){ + if(seq.frame()%static_cast(floor(6.0f/scaleMultiplier))==0){ + if(meter_step > 0){ + meter_step--; + }else{ + meter_step = actualSteps.load()-1; + } + } + //meter_step = 7 - (seq.frame()%actualSteps.load()); + }else{ + if(seq.frame()%static_cast(floor(6.0f/scaleMultiplier))==0){ + if(meter_step < actualSteps.load()-1){ + meter_step++; + }else{ + meter_step = 0; + } + } + //meter_step = static_cast(floor(seq.frame()*scaleMultiplier))%actualSteps.load(); + } + + + // SEQ bangs + if(seqSteps[meter_step]>0.0f){ + *(float *)&_outletParams[0] = 1.0f; + }else{ + *(float *)&_outletParams[0] = 0.0f; + } + + // CTRLS values + *(float *)&_outletParams[1] = seqSteps[meter_step]; // value + + }; + +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::updateObjectContent(map> &patchObjects){ + unusedArgs(patchObjects); + + if(this->inletsConnected[1]){ // ratio + scaleMultiplier = *(float *)&_inletParams[1]; //ofClamp(*(float *)&_inletParams[1],0.25f,4.0f); + } + + if(this->inletsConnected[2]){ // steps + manualSteps = static_cast(floor(ofClamp(*(float *)&_inletParams[2],1,8))); + actualSteps = manualSteps; + } + + // SYNC + if(this->inletsConnected[3]){ + if(*(float *)&_inletParams[3] == 1.0f){ + if(rev){ + meter_step = actualSteps.load()-1; + }else{ + meter_step = 0; + } + + } + } + + if(!loaded){ + loaded = true; + manualSteps = static_cast(this->getCustomVar("MANUAL_STEPS")); + rev = static_cast(this->getCustomVar("REVERSE")); + scaleMode = static_cast(this->getCustomVar("SCALE_MODE")); + + actualSteps = manualSteps; + for(size_t i=0;i<8;i++){ + seqSteps[i] = this->getCustomVar("S_"+ofToString(i+1)); + } + } +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::updateAudioObjectContent(pdsp::Engine &engine){ + unusedArgs(engine); +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ + unusedArgs(font,glRenderer); + +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ + + if(_nodeCanvas.BeginNodeMenu()){ + ImGui::Separator(); + ImGui::Separator(); + ImGui::Separator(); + + if (ImGui::BeginMenu("CONFIG")) + { + + drawObjectNodeConfig(); this->configMenuWidth = ImGui::GetWindowWidth(); + + ImGui::EndMenu(); + } + _nodeCanvas.EndNodeMenu(); + } + + // Visualize (Object main view) + if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ + ImVec2 window_pos = ImGui::GetWindowPos(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + + char temp[32]; + + for(size_t i=0;i<8;i++){ + // gate leds + ImVec2 stepPos = ImVec2(window_pos.x - 10 + (window_size.x-(50*scaleFactor))/8 * (i+1),window_pos.y + (32*scaleFactor)); + if(i == static_cast(meter_step) && seqSteps[i] > 0.0f){ + _nodeCanvas.getNodeDrawList()->AddCircleFilled(stepPos, 5*scaleFactor, IM_COL32(255, 255, 120, 140), 40); + } + } + + ImGui::Dummy(ImVec2(-1,IMGUI_EX_NODE_CONTENT_PADDING*8*scaleFactor)); + for(size_t i=0;i<8;i++){ + sprintf_s(temp,"S %s",to_string(i+1).c_str()); + if(ImGuiKnobs::Knob(temp, &seqSteps[i], 0.0f, 1.0f, 0.001f, "%.2f", ImGuiKnobVariant_Wiper,ofMap(_nodeCanvas.GetCanvasScale(),CANVAS_MIN_SCALE,CANVAS_MAX_SCALE,MIN_KNOB_SCALE,MAX_KNOB_SCALE)*this->scaleFactor)){ + this->setCustomVar(seqSteps[i],"S_"+ofToString(i+1)); + } + if(i<7){ + ImGui::SameLine(); + } + } + + for(size_t i=0;i<8;i++){ + // step leds + ImVec2 stepPos = ImVec2(window_pos.x - 10 + (window_size.x-(50*scaleFactor))/8 * (i+1),window_pos.y + window_size.y - (20*scaleFactor)); + if(i == static_cast(meter_step)){ + _nodeCanvas.getNodeDrawList()->AddCircleFilled(stepPos, 6*scaleFactor, IM_COL32(182, 30, 41, 255), 40); + }else{ + _nodeCanvas.getNodeDrawList()->AddCircleFilled(stepPos, 5*scaleFactor, IM_COL32(50, 50, 50, 255), 40); + } + } + + _nodeCanvas.EndNodeContent(); + + } + +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::drawObjectNodeConfig(){ + ImGui::Spacing(); + if(ImGui::SliderInt("steps", &manualSteps, 1, 8)){ + actualSteps = manualSteps; + this->setCustomVar(static_cast(manualSteps),"MANUAL_STEPS"); + } + ImGui::Spacing(); + if(ImGui::BeginCombo("ratio", scaleModesString.at(scaleMode).c_str(),ImGuiComboFlags_HeightLargest)){ + for(unsigned int i=0; i < scaleModesString.size(); ++i){ + bool is_selected = (scaleMode == (int)i ); + if (ImGui::Selectable(scaleModesString.at(i).c_str(), is_selected)){ + scaleMode = i; + this->setCustomVar(static_cast(scaleMode),"SCALE_MODE"); + if(scaleMode == Scale_Mode_d4){ + scaleMultiplier = 1.0f/4.0f; + }else if(scaleMode == Scale_Mode_d3){ + scaleMultiplier = 1.0f/3.0f; + }else if(scaleMode == Scale_Mode_d2_5){ + scaleMultiplier = 1.0f/2.5f; + }else if(scaleMode == Scale_Mode_d2){ + scaleMultiplier = 1.0f/2.0f; + }else if(scaleMode == Scale_Mode_d1_5){ + scaleMultiplier = 1.0f/1.5f; + }else if(scaleMode == Scale_Mode_x1){ + scaleMultiplier = 1.0f; + }else if(scaleMode == Scale_Mode_x1_5){ + scaleMultiplier = 1.5f; + }else if(scaleMode == Scale_Mode_x2){ + scaleMultiplier = 2.0f; + }else if(scaleMode == Scale_Mode_x2_5){ + scaleMultiplier = 2.5f; + }else if(scaleMode == Scale_Mode_x3){ + scaleMultiplier = 3.0f; + }else if(scaleMode == Scale_Mode_x4){ + scaleMultiplier = 4.0f; + } + } + if (is_selected) ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Text("Fwd"); ImGui::SameLine(); ImGuiEx::ToggleButton("seq_direction",&rev); ImGui::SameLine(); ImGui::Text("Rev"); + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Spacing(); + if(ImGui::Button("Randomize",ImVec2(224*scaleFactor,26*scaleFactor))){ + for(size_t i=0;i<8;i++){ + seqSteps[i] = ofRandomuf(); + this->setCustomVar(seqSteps[i],"S_"+ofToString(i+1)); + } + } + ImGui::Spacing(); + + ImGuiEx::ObjectInfo( + "8 step address sequencer.", + "https://mosaic.d3cod3.org/reference.php?r=address-sequencer", scaleFactor); +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::removeObjectContent(bool removeFileFromData){ + unusedArgs(removeFileFromData); +} + +//-------------------------------------------------------------- +void pdspAddressSequencer::audioOutObject(ofSoundBuffer &outputBuffer){ + unusedArgs(outputBuffer); + + // S + if(this->inletsConnected[0] && !static_cast *>(_inletParams[0])->empty()){ + for(size_t i=0;i<8;i++){ + if(i < static_cast *>(_inletParams[0])->size()){ + seqSteps[i] = static_cast *>(_inletParams[0])->at(i); + } + } + } + + +} + +OBJECT_REGISTER( pdspAddressSequencer, "address sequencer", OFXVP_OBJECT_CAT_SOUND) + +#endif diff --git a/src/objects/sound/pdspAddressSequencer.h b/src/objects/sound/pdspAddressSequencer.h new file mode 100755 index 00000000..6b6b5330 --- /dev/null +++ b/src/objects/sound/pdspAddressSequencer.h @@ -0,0 +1,87 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#pragma once + +#include "PatchObject.h" + +#include "imgui_controls.h" +#include "imgui-knobs.h" + +enum Scale_Mode { Scale_Mode_d4, Scale_Mode_d3, Scale_Mode_d2_5, Scale_Mode_d2, Scale_Mode_d1_5, Scale_Mode_x1, Scale_Mode_x1_5, Scale_Mode_x2, Scale_Mode_x2_5, Scale_Mode_x3, Scale_Mode_x4 }; + +class pdspAddressSequencer : public PatchObject{ + +public: + + pdspAddressSequencer(); + + void newObject() override; + void setupObjectContent(shared_ptr &mainWindow) override; + void setupAudioOutObjectContent(pdsp::Engine &engine) override; + void updateObjectContent(map> &patchObjects) override; + void updateAudioObjectContent(pdsp::Engine &engine) override; + + void drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer) override; + void drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ) override; + void drawObjectNodeConfig() override; + + void removeObjectContent(bool removeFileFromData=false) override; + + void audioOutObject(ofSoundBuffer &outputBuffer) override; + + pdsp::Function seq; + std::atomic actualSteps; + std::atomic meter_step; + + + vector scaleModesString; + int scaleMode; + float scaleMultiplier; + int manualSteps; + float seqSteps[8]; + bool rev; + + bool loaded; + +protected: + + +private: + + OBJECT_FACTORY_PROPS + +}; + +#endif From 16ac7cda4fedc7c7b235a1ce2fdff68e6709afcb Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Wed, 29 Jan 2025 20:56:56 +0100 Subject: [PATCH 29/35] fixed sequencer object step counter and added sync inlet --- src/objects/sound/pdspSequencer.cpp | 34 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/objects/sound/pdspSequencer.cpp b/src/objects/sound/pdspSequencer.cpp index 9c6649be..33ab6820 100755 --- a/src/objects/sound/pdspSequencer.cpp +++ b/src/objects/sound/pdspSequencer.cpp @@ -40,7 +40,7 @@ const char* steps_names[Steps_COUNT] = { "1-16", "17-32", "33-48", "49-64" }; //-------------------------------------------------------------- pdspSequencer::pdspSequencer() : PatchObject("sequencer"){ - this->numInlets = 6; + this->numInlets = 7; this->numOutlets = 21; _inletParams[0] = new vector(); // S @@ -50,6 +50,8 @@ pdspSequencer::pdspSequencer() : PatchObject("sequencer"){ _inletParams[4] = new vector(); // D _inletParams[5] = new float(); // steps *(float *)&_inletParams[5] = 0.0f; + _inletParams[6] = new float(); // sync + *(float *)&_inletParams[6] = 0.0f; _outletParams[0] = new float(); // step *(float *)&_outletParams[0] = 0.0f; @@ -142,6 +144,7 @@ void pdspSequencer::newObject(){ this->addInlet(VP_LINK_ARRAY,"C"); this->addInlet(VP_LINK_ARRAY,"D"); this->addInlet(VP_LINK_NUMERIC,"steps"); + this->addInlet(VP_LINK_NUMERIC,"sync"); this->addOutlet(VP_LINK_NUMERIC,"s1"); this->addOutlet(VP_LINK_NUMERIC,"s2"); @@ -184,12 +187,22 @@ void pdspSequencer::newObject(){ void pdspSequencer::setupObjectContent(shared_ptr &mainWindow){ unusedArgs(mainWindow); + seq.timing = 64; + // ---- this code runs in the audio thread ---- seq.code = [&]() noexcept { // actual sequencer step - int step = seq.frame()%actualSteps.load(); + //int step = seq.frame()%actualSteps.load(); + + //meter_step = step; - meter_step = step; + if(seq.frame()%8==0){ + if(meter_step < actualSteps.load()-1){ + meter_step++; + }else{ + meter_step = 0; + } + } // CTRLS *(float *)&_outletParams[16] = seqSteps[meter_step]; // S @@ -253,7 +266,14 @@ void pdspSequencer::updateObjectContent(map> &patchO }else if(actualSteps > 48 && actualSteps <= 64){ maxChapter = 3; } - meter_step = seq.frame()%actualSteps.load(); + //meter_step = seq.frame()%actualSteps.load(); + } + + // SYNC + if(this->inletsConnected[6]){ + if(*(float *)&_inletParams[6] == 1.0f){ + meter_step = 0; + } } if(!loaded){ @@ -401,7 +421,7 @@ void pdspSequencer::drawObjectNodeConfig(){ if(ImGui::SliderInt("steps", &maxChapter, 0, Steps_COUNT - 1, steps_nums[maxChapter])){ actualSteps = CHAPTER_STEPS*(maxChapter+1); manualSteps = actualSteps; - meter_step = seq.frame()%actualSteps.load(); + //meter_step = seq.frame()%actualSteps.load(); this->setCustomVar(static_cast(maxChapter),"STEPS"); this->setCustomVar(static_cast(manualSteps),"MANUAL_STEPS"); } @@ -417,7 +437,7 @@ void pdspSequencer::drawObjectNodeConfig(){ }else if(actualSteps > 48 && actualSteps <= 64){ maxChapter = 3; } - meter_step = seq.frame()%actualSteps.load(); + //meter_step = seq.frame()%actualSteps.load(); this->setCustomVar(static_cast(manualSteps),"MANUAL_STEPS"); } ImGui::Spacing(); @@ -436,7 +456,7 @@ void pdspSequencer::removeObjectContent(bool removeFileFromData){ void pdspSequencer::audioOutObject(ofSoundBuffer &outputBuffer){ unusedArgs(outputBuffer); - seq.timing = actualSteps.load(); + //seq.timing = actualSteps.load(); // S if(this->inletsConnected[0] && !static_cast *>(_inletParams[0])->empty()){ From 037620098eacd8b9128b4a6afae583f3b4281464 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Thu, 30 Jan 2025 19:05:30 +0100 Subject: [PATCH 30/35] fixed set ratio on loading object --- src/objects/sound/pdspAddressSequencer.cpp | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/objects/sound/pdspAddressSequencer.cpp b/src/objects/sound/pdspAddressSequencer.cpp index 6f77b478..068f118b 100755 --- a/src/objects/sound/pdspAddressSequencer.cpp +++ b/src/objects/sound/pdspAddressSequencer.cpp @@ -195,7 +195,31 @@ void pdspAddressSequencer::updateObjectContent(map> loaded = true; manualSteps = static_cast(this->getCustomVar("MANUAL_STEPS")); rev = static_cast(this->getCustomVar("REVERSE")); + scaleMode = static_cast(this->getCustomVar("SCALE_MODE")); + if(scaleMode == Scale_Mode_d4){ + scaleMultiplier = 1.0f/4.0f; + }else if(scaleMode == Scale_Mode_d3){ + scaleMultiplier = 1.0f/3.0f; + }else if(scaleMode == Scale_Mode_d2_5){ + scaleMultiplier = 1.0f/2.5f; + }else if(scaleMode == Scale_Mode_d2){ + scaleMultiplier = 1.0f/2.0f; + }else if(scaleMode == Scale_Mode_d1_5){ + scaleMultiplier = 1.0f/1.5f; + }else if(scaleMode == Scale_Mode_x1){ + scaleMultiplier = 1.0f; + }else if(scaleMode == Scale_Mode_x1_5){ + scaleMultiplier = 1.5f; + }else if(scaleMode == Scale_Mode_x2){ + scaleMultiplier = 2.0f; + }else if(scaleMode == Scale_Mode_x2_5){ + scaleMultiplier = 2.5f; + }else if(scaleMode == Scale_Mode_x3){ + scaleMultiplier = 3.0f; + }else if(scaleMode == Scale_Mode_x4){ + scaleMultiplier = 4.0f; + } actualSteps = manualSteps; for(size_t i=0;i<8;i++){ From a157b5f8644de7939b1309371583cde68b0e324d Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Fri, 31 Jan 2025 00:51:30 +0100 Subject: [PATCH 31/35] removed unused addon --- addon_config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon_config.mk b/addon_config.mk index c9b51564..70dca82a 100644 --- a/addon_config.mk +++ b/addon_config.mk @@ -26,7 +26,7 @@ common: # or use += in several lines ADDON_DEPENDENCIES = ofxKinect ofxOpenCv ofxOsc ofxXmlSettings ADDON_DEPENDENCIES += ofxAudioFile ofxBTrack ofxCv ofxEasing ofxFFmpegRecorder ofxFft - ADDON_DEPENDENCIES += ofxGLEditor ofxJSON ofxImGui ofxLua ofxMidi ofxMtlMapping2D + ADDON_DEPENDENCIES += ofxGLEditor ofxImGui ofxLua ofxMidi ofxMtlMapping2D ADDON_DEPENDENCIES += ofxOpenDHT ofxPd ofxPDSP ofxScheme ofxTimeline ofxWarp # include search paths, this will be usually parsed from the file system From 6fa7821a967480a07582554d4c4a4f92dfe2fd73 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Fri, 31 Jan 2025 00:54:50 +0100 Subject: [PATCH 32/35] updated readme --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dca646fd..69ee0b22 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,6 @@ In order to build ofxVisualProgramming, you'll need this addons: #### [ofxFft](https://github.com/kylemcdonald/ofxFft) -#### [ofxJSON](https://github.com/jeffcrouse/ofxJSON) - #### [ofxImGui](https://github.com/d3cod3/ofxImGui) #### [ofxInfiniteCanvas](https://github.com/d3cod3/ofxInfiniteCanvas) @@ -118,7 +116,6 @@ git clone https://github.com/kylemcdonald/ofxCv git clone https://github.com/arturoc/ofxEasing git clone https://github.com/d3cod3/ofxFFmpegRecorder git clone https://github.com/kylemcdonald/ofxFft -git clone https://github.com/jeffcrouse/ofxJSON git clone https://github.com/d3cod3/ofxImGui git clone https://github.com/d3cod3/ofxInfiniteCanvas git clone https://github.com/danomatika/ofxLua @@ -262,6 +259,7 @@ Sound | Ready ADSR envelope | X | AHR envelope | X | amplifier | X | +address sequencer | X | audio exporter | X | bit cruncher | X | bit noise | X | @@ -297,6 +295,7 @@ signal gate | X | signal operator | X | signal trigger | X | soundfile player | X | +summer mixer | X | Texture | Ready ---------- | ---------- @@ -346,8 +345,6 @@ ofxEasing original addon by [Arturo Castro](https://github.com/arturoc) ofxFFmpegRecorder original addon by [Furkan Üzümcü](https://github.com/Furkanzmc) -ofxJSON original addon by [Jeff Crouse](https://github.com/jeffcrouse/) - ofxImGui original addon by [Jason Van Cleave](https://github.com/jvcleave) ofxInfiniteCanvas original addon by [Roy Macdonald](https://github.com/roymacdonald) From fed82df75b3e8eb1ca0b825de389e17c94dd6bf3 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Fri, 31 Jan 2025 09:53:39 +0100 Subject: [PATCH 33/35] fixed object name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69ee0b22..b8186511 100644 --- a/README.md +++ b/README.md @@ -295,7 +295,7 @@ signal gate | X | signal operator | X | signal trigger | X | soundfile player | X | -summer mixer | X | +summing mixer | X | Texture | Ready ---------- | ---------- From d8b1edf6d72f6e01f2884342ad16e528692df121 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Fri, 31 Jan 2025 10:15:48 +0100 Subject: [PATCH 34/35] added summing mixer object --- src/objects/sound/SummingMixer.cpp | 322 +++++++++++++++++++++++++++++ src/objects/sound/SummingMixer.h | 84 ++++++++ 2 files changed, 406 insertions(+) create mode 100644 src/objects/sound/SummingMixer.cpp create mode 100644 src/objects/sound/SummingMixer.h diff --git a/src/objects/sound/SummingMixer.cpp b/src/objects/sound/SummingMixer.cpp new file mode 100644 index 00000000..b5fdd331 --- /dev/null +++ b/src/objects/sound/SummingMixer.cpp @@ -0,0 +1,322 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#include "SummingMixer.h" + +//-------------------------------------------------------------- +SummingMixer::SummingMixer() : PatchObject("summing mixer"){ + + this->numInlets = 6; + this->numOutlets = 1; + + for(size_t i=0;i<32;i++){ + _inletParams[i] = new ofSoundBuffer(); + } + + _outletParams[0] = new ofSoundBuffer(); // audio output + + this->initInletsState(); + + signalInlets = 6; + + levels = new pdsp::Amp[signalInlets]; + gain_ctrl = new pdsp::ValueControl[signalInlets]; + + isAudioINObject = true; + isAudioOUTObject = true; + isPDSPPatchableObject = true; + + needReset = false; + loaded = false; + + this->setIsResizable(true); + + prevW = this->width; + prevH = this->height; + +} + +//-------------------------------------------------------------- +void SummingMixer::newObject(){ + PatchObject::setName( this->objectName ); + + for(size_t i=0;i<32;i++){ + this->addInlet(VP_LINK_AUDIO,"s"+ofToString(i+1)); + } + + this->addOutlet(VP_LINK_AUDIO,"output"); + + this->setCustomVar(static_cast(signalInlets),"NUM_INLETS"); + + this->setCustomVar(static_cast(prevW),"WIDTH"); + this->setCustomVar(static_cast(prevH),"HEIGHT"); +} + +//-------------------------------------------------------------- +void SummingMixer::setupObjectContent(shared_ptr &mainWindow){ + unusedArgs(mainWindow); + + loadAudioSettings(); + + initInlets(); +} + +//-------------------------------------------------------------- +void SummingMixer::setupAudioOutObjectContent(pdsp::Engine &engine){ + for(int i=0;i> levels[i].in_mod(); + gain_ctrl[i].set(1.0f/signalInlets); + gain_ctrl[i].enableSmoothing(50.0f); + + this->pdspIn[i] >> levels[i] >> mix; + } + + mix >> this->pdspOut[0]; + mix >> scope >> engine.blackhole(); + +} + +//-------------------------------------------------------------- +void SummingMixer::updateObjectContent(map> &patchObjects){ + unusedArgs(patchObjects); + + if(needReset){ + needReset = false; + resetInletsSettings(); + } + + if(!loaded){ + loaded = true; + + prevW = this->getCustomVar("WIDTH"); + prevH = this->getCustomVar("HEIGHT"); + this->width = prevW; + this->height = prevH; + } + +} + +//-------------------------------------------------------------- +void SummingMixer::drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer){ + unusedArgs(font,glRenderer); + +} + +//-------------------------------------------------------------- +void SummingMixer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){ + + // CONFIG GUI inside Menu + if(_nodeCanvas.BeginNodeMenu()){ + + ImGui::Separator(); + ImGui::Separator(); + ImGui::Separator(); + + if (ImGui::BeginMenu("CONFIG")) + { + + drawObjectNodeConfig(); this->configMenuWidth = ImGui::GetWindowWidth(); + + ImGui::EndMenu(); + } + + _nodeCanvas.EndNodeMenu(); + } + + // Visualize (Object main view) + if( _nodeCanvas.BeginNodeContent(ImGuiExNodeView_Visualise) ){ + + ImVec2 window_pos = ImGui::GetWindowPos(); + ImVec2 window_size = ImVec2(this->width*_nodeCanvas.GetCanvasScale(),this->height*_nodeCanvas.GetCanvasScale()); + float pinDistance = (window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/this->numInlets; + + for(int i=0;inumInlets;i++){ + _nodeCanvas.getNodeDrawList()->AddLine(ImVec2(window_pos.x,window_pos.y + (IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor) + (pinDistance/2) + pinDistance*i),ImVec2(window_pos.x+window_size.x,window_pos.y+(IMGUI_EX_NODE_HEADER_HEIGHT*this->scaleFactor)+((window_size.y-((IMGUI_EX_NODE_HEADER_HEIGHT+IMGUI_EX_NODE_FOOTER_HEIGHT)*this->scaleFactor))/2)),IM_COL32(255,255,120,60),2.0f); + } + + // save object dimensions (for resizable ones) + if(this->width != prevW){ + prevW = this->width; + this->setCustomVar(static_cast(prevW),"WIDTH"); + } + if(this->height != prevH){ + prevH = this->height; + this->setCustomVar(static_cast(prevH),"HEIGHT"); + } + + _nodeCanvas.EndNodeContent(); + } + +} + +//-------------------------------------------------------------- +void SummingMixer::drawObjectNodeConfig(){ + ImGui::Spacing(); + if(ImGui::InputInt("Signal Inlets",&signalInlets)){ + if(signalInlets > MAX_INLETS){ + signalInlets = MAX_INLETS; + } + if(signalInlets < 2){ + signalInlets = 2; + } + } + ImGui::SameLine(); ImGuiEx::HelpMarker("You can set 32 inlets max."); + ImGui::Spacing(); + if(ImGui::Button("APPLY",ImVec2(224*scaleFactor,26*scaleFactor))){ + this->setCustomVar(static_cast(signalInlets),"NUM_INLETS"); + needReset = true; + } + + ImGuiEx::ObjectInfo( + "Sum/mix up to 32 audio signals.", + "https://mosaic.d3cod3.org/reference.php?r=summing-mixer", scaleFactor); +} + +//-------------------------------------------------------------- +void SummingMixer::removeObjectContent(bool removeFileFromData){ + unusedArgs(removeFileFromData); + + for(map::iterator it = this->pdspIn.begin(); it != this->pdspIn.end(); it++ ){ + it->second.disconnectAll(); + } + for(map::iterator it = this->pdspOut.begin(); it != this->pdspOut.end(); it++ ){ + it->second.disconnectAll(); + } +} + +//-------------------------------------------------------------- +void SummingMixer::audioInObject(ofSoundBuffer &inputBuffer){ + unusedArgs(inputBuffer); + + +} + +//-------------------------------------------------------------- +void SummingMixer::audioOutObject(ofSoundBuffer &outputBuffer){ + unusedArgs(outputBuffer); + + // SIGNAL BUFFER + static_cast(_outletParams[0])->copyFrom(scope.getBuffer().data(), bufferSize, 1, sampleRate); +} + +//-------------------------------------------------------------- +void SummingMixer::loadAudioSettings(){ + ofxXmlSettings XML; + +#if OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR < 12 + if (XML.loadFile(patchFile)){ +#else + if (XML.load(patchFile)){ +#endif + if (XML.pushTag("settings")){ + sampleRate = XML.getValue("sample_rate_in",0); + bufferSize = XML.getValue("buffer_size",0); + XML.popTag(); + } + } +} + +//-------------------------------------------------------------- +void SummingMixer::initInlets(){ + signalInlets = this->getCustomVar("NUM_INLETS"); + + resetInletsSettings(); +} + +//-------------------------------------------------------------- +void SummingMixer::resetInletsSettings(){ + + mix.disconnectIn(); + + for(int i=0;ipdspIn[i].disconnectAll(); + } + + vector tempInletsConn; + for(int i=0;inumInlets;i++){ + if(this->inletsConnected[i]){ + tempInletsConn.push_back(true); + }else{ + tempInletsConn.push_back(false); + } + } + + this->numInlets = signalInlets; + + for(int i=0;inumInlets;i++){ + _inletParams[i] = new ofSoundBuffer(); + } + + this->inletsType.clear(); + this->inletsNames.clear(); + this->inletsIDs.clear(); + this->inletsWirelessReceive.clear(); + + for(int i=0;inumInlets;i++){ + this->addInlet(VP_LINK_AUDIO,"s"+ofToString(i+1)); + } + + this->inletsConnected.clear(); + for(int i=0;inumInlets;i++){ + if(i(tempInletsConn.size())){ + if(tempInletsConn.at(i)){ + this->inletsConnected.push_back(true); + }else{ + this->inletsConnected.push_back(false); + } + }else{ + this->inletsConnected.push_back(false); + } + } + + levels = new pdsp::Amp[signalInlets]; + gain_ctrl = new pdsp::ValueControl[signalInlets]; + + for(int i=0;i> levels[i].in_mod(); + gain_ctrl[i].set(1.0f/signalInlets); + gain_ctrl[i].enableSmoothing(50.0f); + + this->pdspIn[i] >> levels[i] >> mix; + } + + ofNotifyEvent(this->resetEvent, this->nId); + + this->saveConfig(false); + +} + +OBJECT_REGISTER( SummingMixer, "summing mixer", OFXVP_OBJECT_CAT_SOUND) + +#endif diff --git a/src/objects/sound/SummingMixer.h b/src/objects/sound/SummingMixer.h new file mode 100644 index 00000000..c6edb7f6 --- /dev/null +++ b/src/objects/sound/SummingMixer.h @@ -0,0 +1,84 @@ +/*============================================================================== + + ofxVisualProgramming: A visual programming patching environment for OF + + Copyright (c) 2025 Emanuele Mazza aka n3m3da + + ofxVisualProgramming is distributed under the MIT License. + This gives everyone the freedoms to use ofxVisualProgramming in any context: + commercial or non-commercial, public or private, open or closed source. + + 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. + + See https://github.com/d3cod3/ofxVisualProgramming for documentation + +==============================================================================*/ + +#ifndef OFXVP_BUILD_WITH_MINIMAL_OBJECTS + +#pragma once + +#include "PatchObject.h" + +class SummingMixer : public PatchObject { + +public: + + SummingMixer(); + + void newObject() override; + void setupObjectContent(shared_ptr &mainWindow) override; + void setupAudioOutObjectContent(pdsp::Engine &engine) override; + void updateObjectContent(map> &patchObjects) override; + + void drawObjectContent(ofTrueTypeFont *font, shared_ptr& glRenderer) override; + void drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ) override; + void drawObjectNodeConfig() override; + + void removeObjectContent(bool removeFileFromData=false) override; + + void audioInObject(ofSoundBuffer &inputBuffer) override; + void audioOutObject(ofSoundBuffer &outputBuffer) override; + + void loadAudioSettings(); + void initInlets(); + void resetInletsSettings(); + + pdsp::PatchNode mix; + pdsp::Amp* levels; + pdsp::ValueControl* gain_ctrl; + pdsp::Scope scope; + + int bufferSize; + int sampleRate; + + int signalInlets; + bool needReset; + bool loaded; + + float prevW, prevH; + + +private: + + OBJECT_FACTORY_PROPS + +}; + +#endif From a518880e10fe5acd355aebe942fcf400827df928 Mon Sep 17 00:00:00 2001 From: d3cod3 Date: Mon, 3 Feb 2025 16:00:48 +0100 Subject: [PATCH 35/35] 0.7.2 macos fixes --- addon_config.mk | 4 +++- src/core/imgui_node_canvas.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/addon_config.mk b/addon_config.mk index 70dca82a..c19b9250 100644 --- a/addon_config.mk +++ b/addon_config.mk @@ -27,7 +27,7 @@ common: ADDON_DEPENDENCIES = ofxKinect ofxOpenCv ofxOsc ofxXmlSettings ADDON_DEPENDENCIES += ofxAudioFile ofxBTrack ofxCv ofxEasing ofxFFmpegRecorder ofxFft ADDON_DEPENDENCIES += ofxGLEditor ofxImGui ofxLua ofxMidi ofxMtlMapping2D - ADDON_DEPENDENCIES += ofxOpenDHT ofxPd ofxPDSP ofxScheme ofxTimeline ofxWarp + ADDON_DEPENDENCIES += ofxOpenDHT ofxPd ofxPDSP ofxTimeline ofxWarp # include search paths, this will be usually parsed from the file system # but if the addon or addon libraries need special search paths they can be @@ -74,6 +74,7 @@ common: linux64: #ADDON_DEPENDENCIES += ofxNDI + ADDON_DEPENDENCIES += ofxScheme ADDON_SOURCES_EXCLUDE = src/objects/video/VideoSender% src/objects/video/VideoReceiver% src/objects/video/SyphonSender% src/objects/video/SyphonReceiver% msys2: @@ -84,3 +85,4 @@ vs: osx: ADDON_DEPENDENCIES += ofxNDI ofxSyphon + ADDON_SOURCES_EXCLUDE = src/objects/scripting/SchemeScript% diff --git a/src/core/imgui_node_canvas.cpp b/src/core/imgui_node_canvas.cpp index 37a13079..e104af6b 100644 --- a/src/core/imgui_node_canvas.cpp +++ b/src/core/imgui_node_canvas.cpp @@ -1159,11 +1159,21 @@ ImGuiEx::NodeConnectData ImGuiEx::NodeCanvas::AddNodePin( const int nodeID, cons const bool is_hovered = is_mouse_hovering_near_link(link_data.bezier); if(ImGui::IsMouseClicked(0) && !isAnyCanvasNodeHovered){ +#ifdef TARGET_OSX + if (is_hovered && ofGetKeyPressed(OF_KEY_COMMAND)){ +#else if (is_hovered && ofGetKeyPressed(OF_KEY_CONTROL)){ +#endif + if (std::find(selected_links.begin(), selected_links.end(),_linksData.at(i)._linkID)==selected_links.end()){ selected_links.push_back(_linksData.at(i)._linkID); } +#ifdef TARGET_OSX + }else if(!is_hovered && !ofGetKeyPressed(OF_KEY_SHIFT) && !ofGetKeyPressed(OF_KEY_COMMAND)){ +#else }else if(!is_hovered && !ofGetKeyPressed(OF_KEY_SHIFT) && !ofGetKeyPressed(OF_KEY_CONTROL)){ +#endif + std::vector::iterator it = std::find(selected_links.begin(), selected_links.end(),_linksData.at(i)._linkID); if (it!=selected_links.end()){ selected_links.erase(it);