From a96166710faf2447ed10194d1829db5564b0dff9 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 4 May 2007 03:59:38 +0000 Subject: Made engine, serialisation, client library, and GUI all dynamically loaded modules. Combined all executables into a single "ingen" program which can do everything. git-svn-id: http://svn.drobilla.net/lad/ingen@493 a436a847-0d15-0410-975c-d299462d15a1 --- src/Makefile.am | 2 + src/common/interface/EngineInterface.h | 2 + src/common/interface/Makefile.am | 1 + src/common/interface/Responder.h | 75 + src/libs/Makefile.am | 2 +- src/libs/client/Makefile.am | 19 +- src/libs/client/OSCEngineSender.h | 5 +- src/libs/client/client.cpp | 36 + src/libs/client/client.h | 40 + src/libs/engine/ClientBroadcaster.h | 7 +- src/libs/engine/DirectResponder.h | 10 +- src/libs/engine/Engine.cpp | 22 +- src/libs/engine/Engine.h | 6 +- src/libs/engine/Event.h | 16 +- src/libs/engine/Makefile.am | 1 - src/libs/engine/MidiBuffer.cpp | 2 +- src/libs/engine/OSCClientSender.cpp | 4 +- src/libs/engine/OSCEngineReceiver.cpp | 11 +- src/libs/engine/OSCEngineReceiver.h | 6 +- src/libs/engine/OSCResponder.h | 10 +- src/libs/engine/Patch.cpp | 2 +- src/libs/engine/QueuedEngineInterface.cpp | 7 +- src/libs/engine/QueuedEngineInterface.h | 8 +- src/libs/engine/QueuedEvent.h | 13 +- src/libs/engine/Responder.h | 73 - src/libs/engine/engine.cpp | 54 +- src/libs/engine/engine.h | 13 +- src/libs/engine/events/AddNodeEvent.cpp | 6 +- src/libs/engine/events/AddNodeEvent.h | 4 +- src/libs/engine/events/AddPortEvent.cpp | 4 +- src/libs/engine/events/AddPortEvent.h | 2 +- src/libs/engine/events/AllNotesOffEvent.cpp | 6 +- src/libs/engine/events/AllNotesOffEvent.h | 4 +- src/libs/engine/events/ClearPatchEvent.cpp | 4 +- src/libs/engine/events/ClearPatchEvent.h | 2 +- src/libs/engine/events/ConnectionEvent.cpp | 4 +- src/libs/engine/events/ConnectionEvent.h | 2 +- src/libs/engine/events/CreatePatchEvent.cpp | 4 +- src/libs/engine/events/CreatePatchEvent.h | 2 +- src/libs/engine/events/DSSIConfigureEvent.cpp | 2 +- src/libs/engine/events/DSSIConfigureEvent.h | 2 +- src/libs/engine/events/DSSIControlEvent.cpp | 2 +- src/libs/engine/events/DSSIControlEvent.h | 2 +- src/libs/engine/events/DSSIProgramEvent.cpp | 2 +- src/libs/engine/events/DSSIProgramEvent.h | 2 +- src/libs/engine/events/DSSIUpdateEvent.cpp | 2 +- src/libs/engine/events/DSSIUpdateEvent.h | 2 +- src/libs/engine/events/DeactivateEvent.cpp | 4 +- src/libs/engine/events/DeactivateEvent.h | 2 +- src/libs/engine/events/DestroyEvent.cpp | 6 +- src/libs/engine/events/DestroyEvent.h | 4 +- src/libs/engine/events/DisablePatchEvent.cpp | 4 +- src/libs/engine/events/DisablePatchEvent.h | 2 +- src/libs/engine/events/DisconnectNodeEvent.cpp | 6 +- src/libs/engine/events/DisconnectNodeEvent.h | 2 +- src/libs/engine/events/DisconnectPortEvent.cpp | 6 +- src/libs/engine/events/DisconnectPortEvent.h | 2 +- src/libs/engine/events/DisconnectionEvent.cpp | 6 +- src/libs/engine/events/DisconnectionEvent.h | 4 +- src/libs/engine/events/EnablePatchEvent.cpp | 4 +- src/libs/engine/events/EnablePatchEvent.h | 2 +- src/libs/engine/events/LashRestoreDoneEvent.h | 2 +- src/libs/engine/events/LoadPluginsEvent.cpp | 4 +- src/libs/engine/events/LoadPluginsEvent.h | 2 +- src/libs/engine/events/MidiLearnEvent.cpp | 4 +- src/libs/engine/events/MidiLearnEvent.h | 4 +- src/libs/engine/events/NoteOffEvent.cpp | 6 +- src/libs/engine/events/NoteOffEvent.h | 4 +- src/libs/engine/events/NoteOnEvent.cpp | 6 +- src/libs/engine/events/NoteOnEvent.h | 4 +- src/libs/engine/events/PingQueuedEvent.h | 6 +- src/libs/engine/events/RegisterClientEvent.cpp | 4 +- src/libs/engine/events/RegisterClientEvent.h | 10 +- src/libs/engine/events/RenameEvent.cpp | 4 +- src/libs/engine/events/RenameEvent.h | 2 +- src/libs/engine/events/RequestAllObjectsEvent.cpp | 4 +- src/libs/engine/events/RequestAllObjectsEvent.h | 2 +- src/libs/engine/events/RequestMetadataEvent.cpp | 4 +- src/libs/engine/events/RequestMetadataEvent.h | 2 +- src/libs/engine/events/RequestObjectEvent.cpp | 4 +- src/libs/engine/events/RequestObjectEvent.h | 2 +- src/libs/engine/events/RequestPluginEvent.cpp | 4 +- src/libs/engine/events/RequestPluginEvent.h | 2 +- src/libs/engine/events/RequestPluginsEvent.cpp | 4 +- src/libs/engine/events/RequestPluginsEvent.h | 4 +- src/libs/engine/events/RequestPortValueEvent.cpp | 4 +- src/libs/engine/events/RequestPortValueEvent.h | 2 +- src/libs/engine/events/SetMetadataEvent.cpp | 4 +- src/libs/engine/events/SetMetadataEvent.h | 2 +- src/libs/engine/events/SetPortValueEvent.cpp | 6 +- src/libs/engine/events/SetPortValueEvent.h | 4 +- src/libs/engine/events/SetPortValueQueuedEvent.cpp | 6 +- src/libs/engine/events/SetPortValueQueuedEvent.h | 4 +- src/libs/engine/events/UnregisterClientEvent.cpp | 6 +- src/libs/engine/events/UnregisterClientEvent.h | 5 +- src/libs/gui/App.cpp | 260 ++ src/libs/gui/App.h | 140 + src/libs/gui/BreadCrumb.h | 81 + src/libs/gui/BreadCrumbBox.cpp | 206 ++ src/libs/gui/BreadCrumbBox.h | 70 + src/libs/gui/ConfigWindow.cpp | 88 + src/libs/gui/ConfigWindow.h | 65 + src/libs/gui/Configuration.cpp | 187 ++ src/libs/gui/Configuration.h | 79 + src/libs/gui/ConnectWindow.cpp | 426 +++ src/libs/gui/ConnectWindow.h | 92 + src/libs/gui/Connection.h | 60 + src/libs/gui/ControlGroups.cpp | 430 +++ src/libs/gui/ControlGroups.h | 162 ++ src/libs/gui/ControlPanel.cpp | 259 ++ src/libs/gui/ControlPanel.h | 94 + src/libs/gui/DSSIController.cpp | 279 ++ src/libs/gui/DSSIController.h | 77 + src/libs/gui/DSSIModule.cpp | 43 + src/libs/gui/DSSIModule.h | 46 + src/libs/gui/GladeFactory.cpp | 72 + src/libs/gui/GladeFactory.h | 51 + src/libs/gui/LashController.cpp | 170 ++ src/libs/gui/LashController.h | 56 + src/libs/gui/LoadPatchWindow.cpp | 149 + src/libs/gui/LoadPatchWindow.h | 81 + src/libs/gui/LoadPluginWindow.cpp | 458 +++ src/libs/gui/LoadPluginWindow.h | 151 + src/libs/gui/LoadRemotePatchWindow.cpp | 163 ++ src/libs/gui/LoadRemotePatchWindow.h | 93 + src/libs/gui/LoadSubpatchWindow.cpp | 175 ++ src/libs/gui/LoadSubpatchWindow.h | 79 + src/libs/gui/Makefile.am | 104 + src/libs/gui/MessagesWindow.cpp | 67 + src/libs/gui/MessagesWindow.h | 58 + src/libs/gui/NewSubpatchWindow.cpp | 111 + src/libs/gui/NewSubpatchWindow.h | 67 + src/libs/gui/NodeControlWindow.cpp | 136 + src/libs/gui/NodeControlWindow.h | 76 + src/libs/gui/NodeMenu.cpp | 262 ++ src/libs/gui/NodeMenu.h | 78 + src/libs/gui/NodeModule.cpp | 153 + src/libs/gui/NodeModule.h | 90 + src/libs/gui/NodePropertiesWindow.cpp | 67 + src/libs/gui/NodePropertiesWindow.h | 58 + src/libs/gui/PatchCanvas.cpp | 525 ++++ src/libs/gui/PatchCanvas.h | 129 + src/libs/gui/PatchPortModule.cpp | 113 + src/libs/gui/PatchPortModule.h | 80 + src/libs/gui/PatchPropertiesWindow.cpp | 89 + src/libs/gui/PatchPropertiesWindow.h | 64 + src/libs/gui/PatchTreeWindow.cpp | 270 ++ src/libs/gui/PatchTreeWindow.h | 112 + src/libs/gui/PatchView.cpp | 162 ++ src/libs/gui/PatchView.h | 102 + src/libs/gui/PatchWindow.cpp | 467 +++ src/libs/gui/PatchWindow.h | 143 + src/libs/gui/Port.cpp | 61 + src/libs/gui/Port.h | 57 + src/libs/gui/PortPropertiesWindow.cpp | 175 ++ src/libs/gui/PortPropertiesWindow.h | 70 + src/libs/gui/RenameWindow.cpp | 117 + src/libs/gui/RenameWindow.h | 60 + src/libs/gui/SubpatchModule.cpp | 95 + src/libs/gui/SubpatchModule.h | 71 + src/libs/gui/ThreadedLoader.cpp | 141 + src/libs/gui/ThreadedLoader.h | 99 + src/libs/gui/UploadPatchWindow.cpp | 283 ++ src/libs/gui/UploadPatchWindow.h | 105 + src/libs/gui/WindowFactory.cpp | 357 +++ src/libs/gui/WindowFactory.h | 105 + src/libs/gui/cmdline.h | 86 + src/libs/gui/ingen-icon.svg | 54 + src/libs/gui/ingen.svg | 54 + src/libs/gui/ingen_gui.glade | 3044 ++++++++++++++++++++ src/libs/gui/ingen_gui.gladep | 9 + src/libs/module/Module.cpp | 29 +- src/progs/Makefile.am | 10 +- src/progs/ingen/Makefile.am | 16 + src/progs/ingen/cmdline.ggo | 19 + src/progs/ingen/ingen.desktop.in | 10 + src/progs/ingen/ingen_dev | 3 + src/progs/ingen/main.cpp | 194 ++ src/progs/ingenuity/App.cpp | 246 -- src/progs/ingenuity/App.h | 137 - src/progs/ingenuity/BreadCrumb.h | 79 - src/progs/ingenuity/BreadCrumbBox.cpp | 204 -- src/progs/ingenuity/BreadCrumbBox.h | 68 - src/progs/ingenuity/ConfigWindow.cpp | 86 - src/progs/ingenuity/ConfigWindow.h | 63 - src/progs/ingenuity/Configuration.cpp | 185 -- src/progs/ingenuity/Configuration.h | 77 - src/progs/ingenuity/ConnectWindow.cpp | 427 --- src/progs/ingenuity/ConnectWindow.h | 91 - src/progs/ingenuity/Connection.h | 58 - src/progs/ingenuity/ControlGroups.cpp | 428 --- src/progs/ingenuity/ControlGroups.h | 160 - src/progs/ingenuity/ControlPanel.cpp | 257 -- src/progs/ingenuity/ControlPanel.h | 92 - src/progs/ingenuity/DSSIController.cpp | 277 -- src/progs/ingenuity/DSSIController.h | 75 - src/progs/ingenuity/DSSIModule.cpp | 41 - src/progs/ingenuity/DSSIModule.h | 44 - src/progs/ingenuity/GladeFactory.cpp | 70 - src/progs/ingenuity/GladeFactory.h | 49 - src/progs/ingenuity/LashController.cpp | 168 -- src/progs/ingenuity/LashController.h | 54 - src/progs/ingenuity/LoadPatchWindow.cpp | 147 - src/progs/ingenuity/LoadPatchWindow.h | 79 - src/progs/ingenuity/LoadPluginWindow.cpp | 456 --- src/progs/ingenuity/LoadPluginWindow.h | 149 - src/progs/ingenuity/LoadRemotePatchWindow.cpp | 161 -- src/progs/ingenuity/LoadRemotePatchWindow.h | 91 - src/progs/ingenuity/LoadSubpatchWindow.cpp | 173 -- src/progs/ingenuity/LoadSubpatchWindow.h | 77 - src/progs/ingenuity/Makefile.am | 98 - src/progs/ingenuity/MessagesWindow.cpp | 65 - src/progs/ingenuity/MessagesWindow.h | 56 - src/progs/ingenuity/NewSubpatchWindow.cpp | 109 - src/progs/ingenuity/NewSubpatchWindow.h | 65 - src/progs/ingenuity/NodeControlWindow.cpp | 134 - src/progs/ingenuity/NodeControlWindow.h | 74 - src/progs/ingenuity/NodeMenu.cpp | 260 -- src/progs/ingenuity/NodeMenu.h | 76 - src/progs/ingenuity/NodeModule.cpp | 151 - src/progs/ingenuity/NodeModule.h | 88 - src/progs/ingenuity/NodePropertiesWindow.cpp | 65 - src/progs/ingenuity/NodePropertiesWindow.h | 56 - src/progs/ingenuity/PatchCanvas.cpp | 523 ---- src/progs/ingenuity/PatchCanvas.h | 127 - src/progs/ingenuity/PatchPortModule.cpp | 111 - src/progs/ingenuity/PatchPortModule.h | 78 - src/progs/ingenuity/PatchPropertiesWindow.cpp | 87 - src/progs/ingenuity/PatchPropertiesWindow.h | 62 - src/progs/ingenuity/PatchTreeWindow.cpp | 268 -- src/progs/ingenuity/PatchTreeWindow.h | 110 - src/progs/ingenuity/PatchView.cpp | 160 - src/progs/ingenuity/PatchView.h | 100 - src/progs/ingenuity/PatchWindow.cpp | 465 --- src/progs/ingenuity/PatchWindow.h | 141 - src/progs/ingenuity/Port.cpp | 59 - src/progs/ingenuity/Port.h | 55 - src/progs/ingenuity/PortPropertiesWindow.cpp | 173 -- src/progs/ingenuity/PortPropertiesWindow.h | 68 - src/progs/ingenuity/RenameWindow.cpp | 115 - src/progs/ingenuity/RenameWindow.h | 58 - src/progs/ingenuity/SubpatchModule.cpp | 93 - src/progs/ingenuity/SubpatchModule.h | 69 - src/progs/ingenuity/ThreadedLoader.cpp | 139 - src/progs/ingenuity/ThreadedLoader.h | 97 - src/progs/ingenuity/UploadPatchWindow.cpp | 281 -- src/progs/ingenuity/UploadPatchWindow.h | 103 - src/progs/ingenuity/WindowFactory.cpp | 355 --- src/progs/ingenuity/WindowFactory.h | 102 - src/progs/ingenuity/cmdline.c | 149 - src/progs/ingenuity/cmdline.ggo | 7 - src/progs/ingenuity/cmdline.h | 45 - src/progs/ingenuity/ingen.svg | 54 - src/progs/ingenuity/ingenuity.desktop | 10 - src/progs/ingenuity/ingenuity.desktop.in | 10 - src/progs/ingenuity/ingenuity.glade | 3044 -------------------- src/progs/ingenuity/ingenuity.gladep | 9 - src/progs/ingenuity/ingenuity_dev | 3 - src/progs/ingenuity/main.cpp | 67 - src/progs/patch_loader/Makefile.am | 13 - src/progs/patch_loader/README | 5 - src/progs/patch_loader/cmdline.c | 163 -- src/progs/patch_loader/cmdline.ggo | 7 - src/progs/patch_loader/cmdline.h | 47 - src/progs/patch_loader/new_patch_loader.cpp | 76 - src/progs/patch_loader/patch_loader.cpp | 110 - src/progs/python/ingen.py | 40 +- src/progs/python/ingenecho.py | 8 +- src/progs/server/Makefile.am | 44 - src/progs/server/cmdline.c | 355 --- src/progs/server/cmdline.ggo | 7 - src/progs/server/cmdline.h | 69 - src/progs/server/ingen_dev | 3 - src/progs/server/main.cpp | 180 -- src/progs/supercollider/Ingen.sc | 76 +- src/set_dev_environment.sh | 2 +- 276 files changed, 14228 insertions(+), 14887 deletions(-) create mode 100644 src/common/interface/Responder.h create mode 100644 src/libs/client/client.cpp create mode 100644 src/libs/client/client.h delete mode 100644 src/libs/engine/Responder.h create mode 100644 src/libs/gui/App.cpp create mode 100644 src/libs/gui/App.h create mode 100644 src/libs/gui/BreadCrumb.h create mode 100644 src/libs/gui/BreadCrumbBox.cpp create mode 100644 src/libs/gui/BreadCrumbBox.h create mode 100644 src/libs/gui/ConfigWindow.cpp create mode 100644 src/libs/gui/ConfigWindow.h create mode 100644 src/libs/gui/Configuration.cpp create mode 100644 src/libs/gui/Configuration.h create mode 100644 src/libs/gui/ConnectWindow.cpp create mode 100644 src/libs/gui/ConnectWindow.h create mode 100644 src/libs/gui/Connection.h create mode 100644 src/libs/gui/ControlGroups.cpp create mode 100644 src/libs/gui/ControlGroups.h create mode 100644 src/libs/gui/ControlPanel.cpp create mode 100644 src/libs/gui/ControlPanel.h create mode 100644 src/libs/gui/DSSIController.cpp create mode 100644 src/libs/gui/DSSIController.h create mode 100644 src/libs/gui/DSSIModule.cpp create mode 100644 src/libs/gui/DSSIModule.h create mode 100644 src/libs/gui/GladeFactory.cpp create mode 100644 src/libs/gui/GladeFactory.h create mode 100644 src/libs/gui/LashController.cpp create mode 100644 src/libs/gui/LashController.h create mode 100644 src/libs/gui/LoadPatchWindow.cpp create mode 100644 src/libs/gui/LoadPatchWindow.h create mode 100644 src/libs/gui/LoadPluginWindow.cpp create mode 100644 src/libs/gui/LoadPluginWindow.h create mode 100644 src/libs/gui/LoadRemotePatchWindow.cpp create mode 100644 src/libs/gui/LoadRemotePatchWindow.h create mode 100644 src/libs/gui/LoadSubpatchWindow.cpp create mode 100644 src/libs/gui/LoadSubpatchWindow.h create mode 100644 src/libs/gui/Makefile.am create mode 100644 src/libs/gui/MessagesWindow.cpp create mode 100644 src/libs/gui/MessagesWindow.h create mode 100644 src/libs/gui/NewSubpatchWindow.cpp create mode 100644 src/libs/gui/NewSubpatchWindow.h create mode 100644 src/libs/gui/NodeControlWindow.cpp create mode 100644 src/libs/gui/NodeControlWindow.h create mode 100644 src/libs/gui/NodeMenu.cpp create mode 100644 src/libs/gui/NodeMenu.h create mode 100644 src/libs/gui/NodeModule.cpp create mode 100644 src/libs/gui/NodeModule.h create mode 100644 src/libs/gui/NodePropertiesWindow.cpp create mode 100644 src/libs/gui/NodePropertiesWindow.h create mode 100644 src/libs/gui/PatchCanvas.cpp create mode 100644 src/libs/gui/PatchCanvas.h create mode 100644 src/libs/gui/PatchPortModule.cpp create mode 100644 src/libs/gui/PatchPortModule.h create mode 100644 src/libs/gui/PatchPropertiesWindow.cpp create mode 100644 src/libs/gui/PatchPropertiesWindow.h create mode 100644 src/libs/gui/PatchTreeWindow.cpp create mode 100644 src/libs/gui/PatchTreeWindow.h create mode 100644 src/libs/gui/PatchView.cpp create mode 100644 src/libs/gui/PatchView.h create mode 100644 src/libs/gui/PatchWindow.cpp create mode 100644 src/libs/gui/PatchWindow.h create mode 100644 src/libs/gui/Port.cpp create mode 100644 src/libs/gui/Port.h create mode 100644 src/libs/gui/PortPropertiesWindow.cpp create mode 100644 src/libs/gui/PortPropertiesWindow.h create mode 100644 src/libs/gui/RenameWindow.cpp create mode 100644 src/libs/gui/RenameWindow.h create mode 100644 src/libs/gui/SubpatchModule.cpp create mode 100644 src/libs/gui/SubpatchModule.h create mode 100644 src/libs/gui/ThreadedLoader.cpp create mode 100644 src/libs/gui/ThreadedLoader.h create mode 100644 src/libs/gui/UploadPatchWindow.cpp create mode 100644 src/libs/gui/UploadPatchWindow.h create mode 100644 src/libs/gui/WindowFactory.cpp create mode 100644 src/libs/gui/WindowFactory.h create mode 100644 src/libs/gui/cmdline.h create mode 100644 src/libs/gui/ingen-icon.svg create mode 100644 src/libs/gui/ingen.svg create mode 100644 src/libs/gui/ingen_gui.glade create mode 100644 src/libs/gui/ingen_gui.gladep create mode 100644 src/progs/ingen/Makefile.am create mode 100644 src/progs/ingen/cmdline.ggo create mode 100644 src/progs/ingen/ingen.desktop.in create mode 100755 src/progs/ingen/ingen_dev create mode 100644 src/progs/ingen/main.cpp delete mode 100644 src/progs/ingenuity/App.cpp delete mode 100644 src/progs/ingenuity/App.h delete mode 100644 src/progs/ingenuity/BreadCrumb.h delete mode 100644 src/progs/ingenuity/BreadCrumbBox.cpp delete mode 100644 src/progs/ingenuity/BreadCrumbBox.h delete mode 100644 src/progs/ingenuity/ConfigWindow.cpp delete mode 100644 src/progs/ingenuity/ConfigWindow.h delete mode 100644 src/progs/ingenuity/Configuration.cpp delete mode 100644 src/progs/ingenuity/Configuration.h delete mode 100644 src/progs/ingenuity/ConnectWindow.cpp delete mode 100644 src/progs/ingenuity/ConnectWindow.h delete mode 100644 src/progs/ingenuity/Connection.h delete mode 100644 src/progs/ingenuity/ControlGroups.cpp delete mode 100644 src/progs/ingenuity/ControlGroups.h delete mode 100644 src/progs/ingenuity/ControlPanel.cpp delete mode 100644 src/progs/ingenuity/ControlPanel.h delete mode 100644 src/progs/ingenuity/DSSIController.cpp delete mode 100644 src/progs/ingenuity/DSSIController.h delete mode 100644 src/progs/ingenuity/DSSIModule.cpp delete mode 100644 src/progs/ingenuity/DSSIModule.h delete mode 100644 src/progs/ingenuity/GladeFactory.cpp delete mode 100644 src/progs/ingenuity/GladeFactory.h delete mode 100644 src/progs/ingenuity/LashController.cpp delete mode 100644 src/progs/ingenuity/LashController.h delete mode 100644 src/progs/ingenuity/LoadPatchWindow.cpp delete mode 100644 src/progs/ingenuity/LoadPatchWindow.h delete mode 100644 src/progs/ingenuity/LoadPluginWindow.cpp delete mode 100644 src/progs/ingenuity/LoadPluginWindow.h delete mode 100644 src/progs/ingenuity/LoadRemotePatchWindow.cpp delete mode 100644 src/progs/ingenuity/LoadRemotePatchWindow.h delete mode 100644 src/progs/ingenuity/LoadSubpatchWindow.cpp delete mode 100644 src/progs/ingenuity/LoadSubpatchWindow.h delete mode 100644 src/progs/ingenuity/Makefile.am delete mode 100644 src/progs/ingenuity/MessagesWindow.cpp delete mode 100644 src/progs/ingenuity/MessagesWindow.h delete mode 100644 src/progs/ingenuity/NewSubpatchWindow.cpp delete mode 100644 src/progs/ingenuity/NewSubpatchWindow.h delete mode 100644 src/progs/ingenuity/NodeControlWindow.cpp delete mode 100644 src/progs/ingenuity/NodeControlWindow.h delete mode 100644 src/progs/ingenuity/NodeMenu.cpp delete mode 100644 src/progs/ingenuity/NodeMenu.h delete mode 100644 src/progs/ingenuity/NodeModule.cpp delete mode 100644 src/progs/ingenuity/NodeModule.h delete mode 100644 src/progs/ingenuity/NodePropertiesWindow.cpp delete mode 100644 src/progs/ingenuity/NodePropertiesWindow.h delete mode 100644 src/progs/ingenuity/PatchCanvas.cpp delete mode 100644 src/progs/ingenuity/PatchCanvas.h delete mode 100644 src/progs/ingenuity/PatchPortModule.cpp delete mode 100644 src/progs/ingenuity/PatchPortModule.h delete mode 100644 src/progs/ingenuity/PatchPropertiesWindow.cpp delete mode 100644 src/progs/ingenuity/PatchPropertiesWindow.h delete mode 100644 src/progs/ingenuity/PatchTreeWindow.cpp delete mode 100644 src/progs/ingenuity/PatchTreeWindow.h delete mode 100644 src/progs/ingenuity/PatchView.cpp delete mode 100644 src/progs/ingenuity/PatchView.h delete mode 100644 src/progs/ingenuity/PatchWindow.cpp delete mode 100644 src/progs/ingenuity/PatchWindow.h delete mode 100644 src/progs/ingenuity/Port.cpp delete mode 100644 src/progs/ingenuity/Port.h delete mode 100644 src/progs/ingenuity/PortPropertiesWindow.cpp delete mode 100644 src/progs/ingenuity/PortPropertiesWindow.h delete mode 100644 src/progs/ingenuity/RenameWindow.cpp delete mode 100644 src/progs/ingenuity/RenameWindow.h delete mode 100644 src/progs/ingenuity/SubpatchModule.cpp delete mode 100644 src/progs/ingenuity/SubpatchModule.h delete mode 100644 src/progs/ingenuity/ThreadedLoader.cpp delete mode 100644 src/progs/ingenuity/ThreadedLoader.h delete mode 100644 src/progs/ingenuity/UploadPatchWindow.cpp delete mode 100644 src/progs/ingenuity/UploadPatchWindow.h delete mode 100644 src/progs/ingenuity/WindowFactory.cpp delete mode 100644 src/progs/ingenuity/WindowFactory.h delete mode 100644 src/progs/ingenuity/cmdline.c delete mode 100644 src/progs/ingenuity/cmdline.ggo delete mode 100644 src/progs/ingenuity/cmdline.h delete mode 100644 src/progs/ingenuity/ingen.svg delete mode 100644 src/progs/ingenuity/ingenuity.desktop delete mode 100644 src/progs/ingenuity/ingenuity.desktop.in delete mode 100644 src/progs/ingenuity/ingenuity.glade delete mode 100644 src/progs/ingenuity/ingenuity.gladep delete mode 100755 src/progs/ingenuity/ingenuity_dev delete mode 100644 src/progs/ingenuity/main.cpp delete mode 100644 src/progs/patch_loader/Makefile.am delete mode 100644 src/progs/patch_loader/README delete mode 100644 src/progs/patch_loader/cmdline.c delete mode 100644 src/progs/patch_loader/cmdline.ggo delete mode 100644 src/progs/patch_loader/cmdline.h delete mode 100644 src/progs/patch_loader/new_patch_loader.cpp delete mode 100644 src/progs/patch_loader/patch_loader.cpp delete mode 100644 src/progs/server/Makefile.am delete mode 100644 src/progs/server/cmdline.c delete mode 100644 src/progs/server/cmdline.ggo delete mode 100644 src/progs/server/cmdline.h delete mode 100755 src/progs/server/ingen_dev delete mode 100644 src/progs/server/main.cpp (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 48cb026b..c9d9fc9b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,5 @@ +EXTRA_DIST = set_dev_environment.sh + SUBDIRS = libs progs DIST_SUBDIRS = $(SUBDIRS) common diff --git a/src/common/interface/EngineInterface.h b/src/common/interface/EngineInterface.h index 8a10c840..1701a78e 100644 --- a/src/common/interface/EngineInterface.h +++ b/src/common/interface/EngineInterface.h @@ -29,6 +29,7 @@ namespace Ingen { namespace Shared { class ClientKey; +class Responder; /** The (only) interface clients use to communicate with the engine. @@ -41,6 +42,7 @@ public: virtual ~EngineInterface() {} // Responses + virtual void set_responder(SharedPtr responder) = 0; virtual void set_next_response_id(int32_t id) = 0; virtual void disable_responses() = 0; diff --git a/src/common/interface/Makefile.am b/src/common/interface/Makefile.am index 8719cccd..347e8186 100644 --- a/src/common/interface/Makefile.am +++ b/src/common/interface/Makefile.am @@ -2,4 +2,5 @@ EXTRA_DIST = \ README \ ClientInterface.h \ ClientKey.h \ + Responder.h \ EngineInterface.h diff --git a/src/common/interface/Responder.h b/src/common/interface/Responder.h new file mode 100644 index 00000000..6e809e1a --- /dev/null +++ b/src/common/interface/Responder.h @@ -0,0 +1,75 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RESPONDER_H +#define RESPONDER_H + +#include +#include +#include +#include "interface/ClientKey.h" +#include "interface/ClientInterface.h" +using std::string; + +namespace Ingen { +namespace Shared { + +using Shared::ClientKey; +using Shared::ClientInterface; + + +/** Class to handle responding to clients. + * + * This is an abstract base class to fully abstract the details of client + * communication from the internals of the engine. + * + * Note that this class only handles sending responses to commands from + * clients, (ie OK or an error), not notifications (ie new node, + * disconnection) - that's what ClientInterface is for. If a command is + * a request, the ClientKey of the Responder can be used to find the + * ClientInterface which should receive the response. + * + * ClientInterface and Responder are seperate because responding might not + * actually get exposed to the client interface (eg in simulated blocking + * interfaces that wait for responses before returning). + * + * Note for messages that have a "response" and some broadcasted effect + * (eg setting a port value) the "response" MUST be sent first since Responder + * is responsible for controlling whether the client wishes to receive the + * notification. + */ +class Responder +{ +public: + Responder() {} + virtual ~Responder() {} + + virtual ClientKey client_key() { return ClientKey(); } + virtual SharedPtr client() { return SharedPtr(); } + + virtual void set_id(int32_t id) {} + + virtual void respond_ok() {} + virtual void respond_error(const string& msg) {} +}; + + +} // namespace Shared +} // namespace Ingen + +#endif // RESPONDER_H + diff --git a/src/libs/Makefile.am b/src/libs/Makefile.am index 81422435..9e80a248 100644 --- a/src/libs/Makefile.am +++ b/src/libs/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = module engine serialisation client +SUBDIRS = module engine serialisation client gui diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am index 1a0aa61d..20822e8a 100644 --- a/src/libs/client/Makefile.am +++ b/src/libs/client/Makefile.am @@ -1,12 +1,25 @@ if BUILD_CLIENT_LIB -noinst_LTLIBRARIES = libingen_client.la -libingen_client_la_CXXFLAGS = @RAUL_CFLAGS@ @SLV2_CFLAGS@ @LXML2_CFLAGS@ @RASQAL_CFLAGS@ @RAPTOR_CFLAGS@ @LSIGCPP_CFLAGS@ @GLIBMM_CFLAGS@ -I$(top_srcdir)/src/common -DPKGDATADIR=\"$(pkgdatadir)\" +moduledir = $(libdir)/ingen -libingen_client_la_LIBADD = @RAUL_LIBS@ @SLV2_LIBS@ @LXML2_LIBS@ @LOSC_LIBS@ @RASQAL_LIBS@ @RAPTOR_LIBS@ @LSIGCPP_LIBS@ @GLIBMM_LIBS@ +module_LTLIBRARIES = libingen_client.la + +libingen_client_la_CXXFLAGS = \ + @RAUL_CFLAGS@ @SLV2_CFLAGS@ @LOSC_CFLAGS@ \ + @LXML2_CFLAGS@ @RASQAL_CFLAGS@ @RAPTOR_CFLAGS@ \ + @LSIGCPP_CFLAGS@ @GLIBMM_CFLAGS@ \ + -I$(top_srcdir)/src/common \ + -DPKGDATADIR=\"$(pkgdatadir)\" + +libingen_client_la_LIBADD = \ + @RAUL_LIBS@ @SLV2_LIBS@ @LOSC_LIBS@ \ + @LXML2_LIBS@ @RASQAL_LIBS@ @RAPTOR_LIBS@ \ + @LSIGCPP_LIBS@ @GLIBMM_LIBS@ libingen_client_la_SOURCES = \ + client.h \ + client.cpp \ OSCEngineSender.h \ OSCEngineSender.cpp \ OSCClientReceiver.h \ diff --git a/src/libs/client/OSCEngineSender.h b/src/libs/client/OSCEngineSender.h index 30df18fa..68163ec6 100644 --- a/src/libs/client/OSCEngineSender.h +++ b/src/libs/client/OSCEngineSender.h @@ -22,10 +22,12 @@ #include #include #include "interface/EngineInterface.h" +#include "interface/Responder.h" using std::string; using Ingen::Shared::EngineInterface; using Ingen::Shared::ClientInterface; using Ingen::Shared::ClientKey; +using Ingen::Shared::Responder; namespace Ingen { namespace Client { @@ -38,7 +40,7 @@ namespace Client { * * \ingroup IngenClient */ -class OSCEngineSender : virtual public EngineInterface +class OSCEngineSender : public EngineInterface { public: OSCEngineSender(const string& engine_url); @@ -50,6 +52,7 @@ public: inline size_t next_id() { int32_t ret = (_id == -1) ? -1 : _id++; return ret; } + void set_responder(SharedPtr responder) { throw; } void set_next_response_id(int32_t id) { _id = id; } void disable_responses() { _id = -1; } diff --git a/src/libs/client/client.cpp b/src/libs/client/client.cpp new file mode 100644 index 00000000..99fa116c --- /dev/null +++ b/src/libs/client/client.cpp @@ -0,0 +1,36 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "client.h" +#include "OSCEngineSender.h" + +namespace Ingen { +namespace Client { + + +SharedPtr +new_osc_interface(const std::string& url) +{ + OSCEngineSender* oes = new OSCEngineSender(url); + oes->attach(rand(), true); + return SharedPtr(oes); +} + + +} // namespace Client +} // namespace Ingen + diff --git a/src/libs/client/client.h b/src/libs/client/client.h new file mode 100644 index 00000000..c2b19d12 --- /dev/null +++ b/src/libs/client/client.h @@ -0,0 +1,40 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef INGEN_CLIENT_H +#define INGEN_CLIENT_H + +#include + +namespace Ingen { + +namespace Shared { class EngineInterface; } + +namespace Client { + +extern "C" { + + SharedPtr new_osc_interface(const std::string& url); + +} + + +} // namespace Client +} // namespace Ingen + +#endif // INGEN_CLIENT_H + diff --git a/src/libs/engine/ClientBroadcaster.h b/src/libs/engine/ClientBroadcaster.h index 8b6d4616..cef7b397 100644 --- a/src/libs/engine/ClientBroadcaster.h +++ b/src/libs/engine/ClientBroadcaster.h @@ -24,9 +24,9 @@ #include #include #include -#include "types.h" -#include "interface/ClientInterface.h" #include +#include "interface/ClientInterface.h" +#include "types.h" using std::list; using std::string; using std::pair; @@ -37,8 +37,7 @@ class Port; class Plugin; class Patch; class Connection; -class Responder; -namespace Shared { class ClientKey; } +namespace Shared { class ClientKey; class Responder; } using Shared::ClientKey; using Shared::ClientInterface; diff --git a/src/libs/engine/DirectResponder.h b/src/libs/engine/DirectResponder.h index c9e50f76..79dc1f81 100644 --- a/src/libs/engine/DirectResponder.h +++ b/src/libs/engine/DirectResponder.h @@ -21,17 +21,17 @@ #include #include "interface/ClientInterface.h" -#include "Responder.h" +#include "interface/Responder.h" namespace Ingen { /** Responder for Direct clients (directly calls methods on a ClientInterface). */ -class DirectResponder : public Responder +class DirectResponder : public Shared::Responder { public: - DirectResponder(SharedPtr client, int32_t id) + DirectResponder(SharedPtr client, int32_t id) : _client(client), _id(id) {} @@ -40,10 +40,10 @@ public: void respond_ok() { _client->response(_id, true, ""); } void respond_error(const string& msg) { _client->response(_id, false, msg); } - SharedPtr client() { return _client; } + SharedPtr client() { return _client; } private: - SharedPtr _client; + SharedPtr _client; int32_t _id; }; diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp index d9481786..1d54aef6 100644 --- a/src/libs/engine/Engine.cpp +++ b/src/libs/engine/Engine.cpp @@ -111,12 +111,11 @@ Engine::main() } cout << "[Main] Done main loop." << endl; + _event_source->deactivate(); + if (_activated) deactivate(); - sleep(1); - cout << "[Main] Exiting..." << endl; - return 0; } @@ -148,17 +147,24 @@ Engine::start_jack_driver() void -Engine::start_osc_driver(const std::string& port) +Engine::start_osc_driver(int port) { _event_source = SharedPtr(new OSCEngineReceiver( - *this, pre_processor_queue_size, port.c_str())); + *this, pre_processor_queue_size, port)); } -void -Engine::set_event_source(SharedPtr source) +SharedPtr +Engine::new_queued_interface() { - _event_source = source; + assert(!_event_source); + + SharedPtr result(new QueuedEngineInterface( + *this, Ingen::event_queue_size, Ingen::event_queue_size)); + + _event_source = result; + + return result; } diff --git a/src/libs/engine/Engine.h b/src/libs/engine/Engine.h index e66e1125..ad4332ee 100644 --- a/src/libs/engine/Engine.h +++ b/src/libs/engine/Engine.h @@ -39,6 +39,7 @@ class EventSource; class PostProcessor; class Event; class QueuedEvent; +class QueuedEngineInterface; class LashDriver; class Driver; @@ -64,8 +65,9 @@ public: virtual void quit() { _quit_flag = true; } virtual void start_jack_driver(); - virtual void start_osc_driver(const std::string& port); - virtual void set_event_source(SharedPtr source); + virtual void start_osc_driver(int port); + + virtual SharedPtr new_queued_interface(); virtual bool activate(); virtual void deactivate(); diff --git a/src/libs/engine/Event.h b/src/libs/engine/Event.h index 9fd398e2..01b14abc 100644 --- a/src/libs/engine/Event.h +++ b/src/libs/engine/Event.h @@ -20,14 +20,16 @@ #include #include -#include "types.h" #include -#include "Responder.h" +#include "interface/Responder.h" +#include "types.h" #include "ThreadManager.h" namespace Raul { class Path; } using Raul::Path; +using Ingen::Shared::Responder; + namespace Ingen { class Engine; @@ -73,17 +75,17 @@ public: inline SampleCount time() { return _time; } protected: - Event(Engine& engine, SharedPtr responder, FrameTime time) + Event(Engine& engine, SharedPtr responder, FrameTime time) : _engine(engine) , _responder(responder) , _time(time) , _executed(false) {} - Engine& _engine; - SharedPtr _responder; - FrameTime _time; - bool _executed; + Engine& _engine; + SharedPtr _responder; + FrameTime _time; + bool _executed; }; diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index 5529898d..d11609b9 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -31,7 +31,6 @@ libingen_engine_la_SOURCES = \ JackAudioDriver.cpp \ OSCEngineReceiver.h \ OSCEngineReceiver.cpp \ - Responder.h \ DirectResponder.h \ OSCResponder.h \ OSCResponder.cpp \ diff --git a/src/libs/engine/MidiBuffer.cpp b/src/libs/engine/MidiBuffer.cpp index 9842b28c..41feb3df 100644 --- a/src/libs/engine/MidiBuffer.cpp +++ b/src/libs/engine/MidiBuffer.cpp @@ -34,7 +34,7 @@ MidiBuffer::MidiBuffer(size_t capacity) clear(); assert(_local_state.midi == _buf); - cerr << "Creating MIDI Buffer " << _buf << ", capacity = " << _buf->capacity << endl; + //cerr << "Creating MIDI Buffer " << _buf << ", capacity = " << _buf->capacity << endl; } diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp index 763574d1..5565505b 100644 --- a/src/libs/engine/OSCClientSender.cpp +++ b/src/libs/engine/OSCClientSender.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "ObjectStore.h" #include "NodeFactory.h" #include "util.h" @@ -29,8 +30,7 @@ #include "Connection.h" #include "AudioDriver.h" #include "interface/ClientInterface.h" -#include "Responder.h" -#include +#include "interface/Responder.h" using std::cout; using std::cerr; using std::endl; namespace Ingen { diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 1d835190..260721d4 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -48,14 +48,15 @@ using Shared::ClientKey; */ -OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, const char* const port) -: EngineInterface(), - QueuedEngineInterface(engine, queue_size, queue_size), // FIXME - _port(port), +OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t port) +: QueuedEngineInterface(engine, queue_size, queue_size), // FIXME _server(NULL), _osc_responder(SharedPtr()) { - _server = lo_server_new(port, error_cb); + char port_str[6]; + snprintf(port_str, 6, "%u", port); + + _server = lo_server_new(port_str, error_cb); if (_server == NULL) { cerr << "[OSC] Could not start OSC server. Aborting." << endl; diff --git a/src/libs/engine/OSCEngineReceiver.h b/src/libs/engine/OSCEngineReceiver.h index 04448fdf..ba9d2544 100644 --- a/src/libs/engine/OSCEngineReceiver.h +++ b/src/libs/engine/OSCEngineReceiver.h @@ -20,6 +20,7 @@ #include "config.h" #include +#include #include #include #include "QueuedEngineInterface.h" @@ -61,7 +62,7 @@ inline static int name##_cb(LO_HANDLER_ARGS, void* myself)\ class OSCEngineReceiver : public QueuedEngineInterface { public: - OSCEngineReceiver(Engine& engine, size_t queue_size, const char* const port); + OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t port); ~OSCEngineReceiver(); void activate(); @@ -114,8 +115,7 @@ private: LO_HANDLER(dssi); #endif - const char* const _port; - lo_server _server; + lo_server _server; /** Cached OSC responder (for most recent incoming message) */ SharedPtr _osc_responder; diff --git a/src/libs/engine/OSCResponder.h b/src/libs/engine/OSCResponder.h index 11e5901c..41158c14 100644 --- a/src/libs/engine/OSCResponder.h +++ b/src/libs/engine/OSCResponder.h @@ -21,7 +21,7 @@ #include #include #include -#include "Responder.h" +#include "interface/Responder.h" namespace Ingen { @@ -38,7 +38,7 @@ class ClientBroadcaster; * Creation of the lo_address is deferred until needed to avoid bogging down * the receiving thread as much as possible. */ -class OSCResponder : public Responder +class OSCResponder : public Shared::Responder { public: OSCResponder(ClientBroadcaster* broadcaster, int32_t id, char* url); @@ -51,10 +51,10 @@ public: const char* url() const { return _url; } - ClientKey client_key() { return ClientKey(ClientKey::OSC_URL, _url); } + Shared::ClientKey client_key() + { return Shared::ClientKey(Shared::ClientKey::OSC_URL, _url); } - SharedPtr client(); - + SharedPtr client(); private: ClientBroadcaster* _broadcaster; diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index a81b9ee7..dad3431b 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -343,7 +343,7 @@ Patch::build_process_order() const { assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - cerr << "*********** Building process order for " << path() << endl; + //cerr << "*********** Building process order for " << path() << endl; Raul::Array* const process_order = new Raul::Array(_nodes.size(), NULL); diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp index b38692ea..8ee3851b 100644 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ b/src/libs/engine/QueuedEngineInterface.cpp @@ -26,7 +26,7 @@ namespace Ingen { QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size) : QueuedEventSource(queued_size, stamped_size) -, _responder(SharedPtr(new Responder())) // NULL responder +, _responder(SharedPtr(new Shared::Responder())) // NULL responder , _engine(engine) { } @@ -47,7 +47,7 @@ QueuedEngineInterface::now() const * Ownership of @a responder is taken. */ void -QueuedEngineInterface::set_responder(SharedPtr responder) +QueuedEngineInterface::set_responder(SharedPtr responder) { _responder = responder; } @@ -64,7 +64,7 @@ QueuedEngineInterface::set_next_response_id(int32_t id) void QueuedEngineInterface::disable_responses() { - static SharedPtr null_responder(new Responder()); + static SharedPtr null_responder(new Shared::Responder()); //cerr << "DISABLE\n"; set_responder(null_responder); } @@ -93,7 +93,6 @@ void QueuedEngineInterface::load_plugins() { push_queued(new LoadPluginsEvent(_engine, _responder, now())); - } diff --git a/src/libs/engine/QueuedEngineInterface.h b/src/libs/engine/QueuedEngineInterface.h index ddf293dc..0d2ba5d9 100644 --- a/src/libs/engine/QueuedEngineInterface.h +++ b/src/libs/engine/QueuedEngineInterface.h @@ -25,9 +25,9 @@ #include "interface/EngineInterface.h" #include "interface/ClientInterface.h" #include "interface/ClientKey.h" +#include "interface/Responder.h" #include "QueuedEventSource.h" #include "Engine.h" -#include "Responder.h" using std::string; namespace Ingen { @@ -58,7 +58,7 @@ class Engine; * events and get pushed directly into the realtime event queue. Should that * be separated into a different interface/client? */ -class QueuedEngineInterface : public QueuedEventSource, public virtual EngineInterface +class QueuedEngineInterface : public QueuedEventSource, public EngineInterface { public: QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size); @@ -66,7 +66,7 @@ public: void set_next_response_id(int32_t id); - virtual void set_responder(SharedPtr responder); + virtual void set_responder(SharedPtr responder); virtual void disable_responses(); // Client registration @@ -156,7 +156,7 @@ public: protected: /** Where responses to current messages will go. */ - SharedPtr _responder; + SharedPtr _responder; Engine& _engine; diff --git a/src/libs/engine/QueuedEvent.h b/src/libs/engine/QueuedEvent.h index ab987c13..f1b82735 100644 --- a/src/libs/engine/QueuedEvent.h +++ b/src/libs/engine/QueuedEvent.h @@ -22,7 +22,6 @@ namespace Ingen { -class Responder; class QueuedEventSource; @@ -71,11 +70,11 @@ public: bool is_prepared() { return _pre_processed; } protected: - QueuedEvent(Engine& engine, - SharedPtr responder, - FrameTime time, - bool blocking = false, - QueuedEventSource* source = NULL) + QueuedEvent(Engine& engine, + SharedPtr responder, + FrameTime time, + bool blocking = false, + QueuedEventSource* source = NULL) : Event(engine, responder, time) , _pre_processed(false), _blocking(blocking), _source(source) { @@ -85,7 +84,7 @@ protected: // NULL event base (for internal events only!) QueuedEvent(Engine& engine) - : Event(engine, SharedPtr(), 0) + : Event(engine, SharedPtr(), 0) , _pre_processed(false), _blocking(false), _source(NULL) {} diff --git a/src/libs/engine/Responder.h b/src/libs/engine/Responder.h deleted file mode 100644 index f111b02a..00000000 --- a/src/libs/engine/Responder.h +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RESPONDER_H -#define RESPONDER_H - -#include -#include -#include -#include "interface/ClientKey.h" -#include "interface/ClientInterface.h" -using std::string; - -namespace Ingen { - -using Shared::ClientKey; -using Shared::ClientInterface; - - -/** Class to handle responding to clients. - * - * This is an abstract base class to fully abstract the details of client - * communication from the internals of the engine. - * - * Note that this class only handles sending responses to commands from - * clients, (ie OK or an error), not notifications (ie new node, - * disconnection) - that's what ClientInterface is for. If a command is - * a request, the ClientKey of the Responder can be used to find the - * ClientInterface which should receive the response. - * - * ClientInterface and Responder are seperate because responding might not - * actually get exposed to the client interface (eg in simulated blocking - * interfaces that wait for responses before returning). - * - * Note for messages that have a "response" and some broadcasted effect - * (eg setting a port value) the "response" MUST be sent first since Responder - * is responsible for controlling whether the client wishes to receive the - * notification. - */ -class Responder -{ -public: - Responder() {} - virtual ~Responder() {} - - virtual ClientKey client_key() { return ClientKey(); } - virtual SharedPtr client() { return SharedPtr(); } - - virtual void set_id(int32_t id) {} - - virtual void respond_ok() {} - virtual void respond_error(const string& msg) {} -}; - - -} // namespace Ingen - -#endif // RESPONDER_H - diff --git a/src/libs/engine/engine.cpp b/src/libs/engine/engine.cpp index a2ba26da..bb482e47 100644 --- a/src/libs/engine/engine.cpp +++ b/src/libs/engine/engine.cpp @@ -15,28 +15,74 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "engine.h" #include "Engine.h" #include "QueuedEngineInterface.h" #include "tuning.h" +#include "util.h" namespace Ingen { +/* +void +catch_int(int) +{ + signal(SIGINT, catch_int); + signal(SIGTERM, catch_int); + + std::cout << "[Main] Ingen interrupted." << std::endl; + engine->quit(); +} +*/ Engine* new_engine() { + set_denormal_flags(); return new Engine(); } -QueuedEngineInterface* -new_queued_engine_interface(Engine& engine) +bool +launch_osc_engine(int port) { - return new QueuedEngineInterface(engine, - Ingen::event_queue_size, Ingen::event_queue_size); + char port_str[6]; + snprintf(port_str, 6, "%u", port); + const string cmd = string("ingen -e --engine-port=").append(port_str); + + if (Raul::Process::launch(cmd)) { + return true; + //return SharedPtr(new OSCEngineSender( + // string("osc.udp://localhost:").append(port_str))); + } else { + cerr << "Failed to launch engine process." << endl; + //return SharedPtr(); + return false; + } } +/* +void +run(int port) +{ + signal(SIGINT, catch_int); + signal(SIGTERM, catch_int); + + set_denormal_flags(); + + Engine* engine = new_engine(); + + engine->start_jack_driver(); + engine->start_osc_driver(port); + + engine->activate(); + + engine->main(); + + delete engine; +} +*/ } // namespace Ingen diff --git a/src/libs/engine/engine.h b/src/libs/engine/engine.h index aac69661..588ab047 100644 --- a/src/libs/engine/engine.h +++ b/src/libs/engine/engine.h @@ -21,13 +21,20 @@ namespace Ingen { class Engine; -class QueuedEngineInterface; +namespace Shared { class EngineInterface; } extern "C" { - extern Engine* new_engine(); - extern QueuedEngineInterface* new_queued_interface(Engine& engine); + //void run(int argc, char** argv); + + /** Create a new engine in this process */ + Engine* new_engine(); + + /** Launch an OSC engine as a completely separate process + * \return true if successful + */ + bool launch_osc_engine(int port); } diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp index 88efbb45..1ea2b596 100644 --- a/src/libs/engine/events/AddNodeEvent.cpp +++ b/src/libs/engine/events/AddNodeEvent.cpp @@ -16,7 +16,7 @@ */ #include "AddNodeEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Patch.h" #include "Node.h" #include "Tree.h" @@ -34,7 +34,7 @@ namespace Ingen { -AddNodeEvent::AddNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, +AddNodeEvent::AddNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& plugin_uri, bool poly) : QueuedEvent(engine, responder, timestamp), _path(path), @@ -52,7 +52,7 @@ AddNodeEvent::AddNodeEvent(Engine& engine, SharedPtr responder, Sampl * * Do not use. */ -AddNodeEvent::AddNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, +AddNodeEvent::AddNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& plugin_type, const string& plugin_lib, const string& plugin_label, bool poly) : QueuedEvent(engine, responder, timestamp), _path(path), diff --git a/src/libs/engine/events/AddNodeEvent.h b/src/libs/engine/events/AddNodeEvent.h index 7a88cd1c..68d518ae 100644 --- a/src/libs/engine/events/AddNodeEvent.h +++ b/src/libs/engine/events/AddNodeEvent.h @@ -41,7 +41,7 @@ class AddNodeEvent : public QueuedEvent { public: AddNodeEvent(Engine& engine, - SharedPtr responder, + SharedPtr responder, SampleCount timestamp, const string& node_path, const string& plugin_uri, @@ -49,7 +49,7 @@ public: // DEPRECATED AddNodeEvent(Engine& engine, - SharedPtr responder, + SharedPtr responder, SampleCount timestamp, const string& node_path, const string& plugin_type, diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp index 1157d06a..b1925b07 100644 --- a/src/libs/engine/events/AddPortEvent.cpp +++ b/src/libs/engine/events/AddPortEvent.cpp @@ -16,7 +16,7 @@ */ #include "AddPortEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Patch.h" #include "Tree.h" #include "Plugin.h" @@ -40,7 +40,7 @@ namespace Ingen { AddPortEvent::AddPortEvent(Engine& engine, - SharedPtr responder, + SharedPtr responder, SampleCount timestamp, const string& path, const string& type, diff --git a/src/libs/engine/events/AddPortEvent.h b/src/libs/engine/events/AddPortEvent.h index 84302029..ed382286 100644 --- a/src/libs/engine/events/AddPortEvent.h +++ b/src/libs/engine/events/AddPortEvent.h @@ -42,7 +42,7 @@ class DriverPort; class AddPortEvent : public QueuedEvent { public: - AddPortEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source); + AddPortEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/AllNotesOffEvent.cpp b/src/libs/engine/events/AllNotesOffEvent.cpp index 6c87e52a..1b7a40e1 100644 --- a/src/libs/engine/events/AllNotesOffEvent.cpp +++ b/src/libs/engine/events/AllNotesOffEvent.cpp @@ -16,7 +16,7 @@ */ #include "AllNotesOffEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ObjectStore.h" @@ -25,7 +25,7 @@ namespace Ingen { /** Note off with patch explicitly passed - triggered by MIDI. */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Patch* patch) +AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Patch* patch) : Event(engine, responder, timestamp), _patch(patch) { @@ -34,7 +34,7 @@ AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responde /** Note off event with lookup - triggered by OSC. */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path) +AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path) : Event(engine, responder, timestamp), _patch(NULL), _patch_path(patch_path) diff --git a/src/libs/engine/events/AllNotesOffEvent.h b/src/libs/engine/events/AllNotesOffEvent.h index c4a0d3c2..299e9760 100644 --- a/src/libs/engine/events/AllNotesOffEvent.h +++ b/src/libs/engine/events/AllNotesOffEvent.h @@ -34,8 +34,8 @@ class Patch; class AllNotesOffEvent : public Event { public: - AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Patch* patch); - AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path); + AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Patch* patch); + AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path); void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp index e07ceb5c..44a23267 100644 --- a/src/libs/engine/events/ClearPatchEvent.cpp +++ b/src/libs/engine/events/ClearPatchEvent.cpp @@ -16,7 +16,7 @@ */ #include "ClearPatchEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Patch.h" #include "ClientBroadcaster.h" @@ -31,7 +31,7 @@ namespace Ingen { -ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const string& patch_path) +ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const string& patch_path) : QueuedEvent(engine, responder, time, true, source), _patch_path(patch_path), _patch(NULL), diff --git a/src/libs/engine/events/ClearPatchEvent.h b/src/libs/engine/events/ClearPatchEvent.h index c3570518..21b227ca 100644 --- a/src/libs/engine/events/ClearPatchEvent.h +++ b/src/libs/engine/events/ClearPatchEvent.h @@ -36,7 +36,7 @@ class Patch; class ClearPatchEvent : public QueuedEvent { public: - ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const string& patch_path); + ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const string& patch_path); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp index 7c4b4422..dc4033cc 100644 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ b/src/libs/engine/events/ConnectionEvent.cpp @@ -19,7 +19,7 @@ #include #include #include -#include "Responder.h" +#include "interface/Responder.h" #include "types.h" #include "Engine.h" #include "Connection.h" @@ -34,7 +34,7 @@ using std::string; namespace Ingen { -ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) +ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) : QueuedEvent(engine, responder, timestamp), _src_port_path(src_port_path), _dst_port_path(dst_port_path), diff --git a/src/libs/engine/events/ConnectionEvent.h b/src/libs/engine/events/ConnectionEvent.h index 9565d79f..d294657b 100644 --- a/src/libs/engine/events/ConnectionEvent.h +++ b/src/libs/engine/events/ConnectionEvent.h @@ -48,7 +48,7 @@ class OutputPort; class ConnectionEvent : public QueuedEvent { public: - ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); + ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp index 81d05368..f42b895e 100644 --- a/src/libs/engine/events/CreatePatchEvent.cpp +++ b/src/libs/engine/events/CreatePatchEvent.cpp @@ -16,7 +16,7 @@ */ #include "CreatePatchEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Patch.h" #include "Node.h" #include "Tree.h" @@ -31,7 +31,7 @@ namespace Ingen { -CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, int poly) +CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, int poly) : QueuedEvent(engine, responder, timestamp), _path(path), _patch(NULL), diff --git a/src/libs/engine/events/CreatePatchEvent.h b/src/libs/engine/events/CreatePatchEvent.h index dd492a33..c63fd566 100644 --- a/src/libs/engine/events/CreatePatchEvent.h +++ b/src/libs/engine/events/CreatePatchEvent.h @@ -41,7 +41,7 @@ class Plugin; class CreatePatchEvent : public QueuedEvent { public: - CreatePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, int poly); + CreatePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, int poly); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/DSSIConfigureEvent.cpp b/src/libs/engine/events/DSSIConfigureEvent.cpp index d3847eb0..4f388558 100644 --- a/src/libs/engine/events/DSSIConfigureEvent.cpp +++ b/src/libs/engine/events/DSSIConfigureEvent.cpp @@ -25,7 +25,7 @@ namespace Ingen { -DSSIConfigureEvent::DSSIConfigureEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, const string& key, const string& val) +DSSIConfigureEvent::DSSIConfigureEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, const string& key, const string& val) : QueuedEvent(engine, responder, timestamp), _node_path(node_path), _key(key), diff --git a/src/libs/engine/events/DSSIConfigureEvent.h b/src/libs/engine/events/DSSIConfigureEvent.h index f19c51b6..944f6239 100644 --- a/src/libs/engine/events/DSSIConfigureEvent.h +++ b/src/libs/engine/events/DSSIConfigureEvent.h @@ -31,7 +31,7 @@ namespace Ingen { class DSSIConfigureEvent : public QueuedEvent { public: - DSSIConfigureEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, const string& key, const string& val); + DSSIConfigureEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, const string& key, const string& val); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/DSSIControlEvent.cpp b/src/libs/engine/events/DSSIControlEvent.cpp index 2a6caab6..94f504a7 100644 --- a/src/libs/engine/events/DSSIControlEvent.cpp +++ b/src/libs/engine/events/DSSIControlEvent.cpp @@ -24,7 +24,7 @@ namespace Ingen { -DSSIControlEvent::DSSIControlEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int port_num, Sample val) +DSSIControlEvent::DSSIControlEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int port_num, Sample val) : QueuedEvent(engine, responder, timestamp), _node_path(node_path), _port_num(port_num), diff --git a/src/libs/engine/events/DSSIControlEvent.h b/src/libs/engine/events/DSSIControlEvent.h index 97d1c213..e6800bb2 100644 --- a/src/libs/engine/events/DSSIControlEvent.h +++ b/src/libs/engine/events/DSSIControlEvent.h @@ -33,7 +33,7 @@ namespace Ingen { class DSSIControlEvent : public QueuedEvent { public: - DSSIControlEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int port_num, Sample val); + DSSIControlEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int port_num, Sample val); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/DSSIProgramEvent.cpp b/src/libs/engine/events/DSSIProgramEvent.cpp index 48195cb9..436ab2c6 100644 --- a/src/libs/engine/events/DSSIProgramEvent.cpp +++ b/src/libs/engine/events/DSSIProgramEvent.cpp @@ -29,7 +29,7 @@ using std::cout; using std::cerr; using std::endl; namespace Ingen { -DSSIProgramEvent::DSSIProgramEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int bank, int program) +DSSIProgramEvent::DSSIProgramEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int bank, int program) : QueuedEvent(engine, responder, timestamp), _node_path(node_path), _bank(bank), diff --git a/src/libs/engine/events/DSSIProgramEvent.h b/src/libs/engine/events/DSSIProgramEvent.h index 91946173..8acdea81 100644 --- a/src/libs/engine/events/DSSIProgramEvent.h +++ b/src/libs/engine/events/DSSIProgramEvent.h @@ -31,7 +31,7 @@ namespace Ingen { class DSSIProgramEvent : public QueuedEvent { public: - DSSIProgramEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int bank, int program); + DSSIProgramEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, int bank, int program); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/DSSIUpdateEvent.cpp b/src/libs/engine/events/DSSIUpdateEvent.cpp index e3a73260..5851e065 100644 --- a/src/libs/engine/events/DSSIUpdateEvent.cpp +++ b/src/libs/engine/events/DSSIUpdateEvent.cpp @@ -28,7 +28,7 @@ using std::cerr; using std::endl; namespace Ingen { -DSSIUpdateEvent::DSSIUpdateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& url) +DSSIUpdateEvent::DSSIUpdateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& url) : QueuedEvent(engine, responder, timestamp), _path(path), _url(url), diff --git a/src/libs/engine/events/DSSIUpdateEvent.h b/src/libs/engine/events/DSSIUpdateEvent.h index 3db562cb..8274bb71 100644 --- a/src/libs/engine/events/DSSIUpdateEvent.h +++ b/src/libs/engine/events/DSSIUpdateEvent.h @@ -37,7 +37,7 @@ class DSSINode; class DSSIUpdateEvent : public QueuedEvent { public: - DSSIUpdateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& url); + DSSIUpdateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& url); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/DeactivateEvent.cpp b/src/libs/engine/events/DeactivateEvent.cpp index e93ec800..e6440570 100644 --- a/src/libs/engine/events/DeactivateEvent.cpp +++ b/src/libs/engine/events/DeactivateEvent.cpp @@ -16,13 +16,13 @@ */ #include "DeactivateEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" namespace Ingen { -DeactivateEvent::DeactivateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) +DeactivateEvent::DeactivateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) { } diff --git a/src/libs/engine/events/DeactivateEvent.h b/src/libs/engine/events/DeactivateEvent.h index 82990b54..92276918 100644 --- a/src/libs/engine/events/DeactivateEvent.h +++ b/src/libs/engine/events/DeactivateEvent.h @@ -30,7 +30,7 @@ namespace Ingen { class DeactivateEvent : public QueuedEvent { public: - DeactivateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); + DeactivateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp index c00306d8..ecccaa8a 100644 --- a/src/libs/engine/events/DestroyEvent.cpp +++ b/src/libs/engine/events/DestroyEvent.cpp @@ -16,7 +16,7 @@ */ #include "DestroyEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Patch.h" #include "Tree.h" @@ -37,7 +37,7 @@ namespace Ingen { -DestroyEvent::DestroyEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const string& path, bool block) +DestroyEvent::DestroyEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const string& path, bool block) : QueuedEvent(engine, responder, time, source, source), _path(path), _object(NULL), @@ -56,7 +56,7 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr responder, Frame } -DestroyEvent::DestroyEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, Node* node, bool block) +DestroyEvent::DestroyEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, Node* node, bool block) : QueuedEvent(engine, responder, block, source), _path(node->path()), _object(node), diff --git a/src/libs/engine/events/DestroyEvent.h b/src/libs/engine/events/DestroyEvent.h index 435736aa..421a2dcd 100644 --- a/src/libs/engine/events/DestroyEvent.h +++ b/src/libs/engine/events/DestroyEvent.h @@ -50,8 +50,8 @@ class DisconnectPortEvent; class DestroyEvent : public QueuedEvent { public: - DestroyEvent(Engine& engine, SharedPtr responder, FrameTime timestamp, QueuedEventSource* source, const string& path, bool block = true); - DestroyEvent(Engine& engine, SharedPtr responder, FrameTime timestamp, QueuedEventSource* source, Node* node, bool block = true); + DestroyEvent(Engine& engine, SharedPtr responder, FrameTime timestamp, QueuedEventSource* source, const string& path, bool block = true); + DestroyEvent(Engine& engine, SharedPtr responder, FrameTime timestamp, QueuedEventSource* source, Node* node, bool block = true); ~DestroyEvent(); void pre_process(); diff --git a/src/libs/engine/events/DisablePatchEvent.cpp b/src/libs/engine/events/DisablePatchEvent.cpp index fa032528..ce78cf7e 100644 --- a/src/libs/engine/events/DisablePatchEvent.cpp +++ b/src/libs/engine/events/DisablePatchEvent.cpp @@ -16,7 +16,7 @@ */ #include "DisablePatchEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Patch.h" #include "ClientBroadcaster.h" @@ -27,7 +27,7 @@ namespace Ingen { -DisablePatchEvent::DisablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path) +DisablePatchEvent::DisablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path) : QueuedEvent(engine, responder, timestamp), _patch_path(patch_path), _patch(NULL) diff --git a/src/libs/engine/events/DisablePatchEvent.h b/src/libs/engine/events/DisablePatchEvent.h index 8e6be5ea..1999ece0 100644 --- a/src/libs/engine/events/DisablePatchEvent.h +++ b/src/libs/engine/events/DisablePatchEvent.h @@ -35,7 +35,7 @@ class Patch; class DisablePatchEvent : public QueuedEvent { public: - DisablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path); + DisablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/DisconnectNodeEvent.cpp b/src/libs/engine/events/DisconnectNodeEvent.cpp index f304f0b1..bc97dff4 100644 --- a/src/libs/engine/events/DisconnectNodeEvent.cpp +++ b/src/libs/engine/events/DisconnectNodeEvent.cpp @@ -20,7 +20,7 @@ #include #include #include -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Node.h" #include "Connection.h" @@ -39,7 +39,7 @@ using std::cerr; using std::endl; namespace Ingen { -DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path) +DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path) : QueuedEvent(engine, responder, timestamp), _node_path(node_path), _patch(NULL), @@ -99,7 +99,7 @@ DisconnectNodeEvent::pre_process() for (ConnectionListIterator i = _patch->connections().begin(); i != _patch->connections().end(); ++i) { c = (*i); if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, SharedPtr(new Responder()), _time, + DisconnectionEvent* ev = new DisconnectionEvent(_engine, SharedPtr(new Responder()), _time, c->src_port(), c->dst_port()); ev->pre_process(); _disconnection_events.push_back(new Raul::ListNode(ev)); diff --git a/src/libs/engine/events/DisconnectNodeEvent.h b/src/libs/engine/events/DisconnectNodeEvent.h index 270fa960..a70f9e8c 100644 --- a/src/libs/engine/events/DisconnectNodeEvent.h +++ b/src/libs/engine/events/DisconnectNodeEvent.h @@ -43,7 +43,7 @@ class OutputPort; class DisconnectNodeEvent : public QueuedEvent { public: - DisconnectNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path); + DisconnectNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path); DisconnectNodeEvent(Engine& engine, Node* node); ~DisconnectNodeEvent(); diff --git a/src/libs/engine/events/DisconnectPortEvent.cpp b/src/libs/engine/events/DisconnectPortEvent.cpp index 08266de6..1373d9b8 100644 --- a/src/libs/engine/events/DisconnectPortEvent.cpp +++ b/src/libs/engine/events/DisconnectPortEvent.cpp @@ -20,7 +20,7 @@ #include #include #include -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Node.h" #include "Connection.h" @@ -39,7 +39,7 @@ using std::cerr; using std::endl; namespace Ingen { -DisconnectPortEvent::DisconnectPortEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path) +DisconnectPortEvent::DisconnectPortEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path) : QueuedEvent(engine, responder, timestamp), _port_path(port_path), _patch(NULL), @@ -104,7 +104,7 @@ DisconnectPortEvent::pre_process() for (Raul::List::const_iterator i = _patch->connections().begin(); i != _patch->connections().end(); ++i) { c = (*i); if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, SharedPtr(new Responder()), _time, + DisconnectionEvent* ev = new DisconnectionEvent(_engine, SharedPtr(new Responder()), _time, c->src_port(), c->dst_port()); ev->pre_process(); _disconnection_events.push_back(new Raul::ListNode(ev)); diff --git a/src/libs/engine/events/DisconnectPortEvent.h b/src/libs/engine/events/DisconnectPortEvent.h index 089508ea..647ee1da 100644 --- a/src/libs/engine/events/DisconnectPortEvent.h +++ b/src/libs/engine/events/DisconnectPortEvent.h @@ -44,7 +44,7 @@ using std::string; class DisconnectPortEvent : public QueuedEvent { public: - DisconnectPortEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path); + DisconnectPortEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path); DisconnectPortEvent(Engine& engine, Port* port); ~DisconnectPortEvent(); diff --git a/src/libs/engine/events/DisconnectionEvent.cpp b/src/libs/engine/events/DisconnectionEvent.cpp index 7ac7e236..2fafb98e 100644 --- a/src/libs/engine/events/DisconnectionEvent.cpp +++ b/src/libs/engine/events/DisconnectionEvent.cpp @@ -19,7 +19,7 @@ #include #include #include -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Connection.h" #include "InputPort.h" @@ -36,7 +36,7 @@ namespace Ingen { //// DisconnectionEvent //// -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) +DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) : QueuedEvent(engine, responder, timestamp), _src_port_path(src_port_path), _dst_port_path(dst_port_path), @@ -50,7 +50,7 @@ DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr resp } -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Port* const src_port, Port* const dst_port) +DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Port* const src_port, Port* const dst_port) : QueuedEvent(engine, responder, timestamp), _src_port_path(src_port->path()), _dst_port_path(dst_port->path()), diff --git a/src/libs/engine/events/DisconnectionEvent.h b/src/libs/engine/events/DisconnectionEvent.h index 3faeb23e..23f1526e 100644 --- a/src/libs/engine/events/DisconnectionEvent.h +++ b/src/libs/engine/events/DisconnectionEvent.h @@ -48,8 +48,8 @@ class OutputPort; class DisconnectionEvent : public QueuedEvent { public: - DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); - DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Port* const src_port, Port* const dst_port); + DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); + DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Port* const src_port, Port* const dst_port); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/EnablePatchEvent.cpp b/src/libs/engine/events/EnablePatchEvent.cpp index f1970f4d..74d4a52b 100644 --- a/src/libs/engine/events/EnablePatchEvent.cpp +++ b/src/libs/engine/events/EnablePatchEvent.cpp @@ -16,7 +16,7 @@ */ #include "EnablePatchEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Patch.h" #include "util.h" @@ -26,7 +26,7 @@ namespace Ingen { -EnablePatchEvent::EnablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path) +EnablePatchEvent::EnablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path) : QueuedEvent(engine, responder, timestamp), _patch_path(patch_path), _patch(NULL), diff --git a/src/libs/engine/events/EnablePatchEvent.h b/src/libs/engine/events/EnablePatchEvent.h index 350c9f3e..c63c9db3 100644 --- a/src/libs/engine/events/EnablePatchEvent.h +++ b/src/libs/engine/events/EnablePatchEvent.h @@ -38,7 +38,7 @@ class Node; class EnablePatchEvent : public QueuedEvent { public: - EnablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path); + EnablePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& patch_path); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/LashRestoreDoneEvent.h b/src/libs/engine/events/LashRestoreDoneEvent.h index 8e45cb6b..fd33d813 100644 --- a/src/libs/engine/events/LashRestoreDoneEvent.h +++ b/src/libs/engine/events/LashRestoreDoneEvent.h @@ -40,7 +40,7 @@ class Port; class LashRestoreDoneEvent : public QueuedEvent { public: - LashRestoreDoneEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) {} + LashRestoreDoneEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) {} void post_process() { diff --git a/src/libs/engine/events/LoadPluginsEvent.cpp b/src/libs/engine/events/LoadPluginsEvent.cpp index 78461ff5..a126e3b2 100644 --- a/src/libs/engine/events/LoadPluginsEvent.cpp +++ b/src/libs/engine/events/LoadPluginsEvent.cpp @@ -16,7 +16,7 @@ */ #include "LoadPluginsEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "NodeFactory.h" #include "ClientBroadcaster.h" @@ -27,7 +27,7 @@ using std::cerr; namespace Ingen { -LoadPluginsEvent::LoadPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) +LoadPluginsEvent::LoadPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) { } diff --git a/src/libs/engine/events/LoadPluginsEvent.h b/src/libs/engine/events/LoadPluginsEvent.h index 296904e6..b6de5e5c 100644 --- a/src/libs/engine/events/LoadPluginsEvent.h +++ b/src/libs/engine/events/LoadPluginsEvent.h @@ -33,7 +33,7 @@ class Plugin; class LoadPluginsEvent : public QueuedEvent { public: - LoadPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); + LoadPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/MidiLearnEvent.cpp b/src/libs/engine/events/MidiLearnEvent.cpp index d00a0a9f..6204ed4a 100644 --- a/src/libs/engine/events/MidiLearnEvent.cpp +++ b/src/libs/engine/events/MidiLearnEvent.cpp @@ -16,7 +16,7 @@ */ #include "MidiLearnEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ObjectStore.h" #include "Node.h" @@ -38,7 +38,7 @@ MidiLearnResponseEvent::post_process() // MidiLearnEvent -MidiLearnEvent::MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path) +MidiLearnEvent::MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path) : QueuedEvent(engine, responder, timestamp), _node_path(node_path), _node(NULL), diff --git a/src/libs/engine/events/MidiLearnEvent.h b/src/libs/engine/events/MidiLearnEvent.h index ba11aadb..d28413c7 100644 --- a/src/libs/engine/events/MidiLearnEvent.h +++ b/src/libs/engine/events/MidiLearnEvent.h @@ -39,7 +39,7 @@ class MidiLearnResponseEvent : public Event { public: MidiLearnResponseEvent(Engine& engine, const string& port_path, SampleCount timestamp) - : Event(engine, SharedPtr(), timestamp), + : Event(engine, SharedPtr(), timestamp), _port_path(port_path), _value(0.0f) {} @@ -65,7 +65,7 @@ private: class MidiLearnEvent : public QueuedEvent { public: - MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path); + MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/NoteOffEvent.cpp b/src/libs/engine/events/NoteOffEvent.cpp index cd780bb2..cb081534 100644 --- a/src/libs/engine/events/NoteOffEvent.cpp +++ b/src/libs/engine/events/NoteOffEvent.cpp @@ -16,7 +16,7 @@ */ #include "NoteOffEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ObjectStore.h" #include "Node.h" @@ -28,7 +28,7 @@ namespace Ingen { /** Note off with patch explicitly passed - triggered by MIDI. */ -NoteOffEvent::NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* node, uchar note_num) +NoteOffEvent::NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* node, uchar note_num) : Event(engine, responder, timestamp), _node(node), _note_num(note_num) @@ -38,7 +38,7 @@ NoteOffEvent::NoteOffEvent(Engine& engine, SharedPtr responder, Sampl /** Note off event with lookup - triggered by OSC. */ -NoteOffEvent::NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num) +NoteOffEvent::NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num) : Event(engine, responder, timestamp), _node(NULL), _node_path(node_path), diff --git a/src/libs/engine/events/NoteOffEvent.h b/src/libs/engine/events/NoteOffEvent.h index a8a85c29..423ddcdc 100644 --- a/src/libs/engine/events/NoteOffEvent.h +++ b/src/libs/engine/events/NoteOffEvent.h @@ -35,8 +35,8 @@ class Node; class NoteOffEvent : public Event { public: - NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* node, uchar note_num); - NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num); + NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* node, uchar note_num); + NoteOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num); void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); diff --git a/src/libs/engine/events/NoteOnEvent.cpp b/src/libs/engine/events/NoteOnEvent.cpp index 84482c0f..313dbccd 100644 --- a/src/libs/engine/events/NoteOnEvent.cpp +++ b/src/libs/engine/events/NoteOnEvent.cpp @@ -16,7 +16,7 @@ */ #include "NoteOnEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ObjectStore.h" #include "Node.h" @@ -31,7 +31,7 @@ namespace Ingen { * * Used to be triggered by MIDI. Not used anymore. */ -NoteOnEvent::NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity) +NoteOnEvent::NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity) : Event(engine, responder, timestamp), _node(patch), _note_num(note_num), @@ -45,7 +45,7 @@ NoteOnEvent::NoteOnEvent(Engine& engine, SharedPtr responder, SampleC * * Triggered by OSC. */ -NoteOnEvent::NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity) +NoteOnEvent::NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity) : Event(engine, responder, timestamp), _node(NULL), _node_path(node_path), diff --git a/src/libs/engine/events/NoteOnEvent.h b/src/libs/engine/events/NoteOnEvent.h index 12aea963..a3ee4210 100644 --- a/src/libs/engine/events/NoteOnEvent.h +++ b/src/libs/engine/events/NoteOnEvent.h @@ -35,8 +35,8 @@ class Node; class NoteOnEvent : public Event { public: - NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity); - NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity); + NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity); + NoteOnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity); void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); diff --git a/src/libs/engine/events/PingQueuedEvent.h b/src/libs/engine/events/PingQueuedEvent.h index 621fea27..3d331ccf 100644 --- a/src/libs/engine/events/PingQueuedEvent.h +++ b/src/libs/engine/events/PingQueuedEvent.h @@ -20,7 +20,7 @@ #include "QueuedEvent.h" #include "types.h" -#include "Responder.h" +#include "interface/Responder.h" namespace Ingen { @@ -35,7 +35,9 @@ class Port; class PingQueuedEvent : public QueuedEvent { public: - PingQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) {} + PingQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) + : QueuedEvent(engine, responder, timestamp) + {} void post_process() { _responder->respond_ok(); } }; diff --git a/src/libs/engine/events/RegisterClientEvent.cpp b/src/libs/engine/events/RegisterClientEvent.cpp index 0144ed97..3ba36cc7 100644 --- a/src/libs/engine/events/RegisterClientEvent.cpp +++ b/src/libs/engine/events/RegisterClientEvent.cpp @@ -15,15 +15,15 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "interface/Responder.h" #include "RegisterClientEvent.h" -#include "Responder.h" #include "Engine.h" #include "ClientBroadcaster.h" namespace Ingen { -RegisterClientEvent::RegisterClientEvent(Engine& engine, SharedPtr responder, +RegisterClientEvent::RegisterClientEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, ClientKey key, SharedPtr client) diff --git a/src/libs/engine/events/RegisterClientEvent.h b/src/libs/engine/events/RegisterClientEvent.h index b1dabf2a..f32093a4 100644 --- a/src/libs/engine/events/RegisterClientEvent.h +++ b/src/libs/engine/events/RegisterClientEvent.h @@ -25,6 +25,7 @@ using std::string; using Ingen::Shared::ClientInterface; using Ingen::Shared::ClientKey; +using Ingen::Shared::Responder; namespace Ingen { @@ -36,10 +37,11 @@ namespace Ingen { class RegisterClientEvent : public QueuedEvent { public: - RegisterClientEvent(Engine& engine, SharedPtr responder, - SampleCount timestamp, - ClientKey key, - SharedPtr client); + RegisterClientEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + ClientKey key, + SharedPtr client); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/RenameEvent.cpp b/src/libs/engine/events/RenameEvent.cpp index a833c42e..ac9082e6 100644 --- a/src/libs/engine/events/RenameEvent.cpp +++ b/src/libs/engine/events/RenameEvent.cpp @@ -16,7 +16,7 @@ */ #include "RenameEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Patch.h" #include "Node.h" #include "Tree.h" @@ -28,7 +28,7 @@ namespace Ingen { -RenameEvent::RenameEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& name) +RenameEvent::RenameEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& name) : QueuedEvent(engine, responder, timestamp), _old_path(path), _name(name), diff --git a/src/libs/engine/events/RenameEvent.h b/src/libs/engine/events/RenameEvent.h index 9cba840d..c0d1e538 100644 --- a/src/libs/engine/events/RenameEvent.h +++ b/src/libs/engine/events/RenameEvent.h @@ -44,7 +44,7 @@ class DisconnectPortEvent; class RenameEvent : public QueuedEvent { public: - RenameEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& name); + RenameEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& name); ~RenameEvent(); void pre_process(); diff --git a/src/libs/engine/events/RequestAllObjectsEvent.cpp b/src/libs/engine/events/RequestAllObjectsEvent.cpp index 1a2a1243..ccf5a6a1 100644 --- a/src/libs/engine/events/RequestAllObjectsEvent.cpp +++ b/src/libs/engine/events/RequestAllObjectsEvent.cpp @@ -16,7 +16,7 @@ */ #include "RequestAllObjectsEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ObjectSender.h" #include "ClientBroadcaster.h" @@ -25,7 +25,7 @@ namespace Ingen { -RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) +RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) { } diff --git a/src/libs/engine/events/RequestAllObjectsEvent.h b/src/libs/engine/events/RequestAllObjectsEvent.h index cb5eb60d..a0d10c49 100644 --- a/src/libs/engine/events/RequestAllObjectsEvent.h +++ b/src/libs/engine/events/RequestAllObjectsEvent.h @@ -36,7 +36,7 @@ namespace Shared { class RequestAllObjectsEvent : public QueuedEvent { public: - RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); + RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/RequestMetadataEvent.cpp b/src/libs/engine/events/RequestMetadataEvent.cpp index 0722a19f..b2f189f6 100644 --- a/src/libs/engine/events/RequestMetadataEvent.cpp +++ b/src/libs/engine/events/RequestMetadataEvent.cpp @@ -17,7 +17,7 @@ #include "RequestMetadataEvent.h" #include -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "GraphObject.h" #include "ObjectStore.h" @@ -28,7 +28,7 @@ using std::string; namespace Ingen { -RequestMetadataEvent::RequestMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, const string& key) +RequestMetadataEvent::RequestMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& node_path, const string& key) : QueuedEvent(engine, responder, timestamp), _path(node_path), _key(key), diff --git a/src/libs/engine/events/RequestMetadataEvent.h b/src/libs/engine/events/RequestMetadataEvent.h index 497a94bf..45592e88 100644 --- a/src/libs/engine/events/RequestMetadataEvent.h +++ b/src/libs/engine/events/RequestMetadataEvent.h @@ -38,7 +38,7 @@ namespace Shared { class RequestMetadataEvent : public QueuedEvent { public: - RequestMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& key); + RequestMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& key); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/RequestObjectEvent.cpp b/src/libs/engine/events/RequestObjectEvent.cpp index bd25f514..30ef6f85 100644 --- a/src/libs/engine/events/RequestObjectEvent.cpp +++ b/src/libs/engine/events/RequestObjectEvent.cpp @@ -18,7 +18,7 @@ #include "RequestObjectEvent.h" #include #include "interface/ClientInterface.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ObjectStore.h" #include "ClientBroadcaster.h" @@ -32,7 +32,7 @@ using std::string; namespace Ingen { -RequestObjectEvent::RequestObjectEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path) +RequestObjectEvent::RequestObjectEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path) : QueuedEvent(engine, responder, timestamp), _path(path), _object(NULL) diff --git a/src/libs/engine/events/RequestObjectEvent.h b/src/libs/engine/events/RequestObjectEvent.h index 56b11cb5..b769aee3 100644 --- a/src/libs/engine/events/RequestObjectEvent.h +++ b/src/libs/engine/events/RequestObjectEvent.h @@ -38,7 +38,7 @@ using Shared::ClientInterface; class RequestObjectEvent : public QueuedEvent { public: - RequestObjectEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path); + RequestObjectEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/RequestPluginEvent.cpp b/src/libs/engine/events/RequestPluginEvent.cpp index 64a63aea..da70cd8c 100644 --- a/src/libs/engine/events/RequestPluginEvent.cpp +++ b/src/libs/engine/events/RequestPluginEvent.cpp @@ -18,7 +18,7 @@ #include "RequestPluginEvent.h" #include #include "interface/ClientInterface.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Port.h" #include "ObjectStore.h" @@ -31,7 +31,7 @@ using std::string; namespace Ingen { -RequestPluginEvent::RequestPluginEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& uri) +RequestPluginEvent::RequestPluginEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& uri) : QueuedEvent(engine, responder, timestamp), _uri(uri), _plugin(NULL) diff --git a/src/libs/engine/events/RequestPluginEvent.h b/src/libs/engine/events/RequestPluginEvent.h index 17f1fd92..7047e2fa 100644 --- a/src/libs/engine/events/RequestPluginEvent.h +++ b/src/libs/engine/events/RequestPluginEvent.h @@ -38,7 +38,7 @@ using Shared::ClientInterface; class RequestPluginEvent : public QueuedEvent { public: - RequestPluginEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& uri); + RequestPluginEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& uri); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/RequestPluginsEvent.cpp b/src/libs/engine/events/RequestPluginsEvent.cpp index a6e470b5..1d71b6fa 100644 --- a/src/libs/engine/events/RequestPluginsEvent.cpp +++ b/src/libs/engine/events/RequestPluginsEvent.cpp @@ -16,7 +16,7 @@ */ #include "RequestPluginsEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ClientBroadcaster.h" #include "NodeFactory.h" @@ -24,7 +24,7 @@ namespace Ingen { -RequestPluginsEvent::RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) +RequestPluginsEvent::RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) { } diff --git a/src/libs/engine/events/RequestPluginsEvent.h b/src/libs/engine/events/RequestPluginsEvent.h index f43acbf5..3d795081 100644 --- a/src/libs/engine/events/RequestPluginsEvent.h +++ b/src/libs/engine/events/RequestPluginsEvent.h @@ -26,7 +26,7 @@ using std::string; namespace Ingen { class Plugin; -class Responder; +class Shared::Responder; namespace Shared { class ClientInterface; } using Shared::ClientInterface; @@ -39,7 +39,7 @@ namespace Shared { class RequestPluginsEvent : public QueuedEvent { public: - RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); + RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/RequestPortValueEvent.cpp b/src/libs/engine/events/RequestPortValueEvent.cpp index 533cac38..79a7093a 100644 --- a/src/libs/engine/events/RequestPortValueEvent.cpp +++ b/src/libs/engine/events/RequestPortValueEvent.cpp @@ -18,7 +18,7 @@ #include "RequestPortValueEvent.h" #include #include "interface/ClientInterface.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Port.h" #include "ObjectStore.h" @@ -30,7 +30,7 @@ using std::string; namespace Ingen { -RequestPortValueEvent::RequestPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path) +RequestPortValueEvent::RequestPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path) : QueuedEvent(engine, responder, timestamp), _port_path(port_path), _port(NULL), diff --git a/src/libs/engine/events/RequestPortValueEvent.h b/src/libs/engine/events/RequestPortValueEvent.h index 32b56691..87a6373c 100644 --- a/src/libs/engine/events/RequestPortValueEvent.h +++ b/src/libs/engine/events/RequestPortValueEvent.h @@ -38,7 +38,7 @@ using Shared::ClientInterface; class RequestPortValueEvent : public QueuedEvent { public: - RequestPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path); + RequestPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/SetMetadataEvent.cpp b/src/libs/engine/events/SetMetadataEvent.cpp index 63f28eb7..6d303915 100644 --- a/src/libs/engine/events/SetMetadataEvent.cpp +++ b/src/libs/engine/events/SetMetadataEvent.cpp @@ -17,7 +17,7 @@ #include "SetMetadataEvent.h" #include -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "ClientBroadcaster.h" #include "GraphObject.h" @@ -28,7 +28,7 @@ using std::string; namespace Ingen { -SetMetadataEvent::SetMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& key, const Atom& value) +SetMetadataEvent::SetMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& key, const Atom& value) : QueuedEvent(engine, responder, timestamp), _path(path), _key(key), diff --git a/src/libs/engine/events/SetMetadataEvent.h b/src/libs/engine/events/SetMetadataEvent.h index fae167a4..63a73a6d 100644 --- a/src/libs/engine/events/SetMetadataEvent.h +++ b/src/libs/engine/events/SetMetadataEvent.h @@ -36,7 +36,7 @@ class GraphObject; class SetMetadataEvent : public QueuedEvent { public: - SetMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& key, const Raul::Atom& value); + SetMetadataEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& path, const string& key, const Raul::Atom& value); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp index 5d8127e6..f78dca7f 100644 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ b/src/libs/engine/events/SetPortValueEvent.cpp @@ -15,8 +15,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "interface/Responder.h" #include "SetPortValueEvent.h" -#include "Responder.h" #include "Engine.h" #include "Port.h" #include "ClientBroadcaster.h" @@ -29,7 +29,7 @@ namespace Ingen { /** Voice-specific control setting */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) +SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) : Event(engine, responder, timestamp), _voice_num(voice_num), _port_path(port_path), @@ -40,7 +40,7 @@ SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr respon } -SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val) +SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val) : Event(engine, responder, timestamp), _voice_num(-1), _port_path(port_path), diff --git a/src/libs/engine/events/SetPortValueEvent.h b/src/libs/engine/events/SetPortValueEvent.h index 7425b71f..d5f5735f 100644 --- a/src/libs/engine/events/SetPortValueEvent.h +++ b/src/libs/engine/events/SetPortValueEvent.h @@ -35,8 +35,8 @@ class Port; class SetPortValueEvent : public Event { public: - SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val); - SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); + SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val); + SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.cpp b/src/libs/engine/events/SetPortValueQueuedEvent.cpp index 1eaa33cb..d713ae8a 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.cpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.cpp @@ -16,7 +16,7 @@ */ #include "SetPortValueQueuedEvent.h" -#include "Responder.h" +#include "interface/Responder.h" #include "Engine.h" #include "Port.h" #include "ClientBroadcaster.h" @@ -30,7 +30,7 @@ namespace Ingen { /** Voice-specific control setting */ -SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) +SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) : QueuedEvent(engine, responder, timestamp), _voice_num(voice_num), _port_path(port_path), @@ -41,7 +41,7 @@ SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val) +SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val) : QueuedEvent(engine, responder, timestamp), _voice_num(-1), _port_path(port_path), diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.h b/src/libs/engine/events/SetPortValueQueuedEvent.h index 734bb00f..4cbebe0e 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.h +++ b/src/libs/engine/events/SetPortValueQueuedEvent.h @@ -35,8 +35,8 @@ class Port; class SetPortValueQueuedEvent : public QueuedEvent { public: - SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val); - SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); + SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val); + SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); diff --git a/src/libs/engine/events/UnregisterClientEvent.cpp b/src/libs/engine/events/UnregisterClientEvent.cpp index 216f63f8..4248fdcb 100644 --- a/src/libs/engine/events/UnregisterClientEvent.cpp +++ b/src/libs/engine/events/UnregisterClientEvent.cpp @@ -15,16 +15,16 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "interface/ClientInterface.h" +#include "interface/Responder.h" #include "UnregisterClientEvent.h" -#include "Responder.h" #include "Engine.h" #include "ClientBroadcaster.h" -#include "interface/ClientInterface.h" namespace Ingen { -UnregisterClientEvent::UnregisterClientEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, ClientKey key) +UnregisterClientEvent::UnregisterClientEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, ClientKey key) : QueuedEvent(engine, responder, timestamp) , _key(key) { diff --git a/src/libs/engine/events/UnregisterClientEvent.h b/src/libs/engine/events/UnregisterClientEvent.h index cc3c0991..159bd160 100644 --- a/src/libs/engine/events/UnregisterClientEvent.h +++ b/src/libs/engine/events/UnregisterClientEvent.h @@ -40,7 +40,10 @@ using Shared::ClientKey; class UnregisterClientEvent : public QueuedEvent { public: - UnregisterClientEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, ClientKey key); + UnregisterClientEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + ClientKey key); void post_process(); diff --git a/src/libs/gui/App.cpp b/src/libs/gui/App.cpp new file mode 100644 index 00000000..928e5f5e --- /dev/null +++ b/src/libs/gui/App.cpp @@ -0,0 +1,260 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "App.h" +#include +#include +#include +#include +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/ObjectModel.h" +#include "client/PatchModel.h" +#include "client/Store.h" +#include "NodeModule.h" +#include "ControlPanel.h" +#include "SubpatchModule.h" +#include "LoadPluginWindow.h" +#include "PatchWindow.h" +#include "MessagesWindow.h" +#include "ConfigWindow.h" +#include "GladeFactory.h" +#include "PatchTreeWindow.h" +#include "Configuration.h" +#include "ConnectWindow.h" +#include "ThreadedLoader.h" +#include "WindowFactory.h" +#ifdef HAVE_LASH +#include "LashController.h" +#endif +using std::cerr; using std::cout; using std::endl; +using std::string; +namespace Ingen { namespace Client { class PluginModel; } } +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + +class Port; + + +/// Singleton instance +App* App::_instance = 0; + + +App::App() +: _configuration(new Configuration()), + _about_dialog(NULL), + _window_factory(new WindowFactory()), + _enable_signal(true) +{ + Glib::RefPtr glade_xml = GladeFactory::new_glade_reference(); + + glade_xml->get_widget_derived("connect_win", _connect_window); + glade_xml->get_widget_derived("messages_win", _messages_window); + glade_xml->get_widget_derived("patch_tree_win", _patch_tree_window); + glade_xml->get_widget_derived("config_win", _config_window); + glade_xml->get_widget("about_win", _about_dialog); + + _rdf_world.add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#"); + _rdf_world.add_prefix("ingen", "http://drobilla.net/ns/ingen#"); + _rdf_world.add_prefix("ingenuity", "http://drobilla.net/ns/ingenuity#"); + _rdf_world.add_prefix("lv2", "http://lv2plug.in/ontology#"); + _rdf_world.add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); + _rdf_world.add_prefix("doap", "http://usefulinc.com/ns/doap#"); + + _config_window->configuration(_configuration); + +#ifdef HAVE_SLV2 + SLV2World slv2_world = slv2_world_new_using_rdf_world(_rdf_world.world()); + PluginModel::set_slv2_world(slv2_world); +#endif +} + + +App::~App() +{ +} + + +void +App::run(int argc, char** argv) +{ + Gnome::Canvas::init(); + Gtk::Main main(argc, argv); + + if (!_instance) + _instance = new App(); + + /* Load settings */ + _instance->configuration()->load_settings(); + _instance->configuration()->apply_settings(); + + Gtk::Window::set_default_icon_from_file(PKGDATADIR "/ingen.svg"); + App::instance().connect_window()->start(); + + main.run(); +} + + +void +App::attach(const SharedPtr& engine, const SharedPtr& client) +{ + assert( ! _engine); + assert( ! _client); + assert( ! _store); + assert( ! _loader); + + _engine = engine; + _client = client; + _store = SharedPtr(new Store(engine, client)); + _loader = SharedPtr(new ThreadedLoader(engine)); + + _patch_tree_window->init(*_store); +} + + +void +App::detach() +{ + if (_engine) { + _window_factory->clear(); + _store->clear(); + + _loader.reset(); + _store.reset(); + _client.reset(); + _engine.reset(); + } +} + + +void +App::error_message(const string& str) +{ + _messages_window->post(str); + _messages_window->show(); + _messages_window->raise(); +} + + +/* +bool +App::idle_callback() +{ + _client_hooks->process_events(); + +#ifdef HAVE_LASH + //if (lash_controller->enabled()) + // lash_controller->process_events(); +#endif + + return true; +} +*/ + + +/******** Event Handlers ************/ + + +#if 0 +App::event_load_session() +{ + Gtk::FileChooserDialog* dialog + = new Gtk::FileChooserDialog(*_main_window, "Load Session", Gtk::FILE_CHOOSER_ACTION_OPEN); + + dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); + int result = dialog->run(); + string filename = dialog->get_filename(); + delete dialog; + + cout << result << endl; + + assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); + + if (result == Gtk::RESPONSE_OK) + //configuration->load_session(filename); + _controller->load_session(filename); +} + + +void +App::event_save_session_as() +{ + Gtk::FileChooserDialog dialog(*_main_window, "Save Session", Gtk::FILE_CHOOSER_ACTION_SAVE); + + /* + Gtk::VBox* box = dialog.get_vbox(); + Gtk::Label warning("Warning: Recursively saving will overwrite any subpatch files \ + without confirmation."); + box->pack_start(warning, false, false, 2); + Gtk::CheckButton recursive_checkbutton("Recursively save all subpatches"); + box->pack_start(recursive_checkbutton, false, false, 0); + recursive_checkbutton.show(); + */ + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); + + int result = dialog.run(); + //bool recursive = recursive_checkbutton.get_active(); + + assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); + + if (result == Gtk::RESPONSE_OK) { + string filename = dialog.get_filename(); + if (filename.length() < 11 || filename.substr(filename.length()-10) != ".omsession") + filename += ".omsession"; + + bool confirm = false; + std::fstream fin; + fin.open(filename.c_str(), std::ios::in); + if (fin.is_open()) { // File exists + string msg = "File already exists! Are you sure you want to overwrite "; + msg += filename + "?"; + Gtk::MessageDialog confir_dialog(*_main_window, + msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + if (confir_dialog.run() == Gtk::RESPONSE_YES) + confirm = true; + else + confirm = false; + } else { // File doesn't exist + confirm = true; + } + fin.close(); + + if (confirm) { + _controller->save_session(filename); + } + } +} +#endif + + +void +App::quit() +{ + Gtk::Main::quit(); +} + + +} // namespace GUI +} // namespace Ingen + diff --git a/src/libs/gui/App.h b/src/libs/gui/App.h new file mode 100644 index 00000000..504c6920 --- /dev/null +++ b/src/libs/gui/App.h @@ -0,0 +1,140 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef APP_H +#define APP_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using std::string; using std::map; using std::list; +using std::cerr; using std::endl; + +namespace Ingen { + namespace Shared { + class EngineInterface; + } + namespace Client { + class PatchModel; + class PluginModel; + class Store; + class SigClientInterface; + } +} +using namespace Ingen::Client; +using Ingen::Shared::EngineInterface; + +/** \defgroup GUI GTK GUI + */ + +namespace Ingen { +namespace GUI { + +class MessagesWindow; +class ConfigWindow; +class PatchCanvas; +class PatchTreeView; +class PatchTreeWindow; +class ConnectWindow; +class Configuration; +class ThreadedLoader; +class WindowFactory; + + +/** Singleton master class most everything is contained within. + * + * This is a horrible god-object, but it's shrinking in size as things are + * moved out. Hopefully it will go away entirely some day.. + * + * \ingroup GUI + */ +class App +{ +public: + ~App(); + + void error_message(const string& msg); + + void attach(const SharedPtr& engine, + const SharedPtr& client); + + void detach(); + + void quit(); + + ConnectWindow* connect_window() const { return _connect_window; } + Gtk::Dialog* about_dialog() const { return _about_dialog; } + ConfigWindow* configuration_dialog() const { return _config_window; } + MessagesWindow* messages_dialog() const { return _messages_window; } + PatchTreeWindow* patch_tree() const { return _patch_tree_window; } + Configuration* configuration() const { return _configuration; } + WindowFactory* window_factory() const { return _window_factory; } + + Raul::RDF::World* rdf_world() { return &_rdf_world; } + + const SharedPtr& engine() const { return _engine; } + const SharedPtr& client() const { return _client; } + const SharedPtr& store() const { return _store; } + const SharedPtr& loader() const { return _loader; } + + static inline App& instance() { assert(_instance); return *_instance; } + + static void run(int argc, char** argv); + +protected: + App(); + static App* _instance; + + static void instantiate(int argc, char** argv); + + SharedPtr _engine; + SharedPtr _client; + SharedPtr _store; + SharedPtr _loader; + + Configuration* _configuration; + + ConnectWindow* _connect_window; + MessagesWindow* _messages_window; + PatchTreeWindow* _patch_tree_window; + ConfigWindow* _config_window; + Gtk::Dialog* _about_dialog; + WindowFactory* _window_factory; + + Raul::RDF::World _rdf_world; + + /** Used to avoid feedback loops with (eg) process checkbutton + * FIXME: Maybe this should be globally implemented at the Controller level, + * disable all command sending while handling events to avoid feedback + * issues with widget event callbacks? This same pattern is duplicated + * too much... */ + bool _enable_signal; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // APP_H + diff --git a/src/libs/gui/BreadCrumb.h b/src/libs/gui/BreadCrumb.h new file mode 100644 index 00000000..96464b50 --- /dev/null +++ b/src/libs/gui/BreadCrumb.h @@ -0,0 +1,81 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BREADCRUMB_H +#define BREADCRUMB_H + +#include +#include +#include +#include "PatchView.h" + +namespace Ingen { +namespace GUI { + + +/** Breadcrumb button in a PatchWindow. + * + * Each Breadcrumb stores a reference to a PatchView for quick switching. + * So, the amount of allocated PatchViews at a given time is equal to the + * number of visible breadcrumbs (which is the perfect cache for GUI + * responsiveness balanced with mem consumption). + * + * \ingroup GUI + */ +class BreadCrumb : public Gtk::ToggleButton +{ +public: + BreadCrumb(const Path& path, SharedPtr view = SharedPtr()) + : _path(path) + , _view(view) + { + assert( !view || view->patch()->path() == path); + set_border_width(0); + set_path(path); + show_all(); + } + + void set_view(SharedPtr view) { + assert( !view || view->patch()->path() == _path); + _view = view; + } + + const Path& path() const { return _path; } + SharedPtr view() const { return _view; } + + void set_path(const Path& path) + { + remove(); + const string text = (path == "/") ? "/" : path.name(); + Gtk::Label* lab = manage(new Gtk::Label(text)); + lab->set_padding(0, 0); + lab->show(); + add(*lab); + + if (_view && _view->patch()->path() != path) + _view.reset(); + } + +private: + Path _path; + SharedPtr _view; +}; + +} // namespace GUI +} // namespace Ingen + +#endif // BREADCRUMB_H diff --git a/src/libs/gui/BreadCrumbBox.cpp b/src/libs/gui/BreadCrumbBox.cpp new file mode 100644 index 00000000..79a0bf69 --- /dev/null +++ b/src/libs/gui/BreadCrumbBox.cpp @@ -0,0 +1,206 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "BreadCrumbBox.h" +#include "BreadCrumb.h" +namespace Ingen { +namespace GUI { + + +BreadCrumbBox::BreadCrumbBox() +: Gtk::HBox() +, _active_path("/") +, _full_path("/") +, _enable_signal(true) +{ +} + + +SharedPtr +BreadCrumbBox::view(const Path& path) +{ + for (std::list::const_iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) + if ((*i)->path() == path) + return (*i)->view(); + + return SharedPtr(); +} + + +/** Sets up the crumbs to display @a path. + * + * If @a path is already part of the shown path, it will be selected and the + * children preserved. + */ +void +BreadCrumbBox::build(Path path, SharedPtr view) +{ + bool old_enable_signal = _enable_signal; + _enable_signal = false; + + // Moving to a path we already contain, just switch the active button + if (_breadcrumbs.size() > 0 && (path.is_parent_of(_full_path) || path == _full_path)) { + + for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == path) { + (*i)->set_active(true); + if (!(*i)->view()) + (*i)->set_view(view); + + // views are expensive, having two around for the same patch is a bug + assert((*i)->view() == view); + + } else { + (*i)->set_active(false); + } + } + + _active_path = path; + _enable_signal = old_enable_signal; + + + // Moving to a child of the full path, just append crumbs (preserve view cache) + } else if (_breadcrumbs.size() > 0 && (path.is_child_of(_full_path))) { + + string suffix = path.substr(_full_path.length()); + while (suffix.length() > 0) { + if (suffix[0] == '/') + suffix = suffix.substr(1); + const string name = suffix.substr(0, suffix.find("/")); + _full_path = _full_path.base() + name; + BreadCrumb* but = create_crumb(_full_path, view); + pack_start(*but, false, false, 1); + _breadcrumbs.push_back(but); + but->show(); + if (suffix.find("/") == string::npos) + break; + else + suffix = suffix.substr(suffix.find("/")+1); + } + + for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) + (*i)->set_active(false); + _breadcrumbs.back()->set_active(true); + + + // Rebuild from scratch + // Getting here is bad unless absolutely necessary, since the PatchView cache is lost + } else { + + _full_path = path; + _active_path = path; + + // Empty existing breadcrumbs + for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) + remove(**i); + _breadcrumbs.clear(); + + // Add root + BreadCrumb* root_but = create_crumb("/", view); + pack_start(*root_but, false, false, 1); + _breadcrumbs.push_front(root_but); + root_but->set_active(root_but->path() == _active_path); + + Path working_path = "/"; + string suffix = path.substr(1); + while (suffix.length() > 0) { + if (suffix[0] == '/') + suffix = suffix.substr(1); + const string name = suffix.substr(0, suffix.find("/")); + working_path = working_path.base() + name; + BreadCrumb* but = create_crumb(working_path, view); + pack_start(*but, false, false, 1); + _breadcrumbs.push_back(but); + but->set_active(working_path == _active_path); + but->show(); + if (suffix.find("/") == string::npos) + break; + else + suffix = suffix.substr(suffix.find("/")+1); + } + } + + _enable_signal = old_enable_signal; +} + + +/** Create a new crumb, assigning it a reference to @a view if their paths + * match, otherwise ignoring @a view. + */ +BreadCrumb* +BreadCrumbBox::create_crumb(const Path& path, + SharedPtr view) +{ + BreadCrumb* but = manage(new BreadCrumb(path, + (view && path == view->patch()->path()) ? view : SharedPtr())); + + but->signal_toggled().connect(sigc::bind(sigc::mem_fun( + this, &BreadCrumbBox::breadcrumb_clicked), but)); + + return but; +} + + +void +BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb) +{ + if (_enable_signal) { + _enable_signal = false; + + if (!crumb->get_active()) { + // Tried to turn off the current active button, bad user, no cookie + crumb->set_active(true); + } else { + signal_patch_selected.emit(crumb->path(), crumb->view()); + if (crumb->path() != _active_path) + crumb->set_active(false); + } + _enable_signal = true; + } +} + + +void +BreadCrumbBox::object_removed(const Path& path) +{ + for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == path) { + // Remove all crumbs after the removed one (inclusive) + for (std::list::iterator j = i; j != _breadcrumbs.end(); ) { + BreadCrumb* bc = *j; + j = _breadcrumbs.erase(j); + remove(*bc); + } + break; + } + } +} + + +void +BreadCrumbBox::object_renamed(const Path& old_path, const Path& new_path) +{ + for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == old_path) + (*i)->set_path(new_path); + } +} + + +} // namespace GUI +} // namespace Ingen + diff --git a/src/libs/gui/BreadCrumbBox.h b/src/libs/gui/BreadCrumbBox.h new file mode 100644 index 00000000..8b806f5a --- /dev/null +++ b/src/libs/gui/BreadCrumbBox.h @@ -0,0 +1,70 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BREADCRUMBBOX_H +#define BREADCRUMBBOX_H + +#include +#include +#include +#include +#include +#include +#include "PatchView.h" + +namespace Ingen { +namespace GUI { + +class BreadCrumb; + + +/** Collection of breadcrumb buttons forming a path. + * + * This doubles as a cache for PatchViews. + * + * \ingroup GUI + */ +class BreadCrumbBox : public Gtk::HBox +{ +public: + BreadCrumbBox(); + + SharedPtr view(const Path& path); + + void build(Path path, SharedPtr view); + + sigc::signal > signal_patch_selected; + +private: + BreadCrumb* create_crumb(const Path& path, + SharedPtr view = SharedPtr()); + + void breadcrumb_clicked(BreadCrumb* crumb); + + void object_removed(const Path& path); + void object_renamed(const Path& old_path, const Path& new_path); + + Path _active_path; + Path _full_path; + bool _enable_signal; + std::list _breadcrumbs; +}; + +} // namespace GUI +} // namespace Ingen + +#endif // BREADCRUMBBOX_H diff --git a/src/libs/gui/ConfigWindow.cpp b/src/libs/gui/ConfigWindow.cpp new file mode 100644 index 00000000..c8b29f1a --- /dev/null +++ b/src/libs/gui/ConfigWindow.cpp @@ -0,0 +1,88 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include "client/NodeModel.h" +#include "ConfigWindow.h" + +using namespace std; + +namespace Ingen { +namespace GUI { + + +ConfigWindow::ConfigWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::Window(cobject), + _configuration(NULL) +{ + xml->get_widget("config_path_entry", _path_entry); + xml->get_widget("config_save_button", _save_button); + xml->get_widget("config_cancel_button", _cancel_button); + xml->get_widget("config_ok_button", _ok_button); + + _save_button->signal_clicked().connect( sigc::mem_fun(this, &ConfigWindow::save_clicked)); + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &ConfigWindow::cancel_clicked)); + _ok_button->signal_clicked().connect( sigc::mem_fun(this, &ConfigWindow::ok_clicked)); +} + + +/** Sets the state manager for this window and initializes everything. + * + * This function MUST be called before using the window in any way! + */ +void +ConfigWindow::configuration(Configuration* sm) +{ + _configuration = sm; + _path_entry->set_text(sm->patch_path()); +} + + + +///// Event Handlers ////// + + +void +ConfigWindow::save_clicked() +{ + _configuration->patch_path(_path_entry->get_text()); + _configuration->apply_settings(); + _configuration->save_settings(); +} + + +void +ConfigWindow::cancel_clicked() +{ + hide(); +} + + +void +ConfigWindow::ok_clicked() +{ + _configuration->patch_path(_path_entry->get_text()); + _configuration->apply_settings(); + hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/ConfigWindow.h b/src/libs/gui/ConfigWindow.h new file mode 100644 index 00000000..d1a2cff6 --- /dev/null +++ b/src/libs/gui/ConfigWindow.h @@ -0,0 +1,65 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONFIGWINDOW_H +#define CONFIGWINDOW_H + +#include +#include +#include +#include +#include "client/PluginModel.h" +#include "Configuration.h" + +using std::list; +using Ingen::Client::PluginModel; + +namespace Ingen { +namespace GUI { + + +/** 'Configuration' window. + * + * Loaded by glade as a derived object. + * + * \ingroup GUI + */ +class ConfigWindow : public Gtk::Window +{ +public: + ConfigWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void configuration(Configuration* sm); + +private: + void save_clicked(); + void cancel_clicked(); + void ok_clicked(); + + Configuration* _configuration; + + Gtk::Entry* _path_entry; + Gtk::Button* _save_button; + Gtk::Button* _cancel_button; + Gtk::Button* _ok_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // CONFIGWINDOW_H diff --git a/src/libs/gui/Configuration.cpp b/src/libs/gui/Configuration.cpp new file mode 100644 index 00000000..d641ea98 --- /dev/null +++ b/src/libs/gui/Configuration.cpp @@ -0,0 +1,187 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "Configuration.h" +#include +#include +#include +#include +#include +#include "client/PortModel.h" +#include "client/PluginModel.h" +#include "client/PatchModel.h" +#include "serialisation/Loader.h" +#include "App.h" + +using std::cerr; using std::cout; using std::endl; +using std::map; using std::string; +using Ingen::Client::PatchModel; + +namespace Ingen { +namespace GUI { + +using namespace Ingen::Client; + + +Configuration::Configuration() +: _patch_path("/usr/share/ingen/patches:/usr/local/share/ingen/patches"), + _audio_port_color( 0x394f66B0), + _control_port_color(0x396639B0), + _midi_port_color( 0x663939B0) +{ +} + + +Configuration::~Configuration() +{ +} + + +/** Loads settings from the rc file. Passing no parameter will load from + * the default location. + */ +void +Configuration::load_settings(string filename) +{ + if (filename == "") + filename = string(getenv("HOME")).append("/.omgtkrc"); + + std::ifstream is; + is.open(filename.c_str(), std::ios::in); + + if ( ! is.good()) { + cout << "[Configuration] Unable to open settings file " << filename << endl; + return; + } else { + cout << "[Configuration] Loading settings from " << filename << endl; + } + + string s; + + is >> s; + if (s != "file_version") { + cerr << "[Configuration] Corrupt settings file, load aborted." << endl; + is.close(); + return; + } + + is >> s; + if (s != "1") { + cerr << "[Configuration] Unknown settings file version number, load aborted." << endl; + is.close(); + return; + } + + is >> s; + if (s != "patch_path") { + cerr << "[Configuration] Corrupt settings file, load aborted." << endl; + is.close(); + return; + } + + is >> s; + _patch_path = s; + + is.close(); +} + + +/** Saves settings to rc file. Passing no parameter will save to the + * default location. + */ +void +Configuration::save_settings(string filename) +{ + if (filename == "") + filename = string(getenv("HOME")).append("/.omgtkrc"); + + std::ofstream os; + os.open(filename.c_str(), std::ios::out); + + if ( ! os.good()) { + cout << "[Configuration] Unable to write to setting file " << filename << endl; + return; + } else { + cout << "[Configuration] Saving settings to " << filename << endl; + } + + os << "file_version 1" << endl; + os << "patch_path " << _patch_path << endl; + + os.close(); +} + + +/** Applies the current loaded settings to whichever parts of the app + * need updating. + */ +void +Configuration::apply_settings() +{ + cerr << "FIXME: patch path" << endl; + //App::instance().loader()->set_patch_path(_patch_path); +} + + +int +Configuration::get_port_color(const PortModel* pi) +{ + assert(pi != NULL); + + if (pi->is_control()) { + return _control_port_color; + } else if (pi->is_audio()) { + return _audio_port_color; + } else if (pi->is_midi()) { + return _midi_port_color; + } + + cerr << "[Configuration] Unknown port type! Port will be bright red, this is an error." << endl; + return 0xFF0000B0; +} + +/* +Coord +Configuration::get_window_location(const string& id) +{ + return _window_locations[id]; +} + + +void +Configuration::set_window_location(const string& id, Coord loc) +{ + _window_locations[id] = loc; +} + + +Coord +Configuration::get_window_size(const string& id) +{ + return _window_sizes[id]; +} + + +void +Configuration::set_window_size(const string& id, Coord size) +{ + _window_sizes[id] = size; +}*/ + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/Configuration.h b/src/libs/gui/Configuration.h new file mode 100644 index 00000000..b1a861cb --- /dev/null +++ b/src/libs/gui/Configuration.h @@ -0,0 +1,79 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONFIG_H +#define CONFIG_H + +#include + +namespace Ingen { namespace Client { class PortModel; } } +using Ingen::Client::PortModel; +using std::string; + +struct Coord { double x; double y; }; + +namespace Ingen { +namespace GUI { + +class Controller; + + +/** Singleton state manager for the entire app. + * + * Stores settings like color preferences, search paths, etc. + * (ie any user-defined preferences to be stoed in the rc file). + * + * \ingroup GUI + */ +class Configuration +{ +public: + Configuration(); + ~Configuration(); + + void load_settings(string filename = ""); + void save_settings(string filename = ""); + + void apply_settings(); + + string patch_path() { return _patch_path; } + void patch_path(const string& path) { _patch_path = path; } + + const string& patch_folder() { return _patch_folder; } + void set_patch_folder(const string& f) { _patch_folder = f; } + + int get_port_color(const PortModel* pi); + +private: + /** Search path for patch files. Colon delimited, as usual. */ + string _patch_path; + + /** Most recent patch folder shown in open dialog */ + string _patch_folder; + + int _audio_port_color; + int _control_port_color; + int _midi_port_color; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // CONFIG_H + + diff --git a/src/libs/gui/ConnectWindow.cpp b/src/libs/gui/ConnectWindow.cpp new file mode 100644 index 00000000..367a38fc --- /dev/null +++ b/src/libs/gui/ConnectWindow.cpp @@ -0,0 +1,426 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "interface/ClientKey.h" +#include "interface/EngineInterface.h" +#include "engine/tuning.h" +#include "engine/Engine.h" +#include "engine/DirectResponder.h" +#include "engine/QueuedEngineInterface.h" +#include "client/OSCClientReceiver.h" +#include "client/OSCEngineSender.h" +#include "client/ThreadedSigClientInterface.h" +#include "client/Store.h" +#include "client/PatchModel.h" +#include "module/Module.h" +#include "App.h" +#include "WindowFactory.h" +#include "ConnectWindow.h" +using Ingen::QueuedEngineInterface; +using Ingen::Client::ThreadedSigClientInterface; + +namespace Ingen { +namespace GUI { + + +// Paste together some interfaces to get the combination we want + + +struct OSCSigEmitter : public OSCClientReceiver, public ThreadedSigClientInterface { + OSCSigEmitter(size_t queue_size, int listen_port) + : Ingen::Shared::ClientInterface() + , OSCClientReceiver(listen_port) + , ThreadedSigClientInterface(queue_size) + { + } +}; + + +// ConnectWindow + + +ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) + : Gtk::Dialog(cobject) + , _mode(CONNECT_REMOTE) + , _ping_id(-1) + , _attached(false) + , _connect_stage(0) + , _new_engine(NULL) +{ + xml->get_widget("connect_icon", _icon); + xml->get_widget("connect_progress_bar", _progress_bar); + xml->get_widget("connect_progress_label", _progress_label); + xml->get_widget("connect_server_radiobutton", _server_radio); + xml->get_widget("connect_url_entry", _url_entry); + xml->get_widget("connect_launch_radiobutton", _launch_radio); + xml->get_widget("connect_port_spinbutton", _port_spinbutton); + xml->get_widget("connect_internal_radiobutton", _internal_radio); + xml->get_widget("connect_disconnect_button", _disconnect_button); + xml->get_widget("connect_connect_button", _connect_button); + xml->get_widget("connect_quit_button", _quit_button); + + _server_radio->signal_toggled().connect(sigc::mem_fun(this, &ConnectWindow::server_toggled)); + _launch_radio->signal_toggled().connect(sigc::mem_fun(this, &ConnectWindow::launch_toggled)); + _internal_radio->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::internal_toggled)); + _disconnect_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::disconnect)); + _connect_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::connect)); + _quit_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::quit)); + + _engine_module = Ingen::Shared::load_module("ingen_engine"); + + if (!_engine_module) { + cerr << "Unable to load ingen_engine module, internal engine unavailable." << endl; + cerr << "If you are running from the source tree, run ingenuity_dev." << endl; + } + + bool found = _engine_module->get_symbol("new_engine", (void*&)_new_engine); + + if (!found) { + cerr << "Unable to find module entry point, internal engine unavailable." << endl; + _engine_module.reset(); + } +} + + +void +ConnectWindow::start() +{ + resize(100, 100); + init(); + show(); + connect(); +} + + +void +ConnectWindow::init() +{ + _icon->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); + _progress_bar->set_fraction(0.0); + _url_entry->set_sensitive(true); + _connect_button->set_sensitive(true); + _disconnect_button->set_sensitive(false); + _port_spinbutton->set_sensitive(false); + _launch_radio->set_sensitive(true); + if (_new_engine) + _internal_radio->set_sensitive(true); + else + _internal_radio->set_sensitive(false); + server_toggled(); + + _progress_label->set_text(string("Disconnected")); +} + + +/** Launch (if applicable) and connect to the Engine. + * + * This will create the EngineInterface and ClientInterface and initialize + * the App with them. + */ +void +ConnectWindow::connect() +{ + assert(!_attached); + assert(!App::instance().engine()); + assert(!App::instance().client()); + + _connect_button->set_sensitive(false); + _disconnect_button->set_label("gtk-cancel"); + _disconnect_button->set_sensitive(true); + + _connect_stage = 0; + + if (_mode == CONNECT_REMOTE) { + SharedPtr engine( + new OSCEngineSender(_url_entry->get_text())); + + OSCSigEmitter* ose = new OSCSigEmitter(1024, 16181); // FIXME: args + SharedPtr client(ose); + App::instance().attach(engine, client); + + Glib::signal_timeout().connect( + sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); + + Glib::signal_timeout().connect( + sigc::mem_fun(ose, &ThreadedSigClientInterface::emit_signals), 2, G_PRIORITY_HIGH_IDLE); + + } else if (_mode == LAUNCH_REMOTE) { + + int port = _port_spinbutton->get_value_as_int(); + char port_str[6]; + snprintf(port_str, 6, "%u", port); + const string cmd = string("ingen --port=").append(port_str); + + if (Raul::Process::launch(cmd)) { + SharedPtr engine( + new OSCEngineSender(string("osc.udp://localhost:").append(port_str))); + + OSCSigEmitter* ose = new OSCSigEmitter(1024, 16181); // FIXME: args + SharedPtr client(ose); + App::instance().attach(engine, client); + + Glib::signal_timeout().connect( + sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); + + Glib::signal_timeout().connect( + sigc::mem_fun(ose, &ThreadedSigClientInterface::emit_signals), + 2, G_PRIORITY_HIGH_IDLE); + } else { + cerr << "Failed to launch ingen process." << endl; + } + + } else if (_mode == INTERNAL) { + assert(_new_engine); + SharedPtr engine(_new_engine()); + + engine->start_jack_driver(); + + SharedPtr engine_interface = engine->new_queued_interface(); + + ThreadedSigClientInterface* tsci = new ThreadedSigClientInterface(Ingen::event_queue_size); + SharedPtr client(tsci); + + App::instance().attach(engine_interface, client); + + engine_interface->set_responder(SharedPtr(new Ingen::DirectResponder(client, 1))); + + //engine->set_event_source(engine_interface); + + engine->activate(); + + Glib::signal_timeout().connect( + sigc::mem_fun(engine.get(), &Ingen::Engine::main_iteration), 1000); + + Glib::signal_timeout().connect( + sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); + + Glib::signal_timeout().connect( + sigc::mem_fun(tsci, &ThreadedSigClientInterface::emit_signals), 2, G_PRIORITY_HIGH_IDLE); + } +} + + +void +ConnectWindow::disconnect() +{ + _connect_stage = -1; + _attached = false; + + _progress_bar->set_fraction(0.0); + _connect_button->set_sensitive(false); + _disconnect_button->set_sensitive(false); + + App::instance().detach(); + + init(); + + _connect_button->set_sensitive(true); + _disconnect_button->set_sensitive(false); +} + + +void +ConnectWindow::quit() +{ + if (_attached) { + Gtk::MessageDialog d(*this, "This will exit the GUI, but the engine will " + "remain running (if it is remote).\n\nAre you sure you want to quit?", + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); + d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); + int ret = d.run(); + if (ret == Gtk::RESPONSE_CLOSE) + Gtk::Main::quit(); + } else { + Gtk::Main::quit(); + } +} + + +void +ConnectWindow::server_toggled() +{ + _url_entry->set_sensitive(true); + _port_spinbutton->set_sensitive(false); + _mode = CONNECT_REMOTE; +} + + +void +ConnectWindow::launch_toggled() +{ + _url_entry->set_sensitive(false); + _port_spinbutton->set_sensitive(true); + _mode = LAUNCH_REMOTE; +} + + +void +ConnectWindow::internal_toggled() +{ + _url_entry->set_sensitive(false); + _port_spinbutton->set_sensitive(false); + _mode = INTERNAL; +} + + +bool +ConnectWindow::gtk_callback() +{ + /* This isn't very nice (isn't threaded), but better than no dialog at + * all like before :) + */ + + // Timing stuff for repeated attach attempts + timeval now; + gettimeofday(&now, NULL); + static timeval last = now; + + /* Connecting to engine */ + if (_connect_stage == 0) { + + assert(!_attached); + assert(App::instance().engine()); + assert(App::instance().client()); + + // FIXME + //assert(!App::instance().engine()->is_attached()); + _progress_label->set_text("Connecting to engine..."); + present(); + + App::instance().client()->response_sig.connect(sigc::mem_fun(this, &ConnectWindow::response_received)); + + _ping_id = rand(); + while (_ping_id == -1) + _ping_id = rand(); + + App::instance().engine()->set_next_response_id(_ping_id); + App::instance().engine()->ping(); + ++_connect_stage; + + + } else if (_connect_stage == 1) { + if (_attached) { + App::instance().engine()->activate(); + ++_connect_stage; + } else { + const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + + (now.tv_usec - last.tv_usec) * 0.001f; + if (ms_since_last > 1000) { + App::instance().engine()->set_next_response_id(_ping_id); + App::instance().engine()->ping(); + last = now; + } + } + } else if (_connect_stage == 2) { + _progress_label->set_text(string("Registering as client...")); + //App::instance().engine()->register_client(App::instance().engine()->client_hooks()); + // FIXME + //auto_ptr client(new ThreadedSigClientInterface(); + App::instance().engine()->register_client(ClientKey(), App::instance().client()); + App::instance().engine()->load_plugins(); + ++_connect_stage; + } else if (_connect_stage == 3) { + // Register idle callback to process events and whatnot + // (Gtk refreshes at priority G_PRIORITY_HIGH_IDLE+20) + /*Glib::signal_timeout().connect( + sigc::mem_fun(this, &App::idle_callback), 100, G_PRIORITY_HIGH_IDLE);*/ + //Glib::signal_idle().connect(sigc::mem_fun(this, &App::idle_callback)); + /* Glib::signal_timeout().connect( + sigc::mem_fun((ThreadedSigClientInterface*)_client, &ThreadedSigClientInterface::emit_signals), + 5, G_PRIORITY_DEFAULT_IDLE);*/ + + _progress_label->set_text(string("Requesting plugins...")); + App::instance().engine()->request_plugins(); + ++_connect_stage; + } else if (_connect_stage == 4) { + // Wait for first plugins message + if (App::instance().store()->plugins().size() > 0) { + _progress_label->set_text(string("Receiving plugins...")); + ++_connect_stage; + } + } else if (_connect_stage == 5) { + // FIXME + /*if (App::instance().store().plugins().size() < _client->num_plugins()) { + static char buf[32]; + snprintf(buf, 32, "%zu/%zu", App::instance().store().plugins().size(), + ThreadedSigClientInterface::instance()->num_plugins()); + _progress_bar->set_text(Glib::ustring(buf)); + _progress_bar->set_fraction( + App::instance().store().plugins().size() / (double)_client->num_plugins()); + } else {*/ + _progress_bar->set_text(""); + ++_connect_stage; + //} + } else if (_connect_stage == 6) { + _progress_label->set_text(string("Waiting for root patch...")); + App::instance().engine()->request_all_objects(); + ++_connect_stage; + } else if (_connect_stage == 7) { + if (App::instance().store()->objects().size() > 0) { + SharedPtr root = PtrCast(App::instance().store()->object("/")); + assert(root); + App::instance().window_factory()->present_patch(root); + ++_connect_stage; + } + } else if (_connect_stage == 8) { + _progress_label->set_text("Connected to engine"); + ++_connect_stage; + } else if (_connect_stage == 9) { + ++_connect_stage; + hide(); + } else if (_connect_stage == 10) { + _icon->set(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); + _progress_bar->set_fraction(1.0); + _url_entry->set_sensitive(false); + _connect_button->set_sensitive(false); + _disconnect_button->set_label("gtk-disconnect"); + _disconnect_button->set_sensitive(true); + _port_spinbutton->set_sensitive(false); + _launch_radio->set_sensitive(false); + _internal_radio->set_sensitive(false); + _connect_stage = 0; // set ourselves up for next time (if there is one) + return false; // deregister this callback + } + + if (_connect_stage != 5) // yeah, ew + _progress_bar->pulse(); + + if (_connect_stage == -1) { // we were cancelled + _icon->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); + _progress_bar->set_fraction(0.0); + _connect_button->set_sensitive(true); + _disconnect_button->set_sensitive(false); + _disconnect_button->set_label("gtk-disconnect"); + _progress_label->set_text(string("Disconnected")); + return false; + } else { + return true; + } +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/ConnectWindow.h b/src/libs/gui/ConnectWindow.h new file mode 100644 index 00000000..1a4a654e --- /dev/null +++ b/src/libs/gui/ConnectWindow.h @@ -0,0 +1,92 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONNECT_WINDOW_H +#define CONNECT_WINDOW_H + +#include +#include +#include +#include +#include "client/ThreadedSigClientInterface.h" +using Ingen::Client::SigClientInterface; + +namespace Ingen { class Engine; class QueuedEngineInterface; } + +namespace Ingen { +namespace GUI { + +class App; +class Controller; + + +/** The initially visible "Connect to engine" window. + * + * This handles actually connecting to the engine and making sure everything + * is ready before really launching the app (eg wait for the root patch). + * + * \ingroup GUI + */ +class ConnectWindow : public Gtk::Dialog +{ +public: + ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void start(); + void response_received(int32_t id, bool, string) { if ((id) == _ping_id) _attached = true; } + +private: + enum Mode { CONNECT_REMOTE, LAUNCH_REMOTE, INTERNAL }; + + void server_toggled(); + void launch_toggled(); + void internal_toggled(); + + void init(); + void disconnect(); + void connect(); + void quit(); + + bool gtk_callback(); + + Mode _mode; + int32_t _ping_id; + bool _attached; + + int _connect_stage; + + SharedPtr _engine_module; + Ingen::Engine* (*_new_engine)(); + + Gtk::Image* _icon; + Gtk::ProgressBar* _progress_bar; + Gtk::Label* _progress_label; + Gtk::Entry* _url_entry; + Gtk::RadioButton* _server_radio; + Gtk::SpinButton* _port_spinbutton; + Gtk::RadioButton* _launch_radio; + Gtk::RadioButton* _internal_radio; + Gtk::Button* _disconnect_button; + Gtk::Button* _connect_button; + Gtk::Button* _quit_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // CONNECT_WINDOW_H diff --git a/src/libs/gui/Connection.h b/src/libs/gui/Connection.h new file mode 100644 index 00000000..d4d5c10c --- /dev/null +++ b/src/libs/gui/Connection.h @@ -0,0 +1,60 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONNECTION_H +#define CONNECTION_H + +#include +#include +#include +#include +#include "client/ConnectionModel.h" +using Ingen::Client::ConnectionModel; + +namespace Ingen { +namespace GUI { + + +/** A Connection in a Patch. + * + * \ingroup GUI + */ +class Connection : public LibFlowCanvas::Connection +{ +public: + Connection(boost::shared_ptr canvas, + boost::shared_ptr model, + boost::shared_ptr src, + boost::shared_ptr dst, + uint32_t color) + : LibFlowCanvas::Connection(canvas, src, dst, color) + , _connection_model(model) + {} + + virtual ~Connection() {} + + SharedPtr model() const { return _connection_model; } + +private: + SharedPtr _connection_model; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // CONNECTION_H diff --git a/src/libs/gui/ControlGroups.cpp b/src/libs/gui/ControlGroups.cpp new file mode 100644 index 00000000..7af9011b --- /dev/null +++ b/src/libs/gui/ControlGroups.cpp @@ -0,0 +1,430 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/PluginModel.h" +#include "client/NodeModel.h" +#include "client/PortModel.h" +#include "ControlGroups.h" +#include "ControlPanel.h" +#include "PortPropertiesWindow.h" +#include "GladeFactory.h" +#include "App.h" + +using std::cerr; using std::cout; using std::endl; + +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + + +// ////////////////////// ControlGroup ///////////////////////////////// // + +ControlGroup::ControlGroup(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) +: Gtk::VBox(cobject), + _control_panel(NULL), + _enable_signal(false) +{ +} + + +void +ControlGroup::init(ControlPanel* panel, SharedPtr pm) +{ + _control_panel = panel; + _port_model = pm, + + assert(_port_model); + assert(panel); + + pm->control_change_sig.connect(sigc::mem_fun(this, &ControlGroup::set_value)); +} + + +// ////////////////// SliderControlGroup ////////////////////// // + + +SliderControlGroup::SliderControlGroup(BaseObjectType* cobject, const Glib::RefPtr& xml) +: ControlGroup(cobject, xml), + _enabled(true) +{ + xml->get_widget("control_strip_name_label", _name_label); + xml->get_widget("control_strip_slider", _slider); + xml->get_widget("control_strip_spinner", _value_spinner); + + Glib::RefPtr menu_xml = GladeFactory::new_glade_reference("port_control_menu"); + menu_xml->get_widget("port_control_menu", _menu); + menu_xml->get_widget("port_control_menu_properties", _menu_properties); + + _menu_properties->signal_activate().connect( + sigc::mem_fun(this, &SliderControlGroup::menu_properties)); +} + + +void +SliderControlGroup::init(ControlPanel* panel, SharedPtr pm) +{ + _enable_signal = false; + _enabled = true; + + ControlGroup::init(panel, pm); + + assert(_name_label); + assert(_slider); + + set_name(pm->path().name()); + + _slider->set_draw_value(false); + + _name_label->signal_button_press_event().connect(sigc::mem_fun(*this, &SliderControlGroup::clicked)); + _slider->signal_button_press_event().connect(sigc::mem_fun(*this, &SliderControlGroup::clicked)); + + _slider->signal_event().connect( + sigc::mem_fun(*this, &SliderControlGroup::slider_pressed)); + + _slider->signal_value_changed().connect( + sigc::mem_fun(*this, &SliderControlGroup::update_value_from_slider)); + + _value_spinner->signal_value_changed().connect( + sigc::mem_fun(*this, &SliderControlGroup::update_value_from_spinner)); + + // FIXME: code duplication w/ PortPropertiesWindow.cpp + float min = 0.0f; + float max = 1.0f; + + const Atom& min_atom = pm->get_metadata("ingen:minimum"); + const Atom& max_atom = pm->get_metadata("ingen:maximum"); + if (min_atom.type() == Atom::FLOAT && max_atom.type() == Atom::FLOAT) { + min = min_atom.get_float(); + max = max_atom.get_float(); + } + + const SharedPtr parent = PtrCast(pm->parent()); + + if (parent && parent->plugin() && parent->plugin()->type() == PluginModel::LV2) { + min = slv2_port_get_minimum_value( + parent->plugin()->slv2_plugin(), + slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), + pm->path().name().c_str())); + max = slv2_port_get_maximum_value( + parent->plugin()->slv2_plugin(), + slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), + pm->path().name().c_str())); + } + + if (max <= min) + max = min + 1.0f; + + _slider->set_increments(0, 0); + _slider->set_range(min, max); + _value_spinner->set_range(min, max); + + set_value(pm->value()); + + _enable_signal = true; + + show_all(); +} + + +bool +SliderControlGroup::clicked(GdkEventButton* ev) +{ + if (ev->button == 3) { + _menu->popup(ev->button, ev->time); + return true; + } else { + return false; + } +} + + +void +SliderControlGroup::menu_properties() +{ + Glib::RefPtr xml = GladeFactory::new_glade_reference(); + + PortPropertiesWindow* dialog; + xml->get_widget_derived("port_properties_win", dialog); + dialog->init(this, _port_model); + dialog->run(); +} + + +void +SliderControlGroup::set_value(float val) +{ + _enable_signal = false; + if (_enabled) { + if (_slider->get_value() != val) + _slider->set_value(val); + if (_value_spinner->get_value() != val) + _value_spinner->set_value(val); + } + _enable_signal = true; +} + + +void +SliderControlGroup::set_range(float min, float max) +{ + _slider->set_range(min, max); + _value_spinner->set_range(min, max); +} + + +void +SliderControlGroup::set_name(const string& name) +{ + string name_label = ""; + name_label += name + ""; + _name_label->set_markup(name_label); +} + + +void +SliderControlGroup::enable() +{ + _slider->property_sensitive() = true; + //_min_spinner->property_sensitive() = true; + //_max_spinner->property_sensitive() = true; + _value_spinner->property_sensitive() = true; + _name_label->property_sensitive() = true; +} + + +void +SliderControlGroup::disable() +{ + _slider->property_sensitive() = false; + //_min_spinner->property_sensitive() = false; + //_max_spinner->property_sensitive() = false; + _value_spinner->property_sensitive() = false; + _name_label->property_sensitive() = false; +} + + +void +SliderControlGroup::update_value_from_slider() +{ + if (_enable_signal) { + const float value = _slider->get_value(); + _enable_signal = false; + + _value_spinner->set_value(value); + _control_panel->value_changed(_port_model, value); + + _enable_signal = true; + } +} + + +void +SliderControlGroup::update_value_from_spinner() +{ + if (_enable_signal) { + _enable_signal = false; + const float value = _value_spinner->get_value(); + + /*if (value < _min_spinner->get_value()) { + _min_spinner->set_value(value); + _slider->set_range(_min_spinner->get_value(), _max_spinner->get_value()); + } + if (value > _max_spinner->get_value()) { + _max_spinner->set_value(value); + _slider->set_range(_min_spinner->get_value(), _max_spinner->get_value()); + }*/ + + _slider->set_value(value); + + _control_panel->value_changed(_port_model, value); + + //m_port_model->value(value); + _enable_signal = true; + } +} + + +/** Callback for when slider is grabbed so we can ignore set_control + * events for this port (and avoid nasty feedback issues). + */ +bool +SliderControlGroup::slider_pressed(GdkEvent* ev) +{ + //cerr << "Pressed: " << ev->type << endl; + if (ev->type == GDK_BUTTON_PRESS) { + _enabled = false; + //GtkClientInterface::instance()->set_ignore_port(_port_model->path()); + } else if (ev->type == GDK_BUTTON_RELEASE) { + _enabled = true; + //GtkClientInterface::instance()->clear_ignore_port(); + } + + return false; +} + + +// ///////////// IntegerControlGroup ////////////// // + +#if 0 +IntegerControlGroup::IntegerControlGroup(ControlPanel* panel, SharedPtr pm) +: ControlGroup(panel, pm), + _enable_signal(false), + _alignment(0.5, 0.5, 0.0, 0.0), + _name_label(pm->path().name()), + _spinner(1.0, 0) +{ + set_name(pm->path().name()); + + _spinner.set_range(-99999, 99999); + _spinner.set_value(_port_model->value()); + _spinner.signal_value_changed().connect( + sigc::mem_fun(*this, &IntegerControlGroup::update_value)); + _spinner.set_increments(1, 10); + + _alignment.add(_spinner); + pack_start(_name_label); + pack_start(_alignment); + + _enable_signal = true; + + show_all(); +} + + +void +IntegerControlGroup::set_name(const string& name) +{ + string name_label = ""; + name_label += name + ""; + _name_label->set_markup(name_label); +} + + +void +IntegerControlGroup::set_value(float val) +{ + //cerr << "[IntegerControlGroup] Setting value to " << val << endl; + _enable_signal = false; + _spinner.set_value(val); + _enable_signal = true; +} + + +void +IntegerControlGroup::enable() +{ + _spinner.property_sensitive() = true; + _name_label->property_sensitive() = true; +} + + +void +IntegerControlGroup::disable() +{ + _spinner.property_sensitive() = false; + _name_label->property_sensitive() = false; +} + + +void +IntegerControlGroup::update_value() +{ + if (_enable_signal) { + float value = _spinner.get_value(); + _control_panel->value_changed(_port_model, value); + //m_port_model->value(value); + } +} + + +// ///////////// ToggleControlGroup ////////////// // + + +ToggleControlGroup::ToggleControlGroup(ControlPanel* panel, SharedPtr pm) +: ControlGroup(panel, pm), + _enable_signal(false), + _alignment(0.5, 0.5, 0.0, 0.0), + _name_label(pm->path().name()) +{ + set_name(pm->path().name()); + + set_value(_port_model->value()); + _checkbutton.signal_toggled().connect( + sigc::mem_fun(*this, &ToggleControlGroup::update_value)); + + _alignment.add(_checkbutton); + pack_start(_name_label); + pack_start(_alignment); + + _enable_signal = true; + + show_all(); +} + + +void +ToggleControlGroup::set_name(const string& name) +{ + string name_label = ""; + name_label += name + ""; + _name_label->set_markup(name_label); +} + + +void +ToggleControlGroup::set_value(float val) +{ + //cerr << "[ToggleControlGroup] Setting value to " << val << endl; + _enable_signal = false; + _checkbutton.set_active( (val > 0.0f) ); + _enable_signal = true; +} + + +void +ToggleControlGroup::enable() +{ + _checkbutton.property_sensitive() = true; + _name_label->property_sensitive() = true; +} + + +void +ToggleControlGroup::disable() +{ + _checkbutton.property_sensitive() = false; + _name_label->property_sensitive() = false; +} + + +void +ToggleControlGroup::update_value() +{ + if (_enable_signal) { + float value = _checkbutton.get_active() ? 1.0f : 0.0f; + _control_panel->value_changed(_port_model, value); + //m_port_model->value(value); + } +} +#endif + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/ControlGroups.h b/src/libs/gui/ControlGroups.h new file mode 100644 index 00000000..4a1f758e --- /dev/null +++ b/src/libs/gui/ControlGroups.h @@ -0,0 +1,162 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONTROLGROUPS_H +#define CONTROLGROUPS_H + +#include +#include +#include +#include +#include "client/PortModel.h" +#include + +namespace Ingen { namespace Client { class PortModel; } } +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + +class ControlPanel; +class PortPropertiesWindow; + + +/** A group of controls (for a single Port) in a NodeControlWindow. + * + * \ingroup GUI + */ +class ControlGroup : public Gtk::VBox +{ +public: + ControlGroup(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); + virtual ~ControlGroup() { } + + void init(ControlPanel* panel, SharedPtr pm); + + inline const SharedPtr port_model() const { return _port_model; } + +protected: + friend class PortPropertiesWindow; + + virtual void set_value(float value) = 0; + virtual void set_range(float min, float max) {} + + ControlPanel* _control_panel; + SharedPtr _port_model; + bool _enable_signal; +}; + + +/** A slider for a continuous control. + * + * \ingroup GUI + */ +class SliderControlGroup : public ControlGroup +{ +public: + SliderControlGroup(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); + void init(ControlPanel* panel, SharedPtr pm); + + void enable(); + void disable(); + + void set_min(float val); + void set_max(float val); + +private: + void set_name(const string& name); + + bool clicked(GdkEventButton* ev); + + void set_value(float value); + void set_range(float min, float max); + + void update_range(); + void update_value_from_slider(); + void update_value_from_spinner(); + + void menu_properties(); + + bool slider_pressed(GdkEvent* ev); + + bool _enabled; + + Gtk::Label* _name_label; + Gtk::SpinButton* _value_spinner; + Gtk::HScale* _slider; + + Gtk::Menu* _menu; + Gtk::MenuItem* _menu_properties; +}; + + +#if 0 + +/** A spinbutton for integer controls. + * + * \ingroup GUI + */ +class IntegerControlGroup : public ControlGroup +{ +public: + IntegerControlGroup(ControlPanel* panel, SharedPtr pm); + + void enable(); + void disable(); + +private: + void set_name(const string& name); + void set_value(float val); + + void update_value(); + + bool _enable_signal; + Gtk::Alignment _alignment; + Gtk::Label _name_label; + Gtk::SpinButton _spinner; +}; + + +/** A radio button for toggle controls. + * + * \ingroup GUI + */ +class ToggleControlGroup : public ControlGroup +{ +public: + ToggleControlGroup(ControlPanel* panel, SharedPtr pm); + + void enable(); + void disable(); + +private: + void set_name(const string& name); + void set_value(float val); + + void update_value(); + + bool _enable_signal; + Gtk::Alignment _alignment; + Gtk::Label _name_label; + Gtk::CheckButton _checkbutton; +}; +#endif + +} // namespace GUI +} // namespace Ingen + +#endif // CONTROLGROUPS_H diff --git a/src/libs/gui/ControlPanel.cpp b/src/libs/gui/ControlPanel.cpp new file mode 100644 index 00000000..6f3638a8 --- /dev/null +++ b/src/libs/gui/ControlPanel.cpp @@ -0,0 +1,259 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License alongCont + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "client/NodeModel.h" +#include "client/PortModel.h" +#include "client/PluginModel.h" +#include "App.h" +#include "ControlPanel.h" +#include "ControlGroups.h" +#include "GladeFactory.h" + +namespace Ingen { +namespace GUI { + + +ControlPanel::ControlPanel(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::HBox(cobject), + _callback_enabled(true) +{ + xml->get_widget("control_panel_controls_box", _control_box); + xml->get_widget("control_panel_voice_controls_box", _voice_control_box); + xml->get_widget("control_panel_all_voices_radio", _all_voices_radio); + xml->get_widget("control_panel_specific_voice_radio", _specific_voice_radio); + xml->get_widget("control_panel_voice_spinbutton", _voice_spinbutton); + + _all_voices_radio->signal_toggled().connect(sigc::mem_fun(this, &ControlPanel::all_voices_selected)); + _specific_voice_radio->signal_toggled().connect(sigc::mem_fun(this, &ControlPanel::specific_voice_selected)); + _voice_spinbutton->signal_value_changed().connect(sigc::mem_fun(this, &ControlPanel::voice_selected)); + + show_all(); +} + + +ControlPanel::~ControlPanel() +{ + for (vector::iterator i = _controls.begin(); i != _controls.end(); ++i) + delete (*i); +} + + +void +ControlPanel::init(SharedPtr node, size_t poly) +{ + assert(node != NULL); + assert(poly > 0); + + if (poly > 1) { + _voice_spinbutton->set_range(0, poly - 1); + } else { + remove(*_voice_control_box); + } + + for (PortModelList::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) { + add_port(*i); + } + + _callback_enabled = true; +} + + +ControlGroup* +ControlPanel::find_port(const Path& path) const +{ + for (vector::const_iterator cg = _controls.begin(); cg != _controls.end(); ++cg) + if ((*cg)->port_model()->path() == path) + return (*cg); + + return NULL; +} + + +/** Add a control to the panel for the given port. + */ +void +ControlPanel::add_port(SharedPtr pm) +{ + assert(pm); + + // Already have port, don't add another + if (find_port(pm->path()) != NULL) + return; + + // Add port + if (pm->is_control() && pm->is_input()) { + SliderControlGroup* cg = NULL; + if (pm->is_integer()) + cerr << "FIXME: integer\n"; + //cg = new IntegerControlGroup(this, pm); + else if (pm->is_toggle()) + cerr << "FIXME: toggle\n"; + //cg = new ToggleControlGroup(this, pm); + else { + Glib::RefPtr xml = GladeFactory::new_glade_reference("control_strip"); + xml->get_widget_derived("control_strip", cg); + cg->init(this, pm); + } + + if (_controls.size() > 0) + _control_box->pack_start(*Gtk::manage(new Gtk::HSeparator()), false, false, 4); + + _controls.push_back(cg); + _control_box->pack_start(*cg, false, false, 0); + + cg->enable(); + /*if (pm->connected()) + cg->disable(); + else + cg->enable();*/ + + cg->show(); + + cerr << "FIXME: control panel connected port tracking\n"; + // pm->connection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::connection), pm)) + // pm->disconnection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::disconnection), pm)) + } + + Gtk::Requisition controls_size; + _control_box->size_request(controls_size); + _ideal_size.first = controls_size.width; + _ideal_size.second = controls_size.height; + + Gtk::Requisition voice_size; + _voice_control_box->size_request(voice_size); + _ideal_size.first += voice_size.width; + _ideal_size.second += voice_size.height; + + //cerr << "Setting ideal size to " << _ideal_size.first + // << " x " << _ideal_size.second << endl; +} + + +/** Remove the control for the given port. + */ +void +ControlPanel::remove_port(const Path& path) +{ + bool was_first = false; + for (vector::iterator cg = _controls.begin(); cg != _controls.end(); ++cg) { + if ((*cg)->port_model()->path() == path) { + _control_box->remove(**cg); + if (cg == _controls.begin()) + was_first = true; + _controls.erase(cg); + break; + } + } +} + + +/** Rename the control for the given port. + */ +/* +void +ControlPanel::rename_port(const Path& old_path, const Path& new_path) +{ + for (vector::iterator cg = _controls.begin(); cg != _controls.end(); ++cg) { + if ((*cg)->port_model()->path() == old_path) { + (*cg)->set_name(new_path.name()); + return; + } + } +} +*/ + +#if 0 +/** Enable the control for the given port. + * + * Used when all connections to port are un-made. + */ +void +ControlPanel::enable_port(const Path& path) +{ + for (vector::iterator i = _controls.begin(); i != _controls.end(); ++i) { + if ((*i)->port_model()->path() == path) { + (*i)->enable(); + return; + } + } +} + + +/** Disable the control for the given port. + * + * Used when port is connected. + */ +void +ControlPanel::disable_port(const Path& path) +{ + for (vector::iterator i = _controls.begin(); i != _controls.end(); ++i) { + if ((*i)->port_model()->path() == path) { + (*i)->disable(); + return; + } + } +} +#endif + +/** Callback for ControlGroups to notify this of a change. + */ +void +ControlPanel::value_changed(SharedPtr port, float val) +{ + if (_callback_enabled) { + App::instance().engine()->disable_responses(); + + /* Send the message, but set the client-side model's value to the new + * setting right away (so the value doesn't need to be echoed back) */ + + if (_all_voices_radio->get_active()) { + App::instance().engine()->set_port_value(port->path(), val); + port->value(val); + } else { + int voice = _voice_spinbutton->get_value_as_int(); + App::instance().engine()->set_port_value(port->path(), voice, val); + port->value(val); + } + + App::instance().engine()->set_next_response_id(rand()); // FIXME: inefficient, probably not good + } +} + +void +ControlPanel::all_voices_selected() +{ + _voice_spinbutton->property_sensitive() = false; +} + + +void +ControlPanel::specific_voice_selected() +{ + _voice_spinbutton->property_sensitive() = true; +} + + +void +ControlPanel::voice_selected() +{ +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/ControlPanel.h b/src/libs/gui/ControlPanel.h new file mode 100644 index 00000000..230b9b65 --- /dev/null +++ b/src/libs/gui/ControlPanel.h @@ -0,0 +1,94 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONTROLPANEL_H +#define CONTROLPANEL_H + +#include +#include +#include +#include // for pair<> +#include +#include +#include +#include +#include +#include "ControlGroups.h" + + +using std::vector; using std::string; using std::pair; +using std::cerr; using std::cout; using std::endl; + +namespace Ingen { namespace Client { + class PortModel; + class NodeModel; +} } +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + + +/** A group of controls for a node (or patch). + * + * Used by both NodeControlWindow and the main window (for patch controls). + * + * \ingroup GUI + */ +class ControlPanel : public Gtk::HBox { +public: + ControlPanel(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); + virtual ~ControlPanel(); + + void init(SharedPtr node, size_t poly); + + ControlGroup* find_port(const Path& path) const; + + void add_port(SharedPtr port); + void remove_port(const Path& path); + + void enable_port(const Path& path); + void disable_port(const Path& path); + + size_t num_controls() const { return _controls.size(); } + pair ideal_size() const { return _ideal_size; } + + // Callback for ControlGroup + void value_changed(SharedPtr port_path, float val); + +private: + void all_voices_selected(); + void specific_voice_selected(); + void voice_selected(); + + bool _callback_enabled; + + pair _ideal_size; + + vector _controls; + Gtk::VBox* _control_box; + Gtk::Box* _voice_control_box; + Gtk::RadioButton* _all_voices_radio; + Gtk::RadioButton* _specific_voice_radio; + Gtk::SpinButton* _voice_spinbutton; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // CONTROLPANEL_H diff --git a/src/libs/gui/DSSIController.cpp b/src/libs/gui/DSSIController.cpp new file mode 100644 index 00000000..f245d61f --- /dev/null +++ b/src/libs/gui/DSSIController.cpp @@ -0,0 +1,279 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "DSSIController.h" +#include +#include +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/NodeModel.h" +#include "App.h" +#include "DSSIModule.h" + +namespace Ingen { +namespace GUI { + + +DSSIController::DSSIController(SharedPtr model) +: _banks_dirty(true) +{ +#if 0 + assert(model->plugin()->type() == PluginModel::DSSI); + Gtk::Menu::MenuList& items = _menu.items(); + items[0].property_sensitive() = true; // "Show Control Window" item + + Gtk::Menu_Helpers::MenuElem program_elem("Select Program", _program_menu); + items.push_front(program_elem); + _program_menu_item = program_elem.get_child(); + _program_menu_item->set_sensitive(false); + + items.push_front(Gtk::Menu_Helpers::MenuElem("Show Plugin GUI", + sigc::mem_fun(this, &DSSIController::show_gui))); +#endif +} + +void +DSSIController::program_add(int bank, int program, const string& name) +{ + cerr << "FIXME: DSSI add program\n"; + //node_model()->add_program(bank, program, name); + //m_banks_dirty = true; +} + + +void +DSSIController::program_remove(int bank, int program) +{ + cerr << "FIXME: DSSI add program\n"; + //node_model()->remove_program(bank, program); + //m_banks_dirty = true; +} + +/** Trivial wrapper of attempt_to_show_gui for libsigc + */ +void +DSSIController::show_gui() +{ + attempt_to_show_gui(); +} + + +void +DSSIController::update_program_menu() +{ + cerr << "FIXME: Program menu\n"; +#if 0 + _program_menu.items().clear(); + + const map >& banks = node_model()->get_programs(); + std::ostringstream oss; + + map >::const_iterator i; + for (i = banks.begin(); i != banks.end(); ++i) { + Gtk::Menu* bank_menu; + if (banks.size() > 1) + bank_menu = manage(new Gtk::Menu()); + else + bank_menu = &_program_menu; + map::const_iterator j; + for (j = i->second.begin(); j != i->second.end(); ++j) { + oss.str(""); + oss << std::setw(3) << std::setfill('0') + << j->first << ' ' << j->second; + sigc::slot slt = bind( + bind(sigc::mem_fun(*this, &DSSIController::send_program_change), + j->first), i->first); + bank_menu->items().push_back( + Gtk::Menu_Helpers::MenuElem(oss.str(), slt)); + } + if (banks.size() > 1) { + oss.str(""); + oss << "Bank " << i->first; + _program_menu.items().push_back( + Gtk::Menu_Helpers::MenuElem(oss.str(), *bank_menu)); + } + } + + // Disable the program menu if there are no programs + if (banks.size() == 0) + _program_menu_item->set_sensitive(false); + else + _program_menu_item->set_sensitive(true); + + _banks_dirty = false; +#endif +} + + +void +DSSIController::send_program_change(int bank, int program) +{ + //App::instance().engine()->set_program(node_model()->path(), bank, program); +} + + +/** Attempt to show the DSSI GUI for this plugin. + * + * Returns whether or not GUI was successfully loaded/shown. + */ +bool +DSSIController::attempt_to_show_gui() +{ + cerr << "FIXME: DSSI GUI" << endl; +#if 0 + // Shamelessley "inspired by" jack-dssi-host + // Copyright 2004 Chris Cannam, Steve Harris and Sean Bolton. + + const bool verbose = false; + + string engine_url = App::instance().engine()->engine_url(); + // Hack off last character if it's a / + if (engine_url[engine_url.length()-1] == '/') + engine_url = engine_url.substr(0, engine_url.length()-1); + + const char* dllName = node_model()->plugin()->lib_name().c_str(); + const char* label = node_model()->plugin()->plug_label().c_str(); + const char* myName = "ingenuity"; + const string& oscUrl = engine_url + "/dssi" + node_model()->path(); + + struct dirent* entry = NULL; + char* dllBase = strdup(dllName); + char* subpath = NULL; + DIR* subdir = NULL; + char* filename = NULL; + struct stat buf; + int fuzzy = 0; + + char* env_dssi_path = getenv("DSSI_PATH"); + string dssi_path; + if (!env_dssi_path) { + cerr << "DSSI_PATH is empty. Assuming /usr/lib/dssi:/usr/local/lib/dssi." << endl; + dssi_path = "/usr/lib/dssi:/usr/local/lib/dssi"; + } else { + dssi_path = env_dssi_path; + } + + if (strlen(dllBase) > 3 && !strcasecmp(dllBase + strlen(dllBase) - 3, ".so")) { + dllBase[strlen(dllBase) - 3] = '\0'; + } + + + // This is pretty nasty, it loops through the path, even if the dllBase is absolute + while (dssi_path != "") { + string directory = dssi_path.substr(0, dssi_path.find(':')); + if (dssi_path.find(':') != string::npos) + dssi_path = dssi_path.substr(dssi_path.find(':')+1); + else + dssi_path = ""; + + if (*dllBase == '/') { + subpath = strdup(dllBase); + } else { + subpath = (char*)malloc(strlen(directory.c_str()) + strlen(dllBase) + 2); + sprintf(subpath, "%s/%s", directory.c_str(), dllBase); + } + + for (fuzzy = 0; fuzzy <= 1; ++fuzzy) { + + if (!(subdir = opendir(subpath))) { + if (verbose) { + fprintf(stderr, "%s: can't open plugin GUI directory \"%s\"\n", myName, subpath); + } + break; + } + + while ((entry = readdir(subdir))) { + + if (entry->d_name[0] == '.') + continue; + if (!strchr(entry->d_name, '_')) + continue; + + if (fuzzy) { + if (verbose) { + fprintf(stderr, "checking %s against %s\n", entry->d_name, dllBase); + } + if (strncmp(entry->d_name, dllBase, strlen(dllBase))) + continue; + } else { + if (verbose) { + fprintf(stderr, "checking %s against %s\n", entry->d_name, label); + } + if (strncmp(entry->d_name, label, strlen(label))) + continue; + } + + filename = (char*)malloc(strlen(subpath) + strlen(entry->d_name) + 2); + sprintf(filename, "%s/%s", subpath, entry->d_name); + + if (stat(filename, &buf)) { + perror("stat failed"); + free(filename); + continue; + } + + if ((S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) && + (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) { + + if (verbose) { + fprintf(stderr, "%s: trying to execute GUI at \"%s\"\n", + myName, filename); + } + + if (fork() == 0) { + execlp(filename, filename, oscUrl.c_str(), dllName, label, + node_model()->name().c_str(), 0); + perror("exec failed"); + exit(1); + } + + free(filename); + free(subpath); + free(dllBase); + return true; + } + + free(filename); + } + } + } + + cerr << "Unable to launch DSSI GUI for " << node_model()->path() << endl; + + free(subpath); + free(dllBase); +#endif + return false; +} + + +void +DSSIController::show_menu(GdkEventButton* event) +{ +#if 0 + if (_banks_dirty) + update_program_menu(); + NodeController::show_menu(event); +#endif +} + + +} // namespace GUI +} // namespace Ingen + diff --git a/src/libs/gui/DSSIController.h b/src/libs/gui/DSSIController.h new file mode 100644 index 00000000..fdb0c1c0 --- /dev/null +++ b/src/libs/gui/DSSIController.h @@ -0,0 +1,77 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSSICONTROLLER_H +#define DSSICONTROLLER_H + +#include +#include +#include +#include "client/NodeModel.h" + +using std::string; +using namespace Ingen::Client; + +namespace Ingen { namespace Client { + class MetadataModel; + class NodeModel; + class PortModel; +} } + +namespace Ingen { +namespace GUI { + +class NodeControlWindow; +class NodePropertiesWindow; + +/* Controller for a DSSI node. + * + * FIXME: legacy cruft. move this code to the appropriate places and nuke + * this class. + * + * \ingroup GUI + */ +class DSSIController +{ +public: + DSSIController(SharedPtr model); + + virtual ~DSSIController() {} + + void show_gui(); + bool attempt_to_show_gui(); + void program_add(int bank, int program, const string& name); + void program_remove(int bank, int program); + + void send_program_change(int bank, int program); + + void show_menu(GdkEventButton* event); + +private: + void update_program_menu(); + + Gtk::Menu _program_menu; + Glib::RefPtr _program_menu_item; + + bool _banks_dirty; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // DSSICONTROLLER_H diff --git a/src/libs/gui/DSSIModule.cpp b/src/libs/gui/DSSIModule.cpp new file mode 100644 index 00000000..57cbd03f --- /dev/null +++ b/src/libs/gui/DSSIModule.cpp @@ -0,0 +1,43 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "DSSIModule.h" +#include "DSSIController.h" + +namespace Ingen { +namespace GUI { + + +DSSIModule::DSSIModule(boost::shared_ptr canvas, SharedPtr node) +: NodeModule(canvas, node) +{ +} + + +void +DSSIModule::on_double_click(GdkEventButton* ev) +{ + /* + DSSIController* dc = dynamic_cast(_node); + if (!dc || ! dc->attempt_to_show_gui()) + show_control_window(); + */ +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/DSSIModule.h b/src/libs/gui/DSSIModule.h new file mode 100644 index 00000000..1c041900 --- /dev/null +++ b/src/libs/gui/DSSIModule.h @@ -0,0 +1,46 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSSIMODULE_H +#define DSSIMODULE_H + +#include "NodeModule.h" + +namespace Ingen { +namespace GUI { + +class DSSIController; + +/* Module for a DSSI node. + * + * \ingroup GUI + */ +class DSSIModule : public NodeModule +{ +public: + DSSIModule(boost::shared_ptr canvas, SharedPtr node); + virtual ~DSSIModule() {} + + void on_double_click(GdkEventButton* ev); +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // DSSIMODULE_H + diff --git a/src/libs/gui/GladeFactory.cpp b/src/libs/gui/GladeFactory.cpp new file mode 100644 index 00000000..ac796d9f --- /dev/null +++ b/src/libs/gui/GladeFactory.cpp @@ -0,0 +1,72 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GladeFactory.h" +#include +#include +using std::cout; using std::cerr; using std::endl; +using std::ifstream; + +namespace Ingen { +namespace GUI { + + +Glib::ustring GladeFactory::glade_filename = ""; + + +void +GladeFactory::find_glade_file() +{ + // Check for the .glade file in current directory + glade_filename = "./ingenuity.glade"; + ifstream fs(glade_filename.c_str()); + if (fs.fail()) { // didn't find it, check PKGDATADIR + fs.clear(); + glade_filename = PKGDATADIR; + glade_filename += "/ingenuity.glade"; + + fs.open(glade_filename.c_str()); + if (fs.fail()) { + cerr << "[GladeFactory] Unable to find ingenuity.glade in current directory or " << PKGDATADIR << "." << endl; + throw; + } + fs.close(); + } + cerr << "[GladeFactory] Loading widgets from " << glade_filename.c_str() << endl; +} + + +Glib::RefPtr +GladeFactory::new_glade_reference(const string& toplevel_widget) +{ + if (glade_filename == "") + find_glade_file(); + + try { + if (toplevel_widget == "") + return Gnome::Glade::Xml::create(glade_filename); + else + return Gnome::Glade::Xml::create(glade_filename, toplevel_widget.c_str()); + } catch (const Gnome::Glade::XmlError& ex) { + cerr << ex.what() << endl; + throw ex; + } +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/GladeFactory.h b/src/libs/gui/GladeFactory.h new file mode 100644 index 00000000..0a2e88fc --- /dev/null +++ b/src/libs/gui/GladeFactory.h @@ -0,0 +1,51 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GLADEFACTORY_H +#define GLADEFACTORY_H + +#include +#include + +using std::string; + +namespace Ingen { +namespace GUI { + + +/** Creates glade references, so various objects can create widgets. + * Purely static. + * + * \ingroup GUI + */ +class GladeFactory { +public: + static Glib::RefPtr + new_glade_reference(const string& toplevel_widget = ""); + +private: + GladeFactory() {} + + static void find_glade_file(); + static Glib::ustring glade_filename; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // GLADEFACTORY_H diff --git a/src/libs/gui/LashController.cpp b/src/libs/gui/LashController.cpp new file mode 100644 index 00000000..b62ec818 --- /dev/null +++ b/src/libs/gui/LashController.cpp @@ -0,0 +1,170 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "LashController.h" +#include "config.h" +#include +#include +#include +#include +#include +#include "App.h" +#include "PatchModel.h" + +using std::cerr; using std::cout; using std::endl; +using std::string; + +namespace Ingen { +namespace GUI { + + +LashController::LashController(lash_args_t* args) +: _client(NULL) +{ + _client = lash_init(args, PACKAGE_NAME, + /*LASH_Config_Data_Set|*/LASH_Config_File, LASH_PROTOCOL(2, 0)); + if (_client == NULL) { + cerr << "[LashController] Failed to connect to LASH. Session management will not function." << endl; + } else { + cout << "[LashController] Lash initialised" << endl; + } + + lash_event_t* event = lash_event_new_with_type(LASH_Client_Name); + lash_event_set_string(event, "Ingen"); + lash_send_event(_client, event); +} + + +LashController::~LashController() +{ + if (_client != NULL) { + lash_event_t* quit_event = lash_event_new_with_type(LASH_Quit); + lash_send_event(_client, quit_event); + } +} + + +void +LashController::process_events() +{ + assert(_client != NULL); + + lash_event_t* ev = NULL; + lash_config_t* conf = NULL; + + // Process events + while ((ev = lash_get_event(_client)) != NULL) { + handle_event(ev); + lash_event_destroy(ev); + } + + // Process configs + while ((conf = lash_get_config(_client)) != NULL) { + handle_config(conf); + lash_config_destroy(conf); + } +} + + +void +LashController::handle_event(lash_event_t* ev) +{ + assert(ev != NULL); + + LASH_Event_Type type = lash_event_get_type(ev); + const char* c_str = lash_event_get_string(ev); + string str = (c_str == NULL) ? "" : c_str; + + if (type == LASH_Save_File) { + cout << "[LashController] LASH Save File - " << str << endl; + save(str); + lash_send_event(_client, lash_event_new_with_type(LASH_Save_File)); + } else if (type == LASH_Restore_File) { + cout << "[LashController] LASH Restore File - " << str << endl; + cerr << "LASH RESTORE NOT YET (RE)IMPLEMENTED." << endl; + /*_controller->load_session_blocking(str + "/session"); + _controller->lash_restore_finished(); + lash_send_event(_client, lash_event_new_with_type(LASH_Restore_File)); + */ + /*} else if (type == LASH_Save_Data_Set) { + //cout << "[LashController] LASH Save Data Set - " << endl; + + // Tell LASH we're done + lash_send_event(_client, lash_event_new_with_type(LASH_Save_Data_Set)); + */ + } else if (type == LASH_Quit) { + cout << "[LashController] LASH Quit" << endl; + _client = NULL; + App::instance().quit(); + } else { + cerr << "[LashController] Unhandled LASH event, type: " << static_cast(type) << endl; + } +} + + +void +LashController::handle_config(lash_config_t* conf) +{ + assert(conf != NULL); + + const char* key = NULL; + const void* val = NULL; + size_t val_size = 0; + + cout << "[LashController] LASH Config. Key = " << key << endl; + + key = lash_config_get_key(conf); + val = lash_config_get_value(conf); + val_size = lash_config_get_value_size(conf); +} + +void +LashController::save(const string& dir) +{ + cerr << "LASH SAVING NOT YET (RE)IMPLEMENTED\n"; + /* + PatchController* pc = NULL; + + // Save every patch under dir with it's path as a filename + // (so the dir structure will resemble the patch heirarchy) + for (map::iterator i = _app->patches().begin(); + i != _app->patches().end(); ++i) { + pc = (*i).second; + pc->model()->filename(dir + pc->model()->path() + ".om"); + } + + // Create directories + for (map::iterator i = _app->patches().begin(); + i != _app->patches().end(); ++i) { + pc = (*i).second; + if (pc->model()->parent() != NULL) { + string path = Path::parent(pc->model()->path()).substr(1) + "/"; + while (path.find("/") != string::npos) { + mkdir(string(dir +"/"+ path.substr(0, path.find("/"))).c_str(), 0744); + path = path.substr(path.find("/")+1); + } + } + _controller->save_patch_blocking(pc->model(), pc->model()->filename(), false); + } + + //m_app->state_manager()->save(str + "/omgtkrc"); + _controller->save_session_blocking(dir + "/session"); + */ +} + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/LashController.h b/src/libs/gui/LashController.h new file mode 100644 index 00000000..f47eb5e9 --- /dev/null +++ b/src/libs/gui/LashController.h @@ -0,0 +1,56 @@ +/* This file is part of IngenGtk. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LASHCONTROLLER_H +#define LASHCONTROLLER_H + +#include +#include +using std::string; + +namespace Ingen { +namespace GUI { + +class App; + +/* Old and unused LASH controller. + * + * \ingroup GUI + */ +class LashController +{ +public: + LashController(lash_args_t* args); + ~LashController(); + + bool enabled() { return lash_enabled(_client); } + void process_events(); + +private: + void save(const string& dir); + + lash_client_t* _client; + + void handle_event(lash_event_t* conf); + void handle_config(lash_config_t* conf); +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // LASHCONTROLLER_H diff --git a/src/libs/gui/LoadPatchWindow.cpp b/src/libs/gui/LoadPatchWindow.cpp new file mode 100644 index 00000000..faaa519a --- /dev/null +++ b/src/libs/gui/LoadPatchWindow.cpp @@ -0,0 +1,149 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "LoadPatchWindow.h" +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "App.h" +#include "Configuration.h" +#include "ThreadedLoader.h" + +using namespace Ingen::Serialisation; +using boost::optional; + +namespace Ingen { +namespace GUI { + + +LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::FileChooserDialog(cobject), + _replace(true) +{ + xml->get_widget("load_patch_poly_from_current_radio", _poly_from_current_radio); + xml->get_widget("load_patch_poly_from_file_radio", _poly_from_file_radio); + xml->get_widget("load_patch_poly_from_user_radio", _poly_from_user_radio); + xml->get_widget("load_patch_poly_spinbutton", _poly_spinbutton); + xml->get_widget("load_patch_ok_button", _ok_button); + xml->get_widget("load_patch_cancel_button", _cancel_button); + + _poly_from_current_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); + _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); + _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_user_selected)); + _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::ok_clicked)); + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::cancel_clicked)); + + _poly_from_current_radio->set_active(true); + + Gtk::FileFilter filt; + filt.add_pattern("*.om"); + filt.set_name("Om patch files (XML, DEPRECATED) (*.om)"); + filt.add_pattern("*.ingen.ttl"); + filt.set_name("Ingen patch files (RDF, *.ingen.ttl)"); + set_filter(filt); + + // Add global examples directory to "shortcut folders" (bookmarks) + string examples_dir = PKGDATADIR; + examples_dir.append("/patches"); + DIR* d = opendir(examples_dir.c_str()); + if (d != NULL) + add_shortcut_folder(examples_dir); +} + + +void +LoadPatchWindow::present(SharedPtr patch, MetadataMap data) +{ + set_patch(patch); + _initial_data = data; + Gtk::Window::present(); +} + + +/** Sets the patch controller for this window and initializes everything. + * + * This function MUST be called before using the window in any way! + */ +void +LoadPatchWindow::set_patch(SharedPtr patch) +{ + _patch = patch; +} + + +void +LoadPatchWindow::on_show() +{ + if (App::instance().configuration()->patch_folder().length() > 0) + set_current_folder(App::instance().configuration()->patch_folder()); + Gtk::FileChooserDialog::on_show(); +} + + +///// Event Handlers ////// + + +void +LoadPatchWindow::poly_from_file_selected() +{ + _poly_spinbutton->property_sensitive() = false; +} + + +void +LoadPatchWindow::poly_from_user_selected() +{ + _poly_spinbutton->property_sensitive() = true; +} + + +void +LoadPatchWindow::ok_clicked() +{ + // If unset load_patch will load values + optional name; + optional poly; + + optional parent; + + if (_poly_from_user_radio->get_active()) + poly = _poly_spinbutton->get_value_as_int(); + + if (_replace) + App::instance().engine()->clear_patch(_patch->path()); + + if (_patch->path() != "/") + parent = _patch->path().parent(); + + App::instance().loader()->load_patch(true, get_uri(), "/", + _initial_data, parent, name, poly); + + hide(); +} + + +void +LoadPatchWindow::cancel_clicked() +{ + hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/LoadPatchWindow.h b/src/libs/gui/LoadPatchWindow.h new file mode 100644 index 00000000..47f0bc8f --- /dev/null +++ b/src/libs/gui/LoadPatchWindow.h @@ -0,0 +1,81 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LOADPATCHWINDOW_H +#define LOADPATCHWINDOW_H + +#include +#include +#include +#include "client/PluginModel.h" +#include "client/PatchModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; + +namespace Ingen { +namespace GUI { + + +/** 'Load Patch' window. + * + * Loaded by glade as a derived object. Used for both "Import" and "Load" + * (e.g. Replace, clear-then-import) operations (the radio button state + * should be changed with the provided methods before presenting). + * + * This is not for loading subpatches. See @a LoadSubpatchWindow for that. + * + * \ingroup GUI + */ +class LoadPatchWindow : public Gtk::FileChooserDialog +{ +public: + LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void set_patch(SharedPtr patch); + + void set_replace() { _replace = true; } + void set_merge() { _replace = false; } + + void present(SharedPtr patch, MetadataMap data); + +protected: + void on_show(); + +private: + void poly_from_file_selected(); + void poly_from_user_selected(); + void ok_clicked(); + void cancel_clicked(); + + MetadataMap _initial_data; + + SharedPtr _patch; + bool _replace; + + Gtk::RadioButton* _poly_from_current_radio; + Gtk::RadioButton* _poly_from_file_radio; + Gtk::RadioButton* _poly_from_user_radio; + Gtk::SpinButton* _poly_spinbutton; + Gtk::Button* _ok_button; + Gtk::Button* _cancel_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // LOADPATCHWINDOW_H diff --git a/src/libs/gui/LoadPluginWindow.cpp b/src/libs/gui/LoadPluginWindow.cpp new file mode 100644 index 00000000..a4b24e5f --- /dev/null +++ b/src/libs/gui/LoadPluginWindow.cpp @@ -0,0 +1,458 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/NodeModel.h" +#include "client/PatchModel.h" +#include "client/Store.h" +#include "App.h" +#include "LoadPluginWindow.h" +#include "PatchWindow.h" +#include "PatchView.h" +#include "PatchCanvas.h" +using std::cout; using std::cerr; using std::endl; + + +namespace Ingen { +namespace GUI { + +LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::Window(cobject), + _has_shown(false), + _plugin_name_offset(0) +{ + xml->get_widget("load_plugin_plugins_treeview", _plugins_treeview); + xml->get_widget("load_plugin_polyphonic_checkbutton", _polyphonic_checkbutton); + xml->get_widget("load_plugin_name_entry", _node_name_entry); + xml->get_widget("load_plugin_clear_button", _clear_button); + xml->get_widget("load_plugin_add_button", _add_button); + //xml->get_widget("load_plugin_close_button", _close_button); + //xml->get_widget("load_plugin_ok_button", _add_button); + + xml->get_widget("load_plugin_filter_combo", _filter_combo); + xml->get_widget("load_plugin_search_entry", _search_entry); + + // Set up the plugins list + _plugins_liststore = Gtk::ListStore::create(_plugins_columns); + _plugins_treeview->set_model(_plugins_liststore); + _plugins_treeview->append_column("Name", _plugins_columns._col_name); + _plugins_treeview->append_column("Type", _plugins_columns._col_type); + _plugins_treeview->append_column("URI", _plugins_columns._col_uri); + //m_plugins_treeview->append_column("Library", _plugins_columns._col_library); + //m_plugins_treeview->append_column("Label", _plugins_columns._col_label); + + // This could be nicer.. store the TreeViewColumns locally maybe? + _plugins_treeview->get_column(0)->set_sort_column(_plugins_columns._col_name); + _plugins_treeview->get_column(1)->set_sort_column(_plugins_columns._col_type); + _plugins_treeview->get_column(2)->set_sort_column(_plugins_columns._col_uri); + //m_plugins_treeview->get_column(3)->set_sort_column(_plugins_columns._col_library); + //m_plugins_treeview->get_column(4)->set_sort_column(_plugins_columns._col_label); + for (int i=0; i < 3; ++i) + _plugins_treeview->get_column(i)->set_resizable(true); + + _plugins_liststore->set_default_sort_func(sigc::mem_fun(this, &LoadPluginWindow::plugin_compare)); + + // Set up the search criteria combobox + _criteria_liststore = Gtk::ListStore::create(_criteria_columns); + _filter_combo->set_model(_criteria_liststore); + Gtk::TreeModel::iterator iter = _criteria_liststore->append(); + Gtk::TreeModel::Row row = *iter; + row[_criteria_columns._col_label] = "Name contains"; + row[_criteria_columns._col_criteria] = CriteriaColumns::NAME; + _filter_combo->set_active(iter); + iter = _criteria_liststore->append(); row = *iter; + row[_criteria_columns._col_label] = "Type contains"; + row[_criteria_columns._col_criteria] = CriteriaColumns::TYPE; + iter = _criteria_liststore->append(); row = *iter; + row[_criteria_columns._col_label] = "URI contains"; + row[_criteria_columns._col_criteria] = CriteriaColumns::URI; + /*iter = _criteria_liststore->append(); row = *iter; + row[_criteria_columns._col_label] = "Library contains: "; + row[_criteria_columns._col_criteria] = CriteriaColumns::LIBRARY; + iter = _criteria_liststore->append(); row = *iter; + row[_criteria_columns._col_label] = "Label contains: "; + row[_criteria_columns._col_criteria] = CriteriaColumns::LABEL;*/ + + _clear_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::clear_clicked)); + _add_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::add_clicked)); + //m_close_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::close_clicked)); + //m_add_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::ok_clicked)); + _plugins_treeview->signal_row_activated().connect(sigc::mem_fun(this, &LoadPluginWindow::plugin_activated)); + _search_entry->signal_activate().connect( sigc::mem_fun(this, &LoadPluginWindow::add_clicked)); + _search_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::filter_changed)); + _node_name_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::name_changed)); + + _selection = _plugins_treeview->get_selection(); + _selection->signal_changed().connect(sigc::mem_fun(this, &LoadPluginWindow::plugin_selection_changed)); + + //m_add_button->grab_default(); +} + + +void +LoadPluginWindow::present(SharedPtr patch, MetadataMap data) +{ + set_patch(patch); + _initial_data = data; + Gtk::Window::present(); +} + + +/** Called every time the user types into the name input box. + * Used to display warning messages, and enable/disable the OK button. + */ +void +LoadPluginWindow::name_changed() +{ + string name = _node_name_entry->get_text(); + if (!Path::is_valid_name(name)) { + //m_message_label->set_text("Name contains invalid characters."); + _add_button->property_sensitive() = false; + } else if (_patch->get_node(name)) { + //m_message_label->set_text("An object already exists with that name."); + _add_button->property_sensitive() = false; + } else if (name.length() == 0) { + //m_message_label->set_text(""); + _add_button->property_sensitive() = false; + } else { + //m_message_label->set_text(""); + _add_button->property_sensitive() = true; + } +} + + +/** Sets the patch controller for this window and initializes everything. + * + * This function MUST be called before using the window in any way! + */ +void +LoadPluginWindow::set_patch(SharedPtr patch) +{ + _patch = patch; + + if (patch->poly() <= 1) + _polyphonic_checkbutton->property_sensitive() = false; + else + _polyphonic_checkbutton->property_sensitive() = true; + +} + + +/** Populates the plugin list on the first show. + * + * This is done here instead of construction time as the list population is + * really expensive and bogs down creation of a patch. This is especially + * important when many patch notifications are sent at one time from the + * engine. + */ +void +LoadPluginWindow::on_show() +{ + if (!_has_shown) { + set_plugin_list(App::instance().store()->plugins()); + + // Center on patch window + /*int _w, _h; + get_size(_w, _h); + + int parent_x, parent_y, parent_w, parent_h; + _patch_controller->window()->get_position(parent_x, parent_y); + _patch_controller->window()->get_size(parent_w, parent_h); + + move(parent_x + parent_w/2 - _w/2, parent_y + parent_h/2 - _h/2); + */ + _has_shown = true; + } + Gtk::Window::on_show(); +} + + +int +LoadPluginWindow::plugin_compare(const Gtk::TreeModel::iterator& a_i, + const Gtk::TreeModel::iterator& b_i) +{ + SharedPtr a = a_i->get_value(_plugins_columns._col_plugin_model); + SharedPtr b = b_i->get_value(_plugins_columns._col_plugin_model); + + // FIXME: haaack + if (!a && !b) + return 0; + else if (!a) + return 1; + else if (!b) + return -1; + + if (a->type() == b->type()) + return strcmp(a->name().c_str(), b->name().c_str()); + else + return ((int)a->type() < (int)b->type()) ? -1 : 1; +} + + +void +LoadPluginWindow::set_plugin_list(const std::map >& m) +{ + _plugins_liststore->clear(); + + for (std::map >::const_iterator i = m.begin(); i != m.end(); ++i) { + SharedPtr plugin = (*i).second; + + Gtk::TreeModel::iterator iter = _plugins_liststore->append(); + Gtk::TreeModel::Row row = *iter; + + row[_plugins_columns._col_name] = plugin->name(); + //row[_plugins_columns._col_label] = plugin->plug_label(); + if (plugin->type_uri() == "ingen:Internal") + row[_plugins_columns._col_type] = "Internal"; + else if (plugin->type_uri() == "ingen:LV2") + row[_plugins_columns._col_type] = "LV2"; + else if (plugin->type_uri() == "ingen:DSSI") + row[_plugins_columns._col_type] = "DSSI"; + else if (plugin->type_uri() == "ingen:LADSPA") + row[_plugins_columns._col_type] = "LADSPA"; + else + row[_plugins_columns._col_type] = plugin->type_uri(); + row[_plugins_columns._col_uri] = plugin->uri(); + row[_plugins_columns._col_label] = plugin->name(); + //row[_plugins_columns._col_library] = plugin->lib_name(); + row[_plugins_columns._col_plugin_model] = plugin; + } + + _plugins_liststore->set_sort_column(Gtk::TreeSortable::DEFAULT_SORT_COLUMN_ID, Gtk::SORT_ASCENDING); + + _plugins_treeview->columns_autosize(); +} + + +void +LoadPluginWindow::add_plugin(SharedPtr plugin) +{ + Gtk::TreeModel::iterator iter = _plugins_liststore->append(); + Gtk::TreeModel::Row row = *iter; + + row[_plugins_columns._col_name] = plugin->name(); + //row[_plugins_columns._col_label] = plugin->plug_label(); + row[_plugins_columns._col_type] = plugin->type_uri(); + row[_plugins_columns._col_uri] = plugin->uri(); + row[_plugins_columns._col_label] = plugin->name(); + //row[_plugins_columns._col_library] = plugin->lib_name(); + row[_plugins_columns._col_plugin_model] = plugin; +} + + + +///// Event Handlers ////// + + +void +LoadPluginWindow::plugin_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col) +{ + add_clicked(); +} + + +void +LoadPluginWindow::plugin_selection_changed() +{ + _plugin_name_offset = 0; + + _node_name_entry->set_text(generate_module_name()); + + //Gtk::TreeModel::iterator iter = _selection->get_selected(); + //Gtk::TreeModel::Row row = *iter; + //const PluginModel* plugin = row.get_value(_plugins_columns._col_plugin_model); +} + + +/** Generate an automatic name for this Node. + * + * Offset is an offset of the number that will be appended to the plugin's + * label, needed if the user adds multiple plugins faster than the engine + * sends the notification back. + */ +string +LoadPluginWindow::generate_module_name(int offset) +{ + string name = ""; + + Gtk::TreeModel::iterator iter = _selection->get_selected(); + + if (iter) { + Gtk::TreeModel::Row row = *iter; + SharedPtr plugin = row.get_value(_plugins_columns._col_plugin_model); + return plugin->default_node_name(_patch); + } + /*char num_buf[3]; + for (uint i=0; i < 99; ++i) { + name = plugin->default_node_name(); + if (name == "") + name = plugin->name().substr(0, plugin->name().find(' ')); + if (i+offset != 0) { + snprintf(num_buf, 3, "%d", i+offset+1); + name += "_"; + name += num_buf; + } + if (!_patch->get_node(name)) + break; + else + name = ""; + } + }*/ + + return name; +} + + +void +LoadPluginWindow::add_clicked() +{ + Gtk::TreeModel::iterator iter = _selection->get_selected(); + bool polyphonic = _polyphonic_checkbutton->get_active(); + + if (iter) { // If anything is selected + Gtk::TreeModel::Row row = *iter; + SharedPtr plugin = row.get_value(_plugins_columns._col_plugin_model); + string name = _node_name_entry->get_text(); + if (name == "") { + name = generate_module_name(); + } + if (name == "") { + Gtk::MessageDialog dialog(*this, + "Unable to chose a default name for this node. Please enter a name.", + false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + + dialog.run(); + } else { + Path path = _patch->path().base() + Path::nameify(name); + App::instance().engine()->create_node(path, plugin->uri(), polyphonic); + for (MetadataMap::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) + App::instance().engine()->set_metadata(path, i->first, i->second); + ++_plugin_name_offset; + _node_name_entry->set_text(generate_module_name(_plugin_name_offset)); + + // Set the next module location 20 over, for a cascade effect + cerr << "FIXME: cascade\n"; + //m_new_module_x += 20; + //m_new_module_y += 20; + } + } +} + + +/* +void +LoadPluginWindow::close_clicked() +{ + hide(); +} + + +void +LoadPluginWindow::ok_clicked() +{ + add_clicked(); + close_clicked(); +} +*/ + +void +LoadPluginWindow::filter_changed() +{ + _plugins_liststore->clear(); + + string search = _search_entry->get_text(); + transform(search.begin(), search.end(), search.begin(), toupper); + + // Get selected criteria + const Gtk::TreeModel::Row row = *(_filter_combo->get_active()); + CriteriaColumns::Criteria criteria = row[_criteria_columns._col_criteria]; + + string field; + + Gtk::TreeModel::Row model_row; + Gtk::TreeModel::iterator model_iter; + size_t num_visible = 0; + + + for (std::map >::const_iterator i = App::instance().store()->plugins().begin(); + i != App::instance().store()->plugins().end(); ++i) { + + const SharedPtr plugin = (*i).second; + + switch (criteria) { + case CriteriaColumns::NAME: + field = plugin->name(); break; + case CriteriaColumns::TYPE: + field = plugin->type_uri(); break; + case CriteriaColumns::URI: + field = plugin->uri(); break; + /*case CriteriaColumns::LIBRARY: + field = plugin->lib_name(); break; + case CriteriaColumns::LABEL: + field = plugin->plug_label(); break;*/ + default: + throw; + } + + transform(field.begin(), field.end(), field.begin(), toupper); + + if (field.find(search) != string::npos) { + model_iter = _plugins_liststore->append(); + model_row = *model_iter; + + model_row[_plugins_columns._col_name] = plugin->name(); + //model_row[_plugins_columns._col_label] = plugin->plug_label(); + model_row[_plugins_columns._col_type] = plugin->type_uri(); + model_row[_plugins_columns._col_uri] = plugin->uri(); + model_row[_plugins_columns._col_plugin_model] = plugin; + + ++num_visible; + } + } + + if (num_visible == 1) { + _selection->unselect_all(); + _selection->select(model_iter); + } +} + + +void +LoadPluginWindow::clear_clicked() +{ + _search_entry->set_text(""); + set_plugin_list(App::instance().store()->plugins()); +} + +bool +LoadPluginWindow::on_key_press_event(GdkEventKey* event) +{ + if (event->keyval == GDK_w && event->state & GDK_CONTROL_MASK) { + hide(); + return true; + } else { + return Gtk::Window::on_key_press_event(event); + } +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/LoadPluginWindow.h b/src/libs/gui/LoadPluginWindow.h new file mode 100644 index 00000000..1b39d314 --- /dev/null +++ b/src/libs/gui/LoadPluginWindow.h @@ -0,0 +1,151 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef LOADPLUGINWINDOW_H +#define LOADPLUGINWINDOW_H + +#include +#include +#include +#include +#include +#include "client/PatchModel.h" +#include "client/PluginModel.h" +using Ingen::Client::PluginModel; +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; + +namespace Ingen { +namespace GUI { + + +// Gtkmm _really_ needs to add some helper to abstract away this stupid nonsense + +/** Columns for the plugin list in the load plugin window. + * + * \ingroup GUI + */ +class ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + ModelColumns() { + add(_col_name); + add(_col_type); + add(_col_uri); + add(_col_label); + //add(_col_library); + //add(_col_label); + add(_col_plugin_model); + } + + Gtk::TreeModelColumn _col_name; + Gtk::TreeModelColumn _col_type; + Gtk::TreeModelColumn _col_uri; + + // Not displayed: + Gtk::TreeModelColumn _col_label; + Gtk::TreeModelColumn > _col_plugin_model; +}; + + +/** Column for the criteria combo box in the load plugin window. + * + * \ingroup GUI + */ +class CriteriaColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + enum Criteria { NAME, TYPE, URI, }; + + CriteriaColumns() { add(_col_label); add(_col_criteria); } + + Gtk::TreeModelColumn _col_label; + Gtk::TreeModelColumn _col_criteria; +}; + + +/** 'Load Plugin' window. + * + * Loaded by glade as a derived object. + * + * \ingroup GUI + */ +class LoadPluginWindow : public Gtk::Window +{ +public: + LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void set_patch(SharedPtr patch); + void set_plugin_list(const std::map >& m); + + void add_plugin(SharedPtr plugin); + bool has_shown() const { return _has_shown; } + + void present(SharedPtr patch, MetadataMap data); + +protected: + void on_show(); + bool on_key_press_event(GdkEventKey* event); + +private: + void add_clicked(); + //void close_clicked(); + //void ok_clicked(); + void filter_changed(); + void clear_clicked(); + void name_changed(); + + int plugin_compare(const Gtk::TreeModel::iterator& a, + const Gtk::TreeModel::iterator& b); + + void plugin_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col); + void plugin_selection_changed(); + string generate_module_name(int offset = 0); + + MetadataMap _initial_data; + + SharedPtr _patch; + + bool _has_shown; // plugin list only populated on show to speed patch window creation + + Glib::RefPtr _plugins_liststore; + ModelColumns _plugins_columns; + + Glib::RefPtr _criteria_liststore; + CriteriaColumns _criteria_columns; + + Glib::RefPtr _selection; + + int _plugin_name_offset; // see comments for generate_plugin_name + + Gtk::TreeView* _plugins_treeview; + Gtk::CheckButton* _polyphonic_checkbutton; + Gtk::Entry* _node_name_entry; + Gtk::Button* _clear_button; + Gtk::Button* _add_button; + //Gtk::Button* _close_button; + //Gtk::Button* _ok_button; + Gtk::ComboBox* _filter_combo; + Gtk::Entry* _search_entry; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // LOADPLUGINWINDOW_H diff --git a/src/libs/gui/LoadRemotePatchWindow.cpp b/src/libs/gui/LoadRemotePatchWindow.cpp new file mode 100644 index 00000000..534a6949 --- /dev/null +++ b/src/libs/gui/LoadRemotePatchWindow.cpp @@ -0,0 +1,163 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "LoadRemotePatchWindow.h" +#include +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "App.h" +#include "Configuration.h" +#include "ThreadedLoader.h" + +using boost::optional; +using namespace Raul; + +namespace Ingen { +namespace GUI { + + +LoadRemotePatchWindow::LoadRemotePatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::Dialog(cobject), + _replace(true) +{ + xml->get_widget("load_remote_patch_treeview", _treeview); + xml->get_widget("load_remote_patch_uri_entry", _uri_entry); + xml->get_widget("load_remote_patch_cancel_button", _cancel_button); + xml->get_widget("load_remote_patch_open_button", _open_button); + + _liststore = Gtk::ListStore::create(_columns); + _treeview->set_model(_liststore); + _treeview->append_column("Name", _columns._col_name); + _treeview->append_column("URI", _columns._col_uri); + + _selection = _treeview->get_selection(); + _selection->signal_changed().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::patch_selected)); + _treeview->signal_row_activated().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::patch_activated)); + + _open_button->signal_clicked().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::open_clicked)); + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::cancel_clicked)); + _uri_entry->signal_changed().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::uri_changed)); +} + + +void +LoadRemotePatchWindow::present(SharedPtr patch, MetadataMap data) +{ + _liststore->clear(); + + set_patch(patch); + _initial_data = data; + + RDF::Model model(*App::instance().rdf_world(), + "http://rdf.drobilla.net/ingen_patches/index.ttl", + "http://rdf.drobilla.net/ingen_patches/"); + + RDF::Query query(*App::instance().rdf_world(), Glib::ustring( + "SELECT DISTINCT ?name ?uri WHERE {" + " ?uri a ingen:Patch ;" + " doap:name ?name ." + "}")); + + RDF::Query::Results results = query.run(*App::instance().rdf_world(), model); + + for (RDF::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { + Gtk::TreeModel::iterator iter = _liststore->append(); + (*iter)[_columns._col_name] = (*i)["name"].to_string(); + (*iter)[_columns._col_uri] = (*i)["uri"].to_string(); + } + + _treeview->columns_autosize(); + + Gtk::Window::present(); +} + + +/** Sets the patch controller for this window and initializes everything. + * + * This function MUST be called before using the window in any way! + */ +void +LoadRemotePatchWindow::set_patch(SharedPtr patch) +{ + _patch = patch; +} + + +void +LoadRemotePatchWindow::uri_changed() +{ + _open_button->property_sensitive() = (_uri_entry->get_text().length() > 0); +} + + +void +LoadRemotePatchWindow::patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col) +{ + open_clicked(); +} + + +void +LoadRemotePatchWindow::patch_selected() +{ + Gtk::TreeModel::iterator selected_i = _selection->get_selected(); + + if (selected_i) { // If anything is selected + const Glib::ustring uri = selected_i->get_value(_columns._col_uri); + _uri_entry->set_text(uri); + } +} + + +void +LoadRemotePatchWindow::open_clicked() +{ + Glib::ustring uri = _uri_entry->get_text(); + + cerr << "OPEN URI: " << uri << endl; + + // If unset load_patch will load values + optional name; + optional poly; + + optional parent; + + if (_replace) + App::instance().engine()->clear_patch(_patch->path()); + + if (_patch->path() != "/") + parent = _patch->path().parent(); + + App::instance().loader()->load_patch(true, uri, "/", + _initial_data, parent, name, poly); + + hide(); +} + + +void +LoadRemotePatchWindow::cancel_clicked() +{ + hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/LoadRemotePatchWindow.h b/src/libs/gui/LoadRemotePatchWindow.h new file mode 100644 index 00000000..bbb3d93e --- /dev/null +++ b/src/libs/gui/LoadRemotePatchWindow.h @@ -0,0 +1,93 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LOADREMOTEPATCHWINDOW_H +#define LOADREMOTEPATCHWINDOW_H + +#include +#include +#include +#include "client/PatchModel.h" +#include "client/PluginModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; + +namespace Ingen { +namespace GUI { + + +/** Columns for the remote patch list. + * + * \ingroup GUI + */ +class PatchColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + PatchColumns() { + add(_col_name); + add(_col_uri); + } + + Gtk::TreeModelColumn _col_name; + Gtk::TreeModelColumn _col_uri; +}; + + + +/* Load remote patch ("import location") dialog. + * + * \ingroup GUI + */ +class LoadRemotePatchWindow : public Gtk::Dialog +{ +public: + LoadRemotePatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void set_patch(SharedPtr patch); + + void set_replace() { _replace = true; } + void set_merge() { _replace = false; } + + void present(SharedPtr patch, MetadataMap data); + +private: + void patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col); + void patch_selected(); + void uri_changed(); + void open_clicked(); + void cancel_clicked(); + + MetadataMap _initial_data; + + SharedPtr _patch; + bool _replace; + + Glib::RefPtr _selection; + Glib::RefPtr _liststore; + PatchColumns _columns; + + Gtk::TreeView* _treeview; + Gtk::Entry* _uri_entry; + Gtk::Button* _open_button; + Gtk::Button* _cancel_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // LOADREMOTEPATCHWINDOW_H diff --git a/src/libs/gui/LoadSubpatchWindow.cpp b/src/libs/gui/LoadSubpatchWindow.cpp new file mode 100644 index 00000000..57fa9adc --- /dev/null +++ b/src/libs/gui/LoadSubpatchWindow.cpp @@ -0,0 +1,175 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/NodeModel.h" +#include "client/PatchModel.h" +#include "App.h" +#include "LoadSubpatchWindow.h" +#include "PatchView.h" +#include "Configuration.h" +#include "ThreadedLoader.h" +using boost::optional; + +namespace Ingen { +namespace GUI { + + +LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::FileChooserDialog(cobject) +{ + xml->get_widget("load_subpatch_name_from_file_radio", _name_from_file_radio); + xml->get_widget("load_subpatch_name_from_user_radio", _name_from_user_radio); + xml->get_widget("load_subpatch_name_entry", _name_entry); + xml->get_widget("load_subpatch_poly_from_file_radio", _poly_from_file_radio); + xml->get_widget("load_subpatch_poly_from_parent_radio", _poly_from_parent_radio); + xml->get_widget("load_subpatch_poly_from_user_radio", _poly_from_user_radio); + xml->get_widget("load_subpatch_poly_spinbutton", _poly_spinbutton); + xml->get_widget("load_subpatch_ok_button", _ok_button); + xml->get_widget("load_subpatch_cancel_button", _cancel_button); + + _name_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_name_entry)); + _name_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_name_entry)); + _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); + _poly_from_parent_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); + _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_poly_spinner)); + _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::ok_clicked)); + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::cancel_clicked)); + + Gtk::FileFilter filt; + filt.add_pattern("*.om"); + filt.set_name("Om patch files (XML, DEPRECATED) (*.om)"); + filt.add_pattern("*.ingen.ttl"); + filt.set_name("Ingen patch files (RDF, *.ingen.ttl)"); + set_filter(filt); + + // Add global examples directory to "shortcut folders" (bookmarks) + string examples_dir = PKGDATADIR; + examples_dir.append("/patches"); + DIR* d = opendir(examples_dir.c_str()); + if (d != NULL) + add_shortcut_folder(examples_dir); +} + + +void +LoadSubpatchWindow::present(SharedPtr patch, MetadataMap data) +{ + set_patch(patch); + _initial_data = data; + Gtk::Window::present(); +} + + +/** Sets the patch controller for this window and initializes everything. + * + * This function MUST be called before using the window in any way! + */ +void +LoadSubpatchWindow::set_patch(SharedPtr patch) +{ + _patch = patch; + + char temp_buf[4]; + snprintf(temp_buf, 4, "%zd", patch->poly()); + Glib::ustring txt = "Same as parent ("; + txt.append(temp_buf).append(")"); + _poly_from_parent_radio->set_label(txt); +} + + +void +LoadSubpatchWindow::on_show() +{ + if (App::instance().configuration()->patch_folder().length() > 0) + set_current_folder(App::instance().configuration()->patch_folder()); + Gtk::FileChooserDialog::on_show(); +} + + +///// Event Handlers ////// + + + +void +LoadSubpatchWindow::disable_name_entry() +{ + _name_entry->property_sensitive() = false; +} + + +void +LoadSubpatchWindow::enable_name_entry() +{ + _name_entry->property_sensitive() = true; +} + + +void +LoadSubpatchWindow::disable_poly_spinner() +{ + _poly_spinbutton->property_sensitive() = false; +} + + +void +LoadSubpatchWindow::enable_poly_spinner() +{ + _poly_spinbutton->property_sensitive() = true; +} + + +void +LoadSubpatchWindow::ok_clicked() +{ + assert(_patch); + + // If unset load_patch will load values + optional name; + optional poly; + string name_str = ""; + + if (_name_from_user_radio->get_active()) { + name_str = _name_entry->get_text(); + name = name_str; + } + + if (_poly_from_user_radio->get_active()) + poly = _poly_spinbutton->get_value_as_int(); + else if (_poly_from_parent_radio->get_active()) + poly = _patch->poly(); + + App::instance().loader()->load_patch(false, get_uri(), "/", + _initial_data, _patch->path(), name, poly); + + hide(); +} + + +void +LoadSubpatchWindow::cancel_clicked() +{ + hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/LoadSubpatchWindow.h b/src/libs/gui/LoadSubpatchWindow.h new file mode 100644 index 00000000..08a6f7db --- /dev/null +++ b/src/libs/gui/LoadSubpatchWindow.h @@ -0,0 +1,79 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LOADSUBPATCHWINDOW_H +#define LOADSUBPATCHWINDOW_H + +#include +#include +#include +#include "client/PatchModel.h" +#include "client/PluginModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; + +namespace Ingen { +namespace GUI { + + +/** 'Add Subpatch' window. + * + * Loaded by glade as a derived object. + * + * \ingroup GUI + */ +class LoadSubpatchWindow : public Gtk::FileChooserDialog +{ +public: + LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void set_patch(SharedPtr patch); + + void present(SharedPtr patch, MetadataMap data); + +protected: + void on_show(); + +private: + void disable_name_entry(); + void enable_name_entry(); + void disable_poly_spinner(); + void enable_poly_spinner(); + + void ok_clicked(); + void cancel_clicked(); + + MetadataMap _initial_data; + + SharedPtr _patch; + + Gtk::RadioButton* _name_from_file_radio; + Gtk::RadioButton* _name_from_user_radio; + Gtk::Entry* _name_entry; + Gtk::RadioButton* _poly_from_file_radio; + Gtk::RadioButton* _poly_from_parent_radio; + Gtk::RadioButton* _poly_from_user_radio; + Gtk::SpinButton* _poly_spinbutton; + Gtk::Button* _ok_button; + Gtk::Button* _cancel_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // LOADSUBPATCHWINDOW_H diff --git a/src/libs/gui/Makefile.am b/src/libs/gui/Makefile.am new file mode 100644 index 00000000..c94ebbb5 --- /dev/null +++ b/src/libs/gui/Makefile.am @@ -0,0 +1,104 @@ +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = ingen_gui.gladep + +globalpixmapsdir = $(datadir)/pixmaps +dist_globalpixmaps_DATA = ingen.svg ingen-icon.svg + +sharefilesdir = $(pkgdatadir) +dist_sharefiles_DATA = ingen_gui.glade ingen.svg ingen-icon.svg + +moduledir = $(libdir)/ingen + +module_LTLIBRARIES = libingen_gui.la + +libingen_gui_la_CXXFLAGS = \ + -DPKGDATADIR=\"$(pkgdatadir)\" \ + -DINGEN_MODULE_DIR=\"$(libdir)/ingen\" \ + -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED \ + @RAUL_CFLAGS@ @LOSC_CFLAGS@ @SLV2_CFLAGS@ @CURL_CFLAGS@ \ + @GTKMM_CFLAGS@ @LIBGLADEMM_CFLAGS@ @FLOWCANVAS_CFLAGS@ @GNOMECANVASMM_CFLAGS@ \ + -I$(top_srcdir)/src/common \ + -I$(top_srcdir)/src/libs + +libingen_gui_la_LDFLAGS = -no-undefined -module -avoid-version + +libingen_gui_la_LIBADD = \ + @RAUL_LIBS@ @LOSC_LIBS@ @SLV2_LIBS@ @CURL_LIBS@ \ + @GTKMM_LIBS@ @LIBGLADEMM_LIBS@ @FLOWCANVAS_LIBS@ @GNOMECANVASMM_LIBS@ \ + ../module/libingen_module.la \ + ../client/libingen_client.la + + +libingen_gui_la_SOURCES = \ + gui.h \ + gui.cpp \ + App.cpp \ + App.h \ + BreadCrumb.h \ + BreadCrumbBox.cpp \ + BreadCrumbBox.h \ + ConfigWindow.cpp \ + ConfigWindow.h \ + Configuration.cpp \ + Configuration.h \ + ConnectWindow.cpp \ + ConnectWindow.h \ + Connection.h \ + ControlGroups.cpp \ + ControlGroups.h \ + ControlPanel.cpp \ + ControlPanel.h \ + DSSIController.cpp \ + DSSIController.h \ + DSSIModule.cpp \ + DSSIModule.h \ + GladeFactory.cpp \ + GladeFactory.h \ + LoadPatchWindow.cpp \ + LoadPatchWindow.h \ + LoadPluginWindow.cpp \ + LoadPluginWindow.h \ + LoadRemotePatchWindow.cpp \ + LoadRemotePatchWindow.h \ + LoadSubpatchWindow.cpp \ + LoadSubpatchWindow.h \ + MessagesWindow.cpp \ + MessagesWindow.h \ + NewSubpatchWindow.cpp \ + NewSubpatchWindow.h \ + NodeControlWindow.cpp \ + NodeControlWindow.h \ + NodeMenu.cpp \ + NodeMenu.h \ + NodeModule.cpp \ + NodeModule.h \ + NodePropertiesWindow.cpp \ + NodePropertiesWindow.h \ + PatchCanvas.cpp \ + PatchCanvas.h \ + PatchPortModule.cpp \ + PatchPortModule.h \ + PatchPropertiesWindow.cpp \ + PatchPropertiesWindow.h \ + PatchTreeWindow.cpp \ + PatchTreeWindow.h \ + PatchView.cpp \ + PatchView.h \ + PatchWindow.cpp \ + PatchWindow.h \ + Port.cpp \ + Port.h \ + PortPropertiesWindow.cpp \ + PortPropertiesWindow.h \ + RenameWindow.cpp \ + RenameWindow.h \ + SubpatchModule.cpp \ + SubpatchModule.h \ + ThreadedLoader.cpp \ + ThreadedLoader.h \ + UploadPatchWindow.cpp \ + UploadPatchWindow.h \ + WindowFactory.cpp \ + WindowFactory.h + + diff --git a/src/libs/gui/MessagesWindow.cpp b/src/libs/gui/MessagesWindow.cpp new file mode 100644 index 00000000..b8a83c20 --- /dev/null +++ b/src/libs/gui/MessagesWindow.cpp @@ -0,0 +1,67 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "MessagesWindow.h" +#include + +namespace Ingen { +namespace GUI { +using std::string; + + +MessagesWindow::MessagesWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) +: Gtk::Window(cobject) +{ + glade_xml->get_widget("messages_textview", _textview); + glade_xml->get_widget("messages_clear_button", _clear_button); + glade_xml->get_widget("messages_close_button", _close_button); + + _clear_button->signal_clicked().connect(sigc::mem_fun(this, &MessagesWindow::clear_clicked)); + _close_button->signal_clicked().connect(sigc::mem_fun(this, &MessagesWindow::close_clicked)); +} + + +void +MessagesWindow::post(const string& msg) +{ + Glib::RefPtr text_buf = _textview->get_buffer(); + text_buf->insert(text_buf->end(), msg); + text_buf->insert(text_buf->end(), "\n"); + + if (!_clear_button->is_sensitive()) + _clear_button->set_sensitive(true); +} + + +void +MessagesWindow::close_clicked() +{ + hide(); +} + + +void +MessagesWindow::clear_clicked() +{ + Glib::RefPtr text_buf = _textview->get_buffer(); + text_buf->erase(text_buf->begin(), text_buf->end()); + _clear_button->set_sensitive(false); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/MessagesWindow.h b/src/libs/gui/MessagesWindow.h new file mode 100644 index 00000000..dea0fdd4 --- /dev/null +++ b/src/libs/gui/MessagesWindow.h @@ -0,0 +1,58 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MESSAGESWINDOW_H +#define MESSAGESWINDOW_H + +#include +#include +#include +using std::string; + + +namespace Ingen { +namespace GUI { + + +/** Messages Window. + * + * Loaded by libglade as a derived object. + * This is shown when errors occur (ie during patch loading). + * + * \ingroup GUI + */ +class MessagesWindow : public Gtk::Window +{ +public: + MessagesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); + + void post(const string& str); + +private: + void clear_clicked(); + void close_clicked(); + + Gtk::TextView* _textview; + Gtk::Button* _clear_button; + Gtk::Button* _close_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // MESSAGESWINDOW_H diff --git a/src/libs/gui/NewSubpatchWindow.cpp b/src/libs/gui/NewSubpatchWindow.cpp new file mode 100644 index 00000000..f0bc7caa --- /dev/null +++ b/src/libs/gui/NewSubpatchWindow.cpp @@ -0,0 +1,111 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "App.h" +#include "interface/EngineInterface.h" +#include "client/NodeModel.h" +#include "client/PatchModel.h" +#include "NewSubpatchWindow.h" +#include "PatchView.h" + +namespace Ingen { +namespace GUI { + + +NewSubpatchWindow::NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::Window(cobject) +{ + xml->get_widget("new_subpatch_name_entry", _name_entry); + xml->get_widget("new_subpatch_message_label", _message_label); + xml->get_widget("new_subpatch_polyphony_spinbutton", _poly_spinbutton); + xml->get_widget("new_subpatch_ok_button", _ok_button); + xml->get_widget("new_subpatch_cancel_button", _cancel_button); + + _name_entry->signal_changed().connect(sigc::mem_fun(this, &NewSubpatchWindow::name_changed)); + _ok_button->signal_clicked().connect(sigc::mem_fun(this, &NewSubpatchWindow::ok_clicked)); + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &NewSubpatchWindow::cancel_clicked)); + + _ok_button->property_sensitive() = false; +} + +void +NewSubpatchWindow::present(SharedPtr patch, MetadataMap data) +{ + set_patch(patch); + _initial_data = data; + Gtk::Window::present(); +} + +/** Sets the patch controller for this window and initializes everything. + * + * This function MUST be called before using the window in any way! + */ +void +NewSubpatchWindow::set_patch(SharedPtr patch) +{ + _patch = patch; +} + + +/** Called every time the user types into the name input box. + * Used to display warning messages, and enable/disable the OK button. + */ +void +NewSubpatchWindow::name_changed() +{ + string name = _name_entry->get_text(); + if (!Path::is_valid_name(name)) { + _message_label->set_text("Name contains invalid characters."); + _ok_button->property_sensitive() = false; + } else if (_patch->get_node(name)) { + _message_label->set_text("An object already exists with that name."); + _ok_button->property_sensitive() = false; + } else if (name.length() == 0) { + _message_label->set_text(""); + _ok_button->property_sensitive() = false; + } else { + _message_label->set_text(""); + _ok_button->property_sensitive() = true; + } +} + + +void +NewSubpatchWindow::ok_clicked() +{ + const Path path = _patch->path().base() + Path::nameify(_name_entry->get_text()); + const size_t poly = _poly_spinbutton->get_value_as_int(); + + App::instance().engine()->create_patch(path, poly); + for (MetadataMap::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) + App::instance().engine()->set_metadata(path, i->first, i->second); + + App::instance().engine()->enable_patch(path); + + hide(); +} + + +void +NewSubpatchWindow::cancel_clicked() +{ + hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/NewSubpatchWindow.h b/src/libs/gui/NewSubpatchWindow.h new file mode 100644 index 00000000..e70b7f91 --- /dev/null +++ b/src/libs/gui/NewSubpatchWindow.h @@ -0,0 +1,67 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NEWSUBPATCHWINDOW_H +#define NEWSUBPATCHWINDOW_H + +#include +#include +#include +#include "client/PatchModel.h" +#include "client/PluginModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; + +namespace Ingen { +namespace GUI { + + +/** 'New Subpatch' window. + * + * Loaded by glade as a derived object. + * + * \ingroup GUI + */ +class NewSubpatchWindow : public Gtk::Window +{ +public: + NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void set_patch(SharedPtr patch); + + void present(SharedPtr patch, MetadataMap data); + +private: + void name_changed(); + void ok_clicked(); + void cancel_clicked(); + + MetadataMap _initial_data; + SharedPtr _patch; + + Gtk::Entry* _name_entry; + Gtk::Label* _message_label; + Gtk::SpinButton* _poly_spinbutton; + Gtk::Button* _ok_button; + Gtk::Button* _cancel_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // NEWSUBPATCHWINDOW_H diff --git a/src/libs/gui/NodeControlWindow.cpp b/src/libs/gui/NodeControlWindow.cpp new file mode 100644 index 00000000..26108833 --- /dev/null +++ b/src/libs/gui/NodeControlWindow.cpp @@ -0,0 +1,136 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License alongCont + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/NodeModel.h" +#include "App.h" +#include "NodeControlWindow.h" +#include "GladeFactory.h" +#include "ControlGroups.h" +#include "ControlPanel.h" +#include "PatchWindow.h" + +using namespace std; + +namespace Ingen { +namespace GUI { + + +/** Create a node control window and load a new ControlPanel for it. + */ +NodeControlWindow::NodeControlWindow(SharedPtr node, size_t poly) +: _node(node), + _position_stored(false), + _x(0), _y(0) +{ + assert(_node != NULL); + + property_resizable() = true; + set_border_width(5); + + set_title(_node->path() + " Controls"); + + Glib::RefPtr xml = GladeFactory::new_glade_reference("warehouse_win"); + xml->get_widget_derived("control_panel_vbox", _control_panel); + _control_panel->reparent(*this); + + _control_panel->init(_node, poly); + + show_all_children(); + resize(); + + _callback_enabled = true; +} + + +/** Create a node control window and with an existing ControlPanel. + */ +NodeControlWindow::NodeControlWindow(SharedPtr node, ControlPanel* panel) +: _node(node), + _control_panel(panel) +{ + assert(_node); + + property_resizable() = true; + set_border_width(5); + + set_title(_node->path() + " Controls"); + + _control_panel->reparent(*this); + + show_all_children(); + resize(); + + _callback_enabled = true; +} + + +NodeControlWindow::~NodeControlWindow() +{ + delete _control_panel; +} + + +void +NodeControlWindow::resize() +{ + pair controls_size = _control_panel->ideal_size(); + /*int width = 400; + int height = controls_size.second + + ((_node->polyphonic()) ? 4 : 40);*/ + int width = controls_size.first; + int height = controls_size.second; + + if (height > property_screen().get_value()->get_height() - 64) + height = property_screen().get_value()->get_height() - 64; + if (width > property_screen().get_value()->get_width() - 64) + width = property_screen().get_value()->get_width() - 64; + + //cerr << "Resizing to: " << width << " x " << height << endl; + + Gtk::Window::resize(width, height); +} + + +void +NodeControlWindow::on_show() +{ + for (PortModelList::const_iterator i = _node->ports().begin(); + i != _node->ports().end(); ++i) + if ((*i)->is_control() && (*i)->is_input()) + App::instance().engine()->request_port_value((*i)->path()); + + if (_position_stored) + move(_x, _y); + + Gtk::Window::on_show(); +} + + +void +NodeControlWindow::on_hide() +{ + _position_stored = true; + get_position(_x, _y); + Gtk::Window::on_hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/NodeControlWindow.h b/src/libs/gui/NodeControlWindow.h new file mode 100644 index 00000000..bd6f9fc9 --- /dev/null +++ b/src/libs/gui/NodeControlWindow.h @@ -0,0 +1,76 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NODECONTROLWINDOW_H +#define NODECONTROLWINDOW_H + +#include +#include +#include +#include +#include +#include +using std::string; using std::vector; + +namespace Ingen { namespace Client { + class NodeModel; +} } +using Ingen::Client::NodeModel; + +namespace Ingen { +namespace GUI { + +class ControlGroup; +class ControlPanel; + + +/** Window with controls (sliders) for all control-rate ports on a Node. + * + * \ingroup GUI + */ +class NodeControlWindow : public Gtk::Window +{ +public: + NodeControlWindow(SharedPtr node, size_t poly); + NodeControlWindow(SharedPtr node, ControlPanel* panel); + virtual ~NodeControlWindow(); + + SharedPtr node() { return _node; } + + ControlPanel* control_panel() const { return _control_panel; } + + void resize(); + +protected: + void on_show(); + void on_hide(); + +private: + SharedPtr _node; + ControlPanel* _control_panel; + bool _callback_enabled; + + bool _position_stored; + int _x; + int _y; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // NODECONTROLWINDOW_H diff --git a/src/libs/gui/NodeMenu.cpp b/src/libs/gui/NodeMenu.cpp new file mode 100644 index 00000000..cf71989c --- /dev/null +++ b/src/libs/gui/NodeMenu.cpp @@ -0,0 +1,262 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/NodeModel.h" +#include "App.h" +#include "NodeMenu.h" +#include "WindowFactory.h" + +using std::cerr; using std::endl; + +namespace Ingen { +namespace GUI { + + +NodeMenu::NodeMenu(SharedPtr node) +: _node(node) +, _controls_menuitem(NULL) +{ + App& app = App::instance(); + + Gtk::Menu_Helpers::MenuElem controls_elem = Gtk::Menu_Helpers::MenuElem("Controls", + sigc::bind( + sigc::mem_fun(app.window_factory(), &WindowFactory::present_controls), + node)); + _controls_menuitem = controls_elem.get_child(); + items().push_back(controls_elem); + + items().push_back(Gtk::Menu_Helpers::SeparatorElem()); + + /*items().push_back(Gtk::Menu_Helpers::MenuElem("Rename...", + sigc::bind( + sigc::mem_fun(app.window_factory(), &WindowFactory::present_rename), + node)));*/ + /*items().push_back(Gtk::Menu_Helpers::MenuElem("Clone", + sigc::bind( + sigc::mem_fun(app.engine(), &EngineInterface::clone), + node))); + sigc::mem_fun(this, &NodeMenu::on_menu_clone)));*/ + + items().push_back(Gtk::Menu_Helpers::MenuElem("Disconnect All", + sigc::mem_fun(this, &NodeMenu::on_menu_disconnect_all))); + + items().push_back(Gtk::Menu_Helpers::MenuElem("Destroy", + sigc::mem_fun(this, &NodeMenu::on_menu_destroy))); + + //m_controls_menuitem->property_sensitive() = false; + + cerr << "FIXME: MIDI learn menu\n"; + /* + if (_node->plugin() && _node->plugin()->type() == PluginModel::Internal + && _node->plugin()->plug_label() == "midi_control_in") { + items().push_back(Gtk::Menu_Helpers::MenuElem("Learn", + sigc::mem_fun(this, &NodeMenu::on_menu_learn))); + } + */ + + items().push_back(Gtk::Menu_Helpers::SeparatorElem()); + + items().push_back(Gtk::Menu_Helpers::MenuElem("Properties", + sigc::bind( + sigc::mem_fun(app.window_factory(), &WindowFactory::present_properties), + node))); + + //model->new_port_sig.connect(sigc::mem_fun(this, &NodeMenu::add_port)); + //model->destroyed_sig.connect(sigc::mem_fun(this, &NodeMenu::destroy)); +} + +#if 0 +NodeMenu::~NodeMenu() +{ + cerr << "~NodeMenu()\n"; +} + +void +NodeMenu::destroy() +{ + cerr << "FIXME: NODE DESTROYED\n"; + //SharedPtr model = _model; + //m_model.reset(); +} +#endif + +void +NodeMenu::set_path(const Path& new_path) +{ + cerr << "FIXME: rename\n"; + /* + remove_from_store(); + + // Rename ports + for (list::const_iterator i = _node->ports().begin(); + i != _node->ports().end(); ++i) { + ObjectController* const pc = (*i)->controller(); + assert(pc != NULL); + pc->set_path(_model->path().base() + pc->model()->name()); + } + + // Handle bridge port, if this node represents one + if (_bridge_port != NULL) + _bridge_port->set_path(new_path); + + if (_module != NULL) + _module->canvas()->rename_module(_node->path().name(), new_path.name()); + + ObjectController::set_path(new_path); + + add_to_store(); + */ +} + +#if 0 +void +NodeMenu::destroy() +{ + PatchController* pc = ((PatchController*)_model->parent()->controller()); + assert(pc != NULL); + + //remove_from_store(); + //pc->remove_node(_model->path().name()); + cerr << "FIXME: remove node\n"; + + if (_bridge_port != NULL) + _bridge_port->destroy(); + _bridge_port = NULL; + + //if (_module != NULL) + // delete _module; +} +#endif + +#if 0 +void +NodeMenu::add_port(SharedPtr pm) +{ + assert(pm->parent().get() == _node.get()); + assert(pm->parent() == _node); + assert(_node->get_port(pm->path().name()) == pm); + + //cout << "[NodeMenu] Adding port " << pm->path() << endl; + + /* + if (_module != NULL) { + // (formerly PortController) + pc->create_port(_module); + _module->resize(); + + // Enable "Controls" menu item on module + if (has_control_inputs()) + enable_controls_menuitem(); + }*/ +} +#endif + +void +NodeMenu::on_menu_destroy() +{ + App::instance().engine()->destroy(_node->path()); +} + + +void +NodeMenu::on_menu_clone() +{ + cerr << "FIXME: clone broken\n"; + /* + assert(_node); + //assert(_parent != NULL); + //assert(_parent->model() != NULL); + + string clone_name = _node->name(); + int i = 2; // postfix number (ie oldname_2) + + // Check if name already has a number postfix + if (clone_name.find_last_of("_") != string::npos) { + string name_postfix = clone_name.substr(clone_name.find_last_of("_")+1); + clone_name = clone_name.substr(0, clone_name.find_last_of("_")); + if (sscanf(name_postfix.c_str(), "%d", &i)) + ++i; + } + + char clone_postfix[4]; + for ( ; i < 100; ++i) { + snprintf(clone_postfix, 4, "_%d", i); + if (_node->parent_patch()->get_node(clone_name + clone_postfix) == NULL) + break; + } + + clone_name = clone_name + clone_postfix; + + const string path = _node->parent_patch()->base() + clone_name; + NodeModel* nm = new NodeModel(_node->plugin(), path); + nm->polyphonic(_node->polyphonic()); + nm->x(_node->x() + 20); + nm->y(_node->y() + 20); + App::instance().engine()->create_node_from_model(nm); + */ +} + + +void +NodeMenu::on_menu_learn() +{ + App::instance().engine()->midi_learn(_node->path()); +} + +void +NodeMenu::on_menu_disconnect_all() +{ + App::instance().engine()->disconnect_all(_node->path()); +} + + +bool +NodeMenu::has_control_inputs() +{ + for (PortModelList::const_iterator i = _node->ports().begin(); + i != _node->ports().end(); ++i) + if ((*i)->is_input() && (*i)->is_control()) + return true; + + return false; +} + + +void +NodeMenu::enable_controls_menuitem() +{ + _controls_menuitem->property_sensitive() = true; +} + + +void +NodeMenu::disable_controls_menuitem() +{ + _controls_menuitem->property_sensitive() = false; + + //if (_control_window != NULL) + // _control_window->hide(); +} + + + +} // namespace GUI +} // namespace Ingen + diff --git a/src/libs/gui/NodeMenu.h b/src/libs/gui/NodeMenu.h new file mode 100644 index 00000000..65044608 --- /dev/null +++ b/src/libs/gui/NodeMenu.h @@ -0,0 +1,78 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NODEMENU_H +#define NODEMENU_H + +#include +#include +#include +#include +#include "client/NodeModel.h" +using Ingen::Client::NodeModel; + +using std::string; + +namespace Ingen { +namespace GUI { + +class Controller; +class NodeControlWindow; +class NodePropertiesWindow; +class PatchCanvas; + +/** Controller for a Node. + * + * \ingroup GUI + */ +class NodeMenu : public Gtk::Menu +{ +public: + NodeMenu(SharedPtr node); + + void set_path(const Path& new_path); + + virtual void program_add(int bank, int program, const string& name) {} + virtual void program_remove(int bank, int program) {} + + bool has_control_inputs(); + + //virtual void show_menu(GdkEventButton* event) + //{ _menu.popup(event->button, event->time); } + +protected: + + virtual void enable_controls_menuitem(); + virtual void disable_controls_menuitem(); + + //virtual void add_port(SharedPtr pm); + + void on_menu_destroy(); + void on_menu_clone(); + void on_menu_learn(); + void on_menu_disconnect_all(); + + //Gtk::Menu _menu; + SharedPtr _node; + Glib::RefPtr _controls_menuitem; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // NODEMENU_H diff --git a/src/libs/gui/NodeModule.cpp b/src/libs/gui/NodeModule.cpp new file mode 100644 index 00000000..3c80f5e2 --- /dev/null +++ b/src/libs/gui/NodeModule.cpp @@ -0,0 +1,153 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "client/NodeModel.h" +#include "App.h" +#include "NodeModule.h" +#include "PatchCanvas.h" +#include "Port.h" +#include "GladeFactory.h" +#include "RenameWindow.h" +#include "PatchWindow.h" +#include "WindowFactory.h" +#include "SubpatchModule.h" +#include "NodeControlWindow.h" + +namespace Ingen { +namespace GUI { + + +NodeModule::NodeModule(boost::shared_ptr canvas, SharedPtr node) +: LibFlowCanvas::Module(canvas, node->path().name()), + _node(node), + _menu(node) +{ + assert(_node); + + if (node->polyphonic()) { + set_border_width(2.0); + } + + node->new_port_sig.connect(sigc::bind(sigc::mem_fun(this, &NodeModule::add_port), true)); + node->removed_port_sig.connect(sigc::mem_fun(this, &NodeModule::remove_port)); + node->metadata_update_sig.connect(sigc::mem_fun(this, &NodeModule::metadata_update)); + + signal_clicked.connect(sigc::mem_fun(this, &NodeModule::on_click)); +} + + +NodeModule::~NodeModule() +{ + NodeControlWindow* win = App::instance().window_factory()->control_window(_node); + + if (win) { + // Should remove from window factory via signal + delete win; + } +} + + +boost::shared_ptr +NodeModule::create(boost::shared_ptr canvas, SharedPtr node) +{ + boost::shared_ptr ret; + + SharedPtr patch = PtrCast(node); + if (patch) + ret = boost::shared_ptr(new SubpatchModule(canvas, patch)); + else + ret = boost::shared_ptr(new NodeModule(canvas, node)); + + for (MetadataMap::const_iterator m = node->metadata().begin(); m != node->metadata().end(); ++m) + ret->metadata_update(m->first, m->second); + + for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) + ret->add_port(*p, false); + + ret->resize(); + + return ret; +} + + +void +NodeModule::add_port(SharedPtr port, bool resize_to_fit) +{ + Module::add_port(boost::shared_ptr(new Port( + PtrCast(shared_from_this()), port))); + + if (resize_to_fit) + resize(); +} + + +void +NodeModule::remove_port(SharedPtr port) +{ + SharedPtr p = Module::remove_port(port->path().name()); + p.reset(); +} + + +void +NodeModule::show_control_window() +{ + App::instance().window_factory()->present_controls(_node); +} + + +void +NodeModule::store_location() +{ + const float x = static_cast(property_x()); + const float y = static_cast(property_y()); + + const Atom& existing_x = _node->get_metadata("ingenuity:canvas-x"); + const Atom& existing_y = _node->get_metadata("ingenuity:canvas-y"); + + if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT + || existing_x.get_float() != x || existing_y.get_float() != y) { + App::instance().engine()->set_metadata(_node->path(), "ingenuity:canvas-x", Atom(x)); + App::instance().engine()->set_metadata(_node->path(), "ingenuity:canvas-y", Atom(y)); + } +} + + +void +NodeModule::on_click(GdkEventButton* event) +{ + if (event->button == 3) + _menu.popup(event->button, event->time); +} + + +void +NodeModule::metadata_update(const string& key, const Atom& value) +{ + if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT) + move_to(value.get_float(), property_y()); + else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT) + move_to(property_x(), value.get_float()); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/NodeModule.h b/src/libs/gui/NodeModule.h new file mode 100644 index 00000000..8e88b34c --- /dev/null +++ b/src/libs/gui/NodeModule.h @@ -0,0 +1,90 @@ +/* This file is part of In* Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NODEMODULE_H +#define NODEMODULE_H + +#include +#include +#include +#include +#include "Port.h" +#include "NodeMenu.h" +using std::string; + +class Atom; + +namespace Ingen { namespace Client { + class PortModel; + class NodeModel; + class ControlModel; +} } +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + +class PatchCanvas; +class Port; + + +/** A module in a patch. + * + * This base class is extended for various types of modules - SubpatchModule, + * DSSIModule, etc. + * + * \ingroup GUI + */ +class NodeModule : public LibFlowCanvas::Module +{ +public: + static boost::shared_ptr create (boost::shared_ptr canvas, SharedPtr node); + + virtual ~NodeModule(); + + boost::shared_ptr port(const string& port_name) { + return boost::dynamic_pointer_cast( + Module::get_port(port_name)); + } + + virtual void store_location(); + + void on_click(GdkEventButton* event); + + void show_control_window(); + + SharedPtr node() const { return _node; } + +protected: + NodeModule(boost::shared_ptr canvas, SharedPtr node); + + virtual void on_double_click(GdkEventButton* ev) { show_control_window(); } + virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); } + + void metadata_update(const string& key, const Atom& value); + + void add_port(SharedPtr port, bool resize=true); + void remove_port(SharedPtr port); + + SharedPtr _node; + NodeMenu _menu; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // NODEMODULE_H diff --git a/src/libs/gui/NodePropertiesWindow.cpp b/src/libs/gui/NodePropertiesWindow.cpp new file mode 100644 index 00000000..0cd59e80 --- /dev/null +++ b/src/libs/gui/NodePropertiesWindow.cpp @@ -0,0 +1,67 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "client/NodeModel.h" +#include "client/PluginModel.h" +#include "NodePropertiesWindow.h" + +namespace Ingen { +namespace GUI { +using std::string; + + +NodePropertiesWindow::NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) +: Gtk::Window(cobject) +{ + glade_xml->get_widget("node_properties_path_label", _node_path_label); + glade_xml->get_widget("node_properties_polyphonic_checkbutton", _node_polyphonic_toggle); + glade_xml->get_widget("node_properties_plugin_type_label", _plugin_type_label); + glade_xml->get_widget("node_properties_plugin_uri_label", _plugin_uri_label); + glade_xml->get_widget("node_properties_plugin_name_label", _plugin_name_label); +} + + +/** Set the node this window is associated with. + * This function MUST be called before using this object in any way. + */ +void +NodePropertiesWindow::set_node(SharedPtr node_model) +{ + assert(node_model); + + _node_model = node_model; + + set_title(node_model->path() + " Properties"); + + _node_path_label->set_text(node_model->path()); + _node_polyphonic_toggle->set_active(node_model->polyphonic()); + + SharedPtr pm = node_model->plugin(); + + if (pm) { + _plugin_type_label->set_text(pm->type_uri()); + _plugin_uri_label->set_text(pm->uri()); + _plugin_name_label->set_text(pm->name()); + } +} + + +} // namespace GUI +} // namespace Ingen + diff --git a/src/libs/gui/NodePropertiesWindow.h b/src/libs/gui/NodePropertiesWindow.h new file mode 100644 index 00000000..057de4ec --- /dev/null +++ b/src/libs/gui/NodePropertiesWindow.h @@ -0,0 +1,58 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NODEPROPERTIESWINDOW_H +#define NODEPROPERTIESWINDOW_H + +#include +#include +#include +#include "client/NodeModel.h" +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + + +/** Node properties window. + * + * Loaded by libglade as a derived object. + * + * \ingroup GUI + */ +class NodePropertiesWindow : public Gtk::Window +{ +public: + NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); + + void present(SharedPtr node_model) { set_node(node_model); Gtk::Window::present(); } + void set_node(SharedPtr node_model); + +private: + + SharedPtr _node_model; + Gtk::Label* _node_path_label; + Gtk::CheckButton* _node_polyphonic_toggle; + Gtk::Label* _plugin_type_label; + Gtk::Label* _plugin_uri_label; + Gtk::Label* _plugin_name_label; +}; + +} // namespace GUI +} // namespace Ingen + +#endif // NODEPROPERTIESWINDOW_H diff --git a/src/libs/gui/PatchCanvas.cpp b/src/libs/gui/PatchCanvas.cpp new file mode 100644 index 00000000..623d0c7c --- /dev/null +++ b/src/libs/gui/PatchCanvas.cpp @@ -0,0 +1,525 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/PluginModel.h" +#include "client/PatchModel.h" +#include "client/NodeModel.h" +#include "client/Store.h" +#include "client/Serializer.h" +#include "App.h" +#include "PatchCanvas.h" +#include "PatchWindow.h" +#include "PatchPortModule.h" +#include "LoadPluginWindow.h" +#include "LoadSubpatchWindow.h" +#include "NewSubpatchWindow.h" +#include "Port.h" +#include "Connection.h" +#include "NodeModule.h" +#include "SubpatchModule.h" +#include "GladeFactory.h" +#include "WindowFactory.h" +#include "config.h" +using Ingen::Client::Store; +using Ingen::Client::Serializer; +using Ingen::Client::PluginModel; + +namespace Ingen { +namespace GUI { + + +PatchCanvas::PatchCanvas(SharedPtr patch, int width, int height) +: FlowCanvas(width, height), + _patch(patch), + _last_click_x(0), + _last_click_y(0) +{ + Glib::RefPtr xml = GladeFactory::new_glade_reference(); + xml->get_widget("canvas_menu", _menu); + + xml->get_widget("canvas_menu_add_audio_input", _menu_add_audio_input); + xml->get_widget("canvas_menu_add_audio_output", _menu_add_audio_output); + xml->get_widget("canvas_menu_add_control_input", _menu_add_control_input); + xml->get_widget("canvas_menu_add_control_output", _menu_add_control_output); + xml->get_widget("canvas_menu_add_midi_input", _menu_add_midi_input); + xml->get_widget("canvas_menu_add_midi_output", _menu_add_midi_output); + xml->get_widget("canvas_menu_load_plugin", _menu_load_plugin); + xml->get_widget("canvas_menu_load_patch", _menu_load_patch); + xml->get_widget("canvas_menu_new_patch", _menu_new_patch); + + // Add port menu items + _menu_add_audio_input->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), + "audio_input", "ingen:audio", false)); + _menu_add_audio_output->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), + "audio_output", "ingen:audio", true)); + _menu_add_control_input->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), + "control_input", "ingen:control", false)); + _menu_add_control_output->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), + "control_output", "ingen:control", true)); + _menu_add_midi_input->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), + "midi_input", "ingen:midi", false)); + _menu_add_midi_output->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), + "midi_output", "ingen:midi", true)); + + build_plugin_menu(); + + // Connect to model signals to track state + _patch->new_node_sig.connect(sigc::mem_fun(this, &PatchCanvas::add_node)); + _patch->removed_node_sig.connect(sigc::mem_fun(this, &PatchCanvas::remove_node)); + _patch->new_port_sig.connect(sigc::mem_fun(this, &PatchCanvas::add_port)); + _patch->removed_port_sig.connect(sigc::mem_fun(this, &PatchCanvas::remove_port)); + _patch->new_connection_sig.connect(sigc::mem_fun(this, &PatchCanvas::connection)); + _patch->removed_connection_sig.connect(sigc::mem_fun(this, &PatchCanvas::disconnection)); + + // Connect widget signals to do things + _menu_load_plugin->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_load_plugin)); + _menu_load_patch->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_load_patch)); + _menu_new_patch->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_new_patch)); +} + + +void +PatchCanvas::build_plugin_class_menu(Gtk::Menu* menu, + SLV2PluginClass plugin_class, SLV2PluginClasses classes) +{ +#ifdef HAVE_SLV2 + // Add submenus + for (unsigned i=0; i < slv2_plugin_classes_size(classes); ++i) { + SLV2PluginClass c = slv2_plugin_classes_get_at(classes, i); + const char* parent = slv2_plugin_class_get_parent_uri(c); + + if (parent && !strcmp(parent, slv2_plugin_class_get_uri(plugin_class))) { + menu->items().push_back(Gtk::Menu_Helpers::MenuElem( + slv2_plugin_class_get_label(c))); + Gtk::MenuItem* menu_item = &(menu->items().back()); + Gtk::Menu* submenu = Gtk::manage(new Gtk::Menu()); + menu_item->set_submenu(*submenu); + build_plugin_class_menu(submenu, c, classes); + } + } + + + const Store::Plugins& plugins = App::instance().store()->plugins(); + + // Add plugins + for (Store::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) { + SLV2Plugin p = i->second->slv2_plugin(); + if (p && slv2_plugin_get_class(p) == plugin_class) + menu->items().push_back(Gtk::Menu_Helpers::MenuElem(i->second->name(), + sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), + i->second))); + } + + +#endif +} + + +void +PatchCanvas::build_plugin_menu() +{ +#ifdef HAVE_SLV2 + _menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem("Plugin", + *(manage(new Gtk::Image(Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU))))); + Gtk::MenuItem* plugin_menu_item = &(_menu->items().back()); + Gtk::Menu* plugin_menu = Gtk::manage(new Gtk::Menu()); + plugin_menu_item->set_submenu(*plugin_menu); + _menu->reorder_child(*plugin_menu_item, 2); + + SLV2PluginClass lv2_plugin = slv2_world_get_plugin_class(PluginModel::slv2_world()); + SLV2PluginClasses classes = slv2_world_get_plugin_classes(PluginModel::slv2_world()); + + build_plugin_class_menu(plugin_menu, lv2_plugin, classes); +#endif +} + + +void +PatchCanvas::build() +{ + boost::shared_ptr shared_this = + boost::dynamic_pointer_cast(shared_from_this()); + + // Create modules for nodes + for (NodeModelMap::const_iterator i = _patch->nodes().begin(); + i != _patch->nodes().end(); ++i) { + add_node((*i).second); + } + + // Create pseudo modules for ports (ports on this canvas, not on our module) + for (PortModelList::const_iterator i = _patch->ports().begin(); + i != _patch->ports().end(); ++i) { + add_port(*i); + } + + // Create connections + for (list >::const_iterator i = _patch->connections().begin(); + i != _patch->connections().end(); ++i) { + connection(*i); + } +} + + +void +PatchCanvas::arrange() +{ + LibFlowCanvas::FlowCanvas::arrange(); + + for (list >::iterator i = _items.begin(); i != _items.end(); ++i) + (*i)->store_location(); +} + + +void +PatchCanvas::add_node(SharedPtr nm) +{ + boost::shared_ptr shared_this = + boost::dynamic_pointer_cast(shared_from_this()); + + SharedPtr pm = PtrCast(nm); + SharedPtr module; + if (pm) + module = SubpatchModule::create(shared_this, pm); + else + module = NodeModule::create(shared_this, nm); + + add_item(module); + module->show(); + _views.insert(std::make_pair(nm, module)); +} + + +void +PatchCanvas::remove_node(SharedPtr nm) +{ + Views::iterator i = _views.find(nm); + + if (i != _views.end()) { + remove_item(i->second); + _views.erase(i); + } +} + + +void +PatchCanvas::add_port(SharedPtr pm) +{ + boost::shared_ptr shared_this = + boost::dynamic_pointer_cast(shared_from_this()); + + SharedPtr view = PatchPortModule::create(shared_this, pm); + _views.insert(std::make_pair(pm, view)); + add_item(view); + view->show(); +} + + +void +PatchCanvas::remove_port(SharedPtr pm) +{ + Views::iterator i = _views.find(pm); + + if (i != _views.end()) { + remove_item(i->second); + _views.erase(i); + } +} + + +SharedPtr +PatchCanvas::get_port_view(SharedPtr port) +{ + SharedPtr ret; + SharedPtr module = _views[port]; + + // Port on this patch + if (module) { + ret = (PtrCast(module)) + ? *(PtrCast(module)->ports().begin()) + : PtrCast(module); + } else { + module = PtrCast(_views[port->parent()]); + if (module) + ret = module->get_port(port->path().name()); + } + + return ret; +} + + +void +PatchCanvas::connection(SharedPtr cm) +{ + const SharedPtr src = get_port_view(cm->src_port()); + const SharedPtr dst = get_port_view(cm->dst_port()); + + if (src && dst) + add_connection(boost::shared_ptr(new Connection(shared_from_this(), + cm, src, dst, src->color() + 0x22222200))); + else + cerr << "[PatchCanvas] ERROR: Unable to find ports to connect " + << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; +} + + +void +PatchCanvas::disconnection(SharedPtr cm) +{ + const SharedPtr src = get_port_view(cm->src_port()); + const SharedPtr dst = get_port_view(cm->dst_port()); + + if (src && dst) + remove_connection(src, dst); + else + cerr << "[PatchCanvas] ERROR: Unable to find ports to disconnect " + << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; +} + + +void +PatchCanvas::connect(boost::shared_ptr src_port, + boost::shared_ptr dst_port) +{ + const boost::shared_ptr src + = boost::dynamic_pointer_cast(src_port); + + const boost::shared_ptr dst + = boost::dynamic_pointer_cast(dst_port); + + if (!src || !dst) + return; + + // Midi binding/learn shortcut + if (src->model()->is_midi() && dst->model()->is_control()) + { + cerr << "FIXME: MIDI binding" << endl; +#if 0 + SharedPtr pm(new PluginModel(PluginModel::Internal, "", "midi_control_in", "")); + SharedPtr nm(new NodeModel(pm, _patch->path().base() + + src->name() + "-" + dst->name(), false)); + nm->set_metadata("canvas-x", Atom((float) + (dst->module()->property_x() - dst->module()->width() - 20))); + nm->set_metadata("canvas-y", Atom((float) + (dst->module()->property_y()))); + App::instance().engine()->create_node_from_model(nm.get()); + App::instance().engine()->connect(src->model()->path(), nm->path() + "/MIDI_In"); + App::instance().engine()->connect(nm->path() + "/Out_(CR)", dst->model()->path()); + App::instance().engine()->midi_learn(nm->path()); + + // Set control node range to port's user range + + App::instance().engine()->set_port_value_queued(nm->path().base() + "Min", + dst->model()->get_metadata("user-min").get_float()); + App::instance().engine()->set_port_value_queued(nm->path().base() + "Max", + dst->model()->get_metadata("user-max").get_float()); +#endif + } else { + App::instance().engine()->connect(src->model()->path(), dst->model()->path()); + } +} + + +void +PatchCanvas::disconnect(boost::shared_ptr src_port, + boost::shared_ptr dst_port) +{ + const boost::shared_ptr src + = boost::dynamic_pointer_cast(src_port); + + const boost::shared_ptr dst + = boost::dynamic_pointer_cast(dst_port); + + App::instance().engine()->disconnect(src->model()->path(), + dst->model()->path()); +} + + +bool +PatchCanvas::canvas_event(GdkEvent* event) +{ + assert(event); + + switch (event->type) { + + case GDK_BUTTON_PRESS: + if (event->button.button == 3) { + _last_click_x = (int)event->button.x; + _last_click_y = (int)event->button.y; + show_menu(event); + } + break; + + /*case GDK_KEY_PRESS: + if (event->key.keyval == GDK_Delete) + destroy_selected(); + break; + */ + + default: + break; + } + + return FlowCanvas::canvas_event(event); +} + + +void +PatchCanvas::destroy_selection() +{ + for (list >::iterator m = _selected_items.begin(); m != _selected_items.end(); ++m) { + boost::shared_ptr module = boost::dynamic_pointer_cast(*m); + if (module) { + App::instance().engine()->destroy(module->node()->path()); + } else { + boost::shared_ptr port_module = boost::dynamic_pointer_cast(*m); + if (port_module) + App::instance().engine()->destroy(port_module->port()->path()); + } + } + +} + + +void +PatchCanvas::copy_selection() +{ + Serializer serializer(*App::instance().rdf_world()); + serializer.start_to_string(); + + for (list >::iterator m = _selected_items.begin(); m != _selected_items.end(); ++m) { + boost::shared_ptr module = boost::dynamic_pointer_cast(*m); + if (module) { + serializer.serialize(module->node()); + } else { + boost::shared_ptr port_module = boost::dynamic_pointer_cast(*m); + if (port_module) + serializer.serialize(port_module->port()); + } + } + + for (list >::iterator c = _selected_connections.begin(); + c != _selected_connections.end(); ++c) { + boost::shared_ptr connection = boost::dynamic_pointer_cast(*c); + if (connection) + serializer.serialize_connection(connection->model()); + } + + string result = serializer.finish(); + + Glib::RefPtr clipboard = Gtk::Clipboard::get(); + clipboard->set_text(result); +} + + +string +PatchCanvas::generate_port_name(const string& base) { + string name = base; + + char num_buf[5]; + for (uint i=1; i < 9999; ++i) { + snprintf(num_buf, 5, "%u", i); + name = base + "_"; + name += num_buf; + if (!_patch->get_port(name)) + break; + } + + assert(Path::is_valid(string("/") + name)); + + return name; +} + + +void +PatchCanvas::menu_add_port(const string& name, const string& type, bool is_output) +{ + const Path& path = _patch->path().base() + generate_port_name(name); + App::instance().engine()->create_port(path, type, is_output); + MetadataMap data = get_initial_data(); + for (MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i) + App::instance().engine()->set_metadata(path, i->first, i->second); +} + + +void +PatchCanvas::load_plugin(SharedPtr plugin) +{ + const Path& path = _patch->path().base() + plugin->default_node_name(_patch); + // FIXME: polyphony? + App::instance().engine()->create_node(path, plugin->uri(), false); + MetadataMap data = get_initial_data(); + for (MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i) + App::instance().engine()->set_metadata(path, i->first, i->second); +} + + +/** Try to guess a suitable location for a new module. + */ +void +PatchCanvas::get_new_module_location(double& x, double& y) +{ + int scroll_x; + int scroll_y; + get_scroll_offsets(scroll_x, scroll_y); + x = scroll_x + 20; + y = scroll_y + 20; +} + + +MetadataMap +PatchCanvas::get_initial_data() +{ + MetadataMap result; + + result["ingenuity:canvas-x"] = Atom((float)_last_click_x); + result["ingenuity:canvas-y"] = Atom((float)_last_click_y); + + return result; +} + +void +PatchCanvas::menu_load_plugin() +{ + App::instance().window_factory()->present_load_plugin(_patch, get_initial_data()); +} + + +void +PatchCanvas::menu_load_patch() +{ + App::instance().window_factory()->present_load_subpatch(_patch, get_initial_data()); +} + + +void +PatchCanvas::menu_new_patch() +{ + App::instance().window_factory()->present_new_subpatch(_patch, get_initial_data()); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/PatchCanvas.h b/src/libs/gui/PatchCanvas.h new file mode 100644 index 00000000..8634b7bf --- /dev/null +++ b/src/libs/gui/PatchCanvas.h @@ -0,0 +1,129 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PATCHCANVAS_H +#define PATCHCANVAS_H + +#include +#include +#include +#include +#include +#include +#include +#include "client/ConnectionModel.h" +#include "client/PatchModel.h" +#include "NodeModule.h" + +using std::string; +using namespace LibFlowCanvas; + +using LibFlowCanvas::Port; +using Ingen::Client::ConnectionModel; +using Ingen::Client::PatchModel; +using Ingen::Client::NodeModel; +using Ingen::Client::PortModel; +using Ingen::Client::MetadataMap; + +namespace Ingen { +namespace GUI { + +class NodeModule; + + +/** Patch canvas widget. + * + * \ingroup GUI + */ +class PatchCanvas : public LibFlowCanvas::FlowCanvas +{ +public: + PatchCanvas(SharedPtr patch, int width, int height); + + virtual ~PatchCanvas() {} + + /*boost::shared_ptr find_module(const string& name) { + return boost::dynamic_pointer_cast( + FlowCanvas::get_item(name)); + }*/ + + void build(); + void arrange(); + + void add_node(SharedPtr nm); + void remove_node(SharedPtr nm); + void add_port(SharedPtr pm); + void remove_port(SharedPtr pm); + void connection(SharedPtr cm); + void disconnection(SharedPtr cm); + + void get_new_module_location(double& x, double& y); + + void destroy_selection(); + void copy_selection(); + + void show_menu(GdkEvent* event) + { _menu->popup(event->button.button, event->button.time); } + +private: + string generate_port_name(const string& base); + void menu_add_port(const string& name, const string& type, bool is_output); + void menu_load_plugin(); + void menu_new_patch(); + void menu_load_patch(); + void load_plugin(SharedPtr plugin); + void build_plugin_menu(); + void build_plugin_class_menu(Gtk::Menu* menu, + SLV2PluginClass plugin_class, SLV2PluginClasses classes); + + MetadataMap get_initial_data(); + + bool canvas_event(GdkEvent* event); + + SharedPtr get_port_view(SharedPtr port); + + void connect(boost::shared_ptr src, + boost::shared_ptr dst); + + void disconnect(boost::shared_ptr src, + boost::shared_ptr dst); + + SharedPtr _patch; + + typedef std::map, SharedPtr > Views; + Views _views; + + int _last_click_x; + int _last_click_y; + + Gtk::Menu* _menu; + Gtk::MenuItem* _menu_add_audio_input; + Gtk::MenuItem* _menu_add_audio_output; + Gtk::MenuItem* _menu_add_control_input; + Gtk::MenuItem* _menu_add_control_output; + Gtk::MenuItem* _menu_add_midi_input; + Gtk::MenuItem* _menu_add_midi_output; + Gtk::MenuItem* _menu_load_plugin; + Gtk::MenuItem* _menu_load_patch; + Gtk::MenuItem* _menu_new_patch; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // PATCHCANVAS_H diff --git a/src/libs/gui/PatchPortModule.cpp b/src/libs/gui/PatchPortModule.cpp new file mode 100644 index 00000000..2a812296 --- /dev/null +++ b/src/libs/gui/PatchPortModule.cpp @@ -0,0 +1,113 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "PatchPortModule.h" +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "client/NodeModel.h" +#include "App.h" +#include "PatchCanvas.h" +#include "Port.h" +#include "GladeFactory.h" +#include "RenameWindow.h" +#include "PatchWindow.h" + +namespace Ingen { +namespace GUI { + + +PatchPortModule::PatchPortModule(boost::shared_ptr canvas, SharedPtr port) +: LibFlowCanvas::Module(canvas, port->path().name(), 0, 0, false), // FIXME: coords? + _port(port) +{ + /*if (port_model()->polyphonic() && port_model()->parent() != NULL + && port_model()->parent_patch()->poly() > 1) { + border_width(2.0); + }*/ + + assert(canvas); + assert(port); + + assert(PtrCast(port->parent())); + + /*resize(); + + const Atom& x_atom = port->get_metadata("ingenuity:canvas-x"); + const Atom& y_atom = port->get_metadata("ingenuity:canvas-y"); + + if (x_atom && y_atom && x_atom.type() == Atom::FLOAT && y_atom.type() == Atom::FLOAT) { + move_to(x_atom.get_float(), y_atom.get_float()); + } else { + double default_x; + double default_y; + canvas->get_new_module_location(default_x, default_y); + move_to(default_x, default_y); + }*/ + + port->metadata_update_sig.connect(sigc::mem_fun(this, &PatchPortModule::metadata_update)); +} + + +boost::shared_ptr +PatchPortModule::create(boost::shared_ptr canvas, SharedPtr port) +{ + boost::shared_ptr ret = boost::shared_ptr( + new PatchPortModule(canvas, port)); + assert(ret); + + ret->_patch_port = boost::shared_ptr(new Port(ret, port, true, true)); + ret->add_port(ret->_patch_port); + + for (MetadataMap::const_iterator m = port->metadata().begin(); m != port->metadata().end(); ++m) + ret->metadata_update(m->first, m->second); + + ret->resize(); + + return ret; +} + + +void +PatchPortModule::store_location() +{ + const float x = static_cast(property_x()); + const float y = static_cast(property_y()); + + const Atom& existing_x = _port->get_metadata("ingenuity:canvas-x"); + const Atom& existing_y = _port->get_metadata("ingenuity:canvas-y"); + + if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT + || existing_x.get_float() != x || existing_y.get_float() != y) { + App::instance().engine()->set_metadata(_port->path(), "ingenuity:canvas-x", Atom(x)); + App::instance().engine()->set_metadata(_port->path(), "ingenuity:canvas-y", Atom(y)); + } +} + + +void +PatchPortModule::metadata_update(const string& key, const Atom& value) +{ + if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT) + move_to(value.get_float(), property_y()); + else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT) + move_to(property_x(), value.get_float()); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/PatchPortModule.h b/src/libs/gui/PatchPortModule.h new file mode 100644 index 00000000..ac39eadf --- /dev/null +++ b/src/libs/gui/PatchPortModule.h @@ -0,0 +1,80 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PATCHPORTMODULE_H +#define PATCHPORTMODULE_H + +#include +#include +#include +#include +#include +#include "Port.h" +using std::string; + +namespace Ingen { namespace Client { + class PortModel; + class NodeModel; + class ControlModel; +} } +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + +class PatchCanvas; +class Port; + + +/** A "module" to represent a patch's port on it's own canvas. + * + * Translation: This is the nameless single port pseudo module thingy. + * + * \ingroup GUI + */ +class PatchPortModule : public boost::enable_shared_from_this, + public LibFlowCanvas::Module +{ +public: + static boost::shared_ptr create(boost::shared_ptr canvas, + SharedPtr port); + + virtual ~PatchPortModule() {} + + virtual void store_location(); + + //void on_right_click(GdkEventButton* event) { _port->show_menu(event); } + + SharedPtr port() const { return _port; } + +protected: + PatchPortModule(boost::shared_ptr canvas, SharedPtr port); + + //virtual void on_double_click(GdkEventButton* ev) { show_control_window(); } + //virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); } + + void metadata_update(const string& key, const Raul::Atom& value); + + SharedPtr _port; + boost::shared_ptr _patch_port; ///< Port on this 'anonymous' module +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // PATCHPORTMODULE_H diff --git a/src/libs/gui/PatchPropertiesWindow.cpp b/src/libs/gui/PatchPropertiesWindow.cpp new file mode 100644 index 00000000..1e310f0b --- /dev/null +++ b/src/libs/gui/PatchPropertiesWindow.cpp @@ -0,0 +1,89 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "client/PatchModel.h" +#include "PatchPropertiesWindow.h" + +namespace Ingen { +namespace GUI { +using std::string; + + +PatchPropertiesWindow::PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) +: Gtk::Window(cobject) +{ + glade_xml->get_widget("properties_author_entry", _author_entry); + glade_xml->get_widget("properties_description_textview", _textview); + glade_xml->get_widget("properties_cancel_button", _cancel_button); + glade_xml->get_widget("properties_ok_button", _ok_button); + + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &PatchPropertiesWindow::cancel_clicked)); + _ok_button->signal_clicked().connect(sigc::mem_fun(this, &PatchPropertiesWindow::ok_clicked)); +} + + +/** Set the patch model this description is for. + * + * This function is a "post-constructor" - it MUST be called before using + * the window in any way. + */ +void +PatchPropertiesWindow::set_patch(SharedPtr patch_model) +{ + property_title() = patch_model->path() + " Properties"; + _patch_model = patch_model; + + const Atom& author_atom = _patch_model->get_metadata("author"); + _author_entry->set_text( + (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); + + const Atom& desc_atom = _patch_model->get_metadata("description"); + _textview->get_buffer()->set_text( + (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); +} + + +void +PatchPropertiesWindow::cancel_clicked() +{ + const Atom& author_atom = _patch_model->get_metadata("author"); + _author_entry->set_text( + (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); + + const Atom& desc_atom = _patch_model->get_metadata("description"); + _textview->get_buffer()->set_text( + (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); + + hide(); +} + + +void +PatchPropertiesWindow::ok_clicked() +{ + cerr << "FIXME: properties\n"; + + //m_patch_model->set_metadata("author", Atom(_author_entry->get_text().c_str())); + //m_patch_model->set_metadata("description", Atom(_textview->get_buffer()->get_text().c_str())); + hide(); +} + + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/PatchPropertiesWindow.h b/src/libs/gui/PatchPropertiesWindow.h new file mode 100644 index 00000000..0640a198 --- /dev/null +++ b/src/libs/gui/PatchPropertiesWindow.h @@ -0,0 +1,64 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PATCHPROPERTIESWINDOW_H +#define PATCHPROPERTIESWINDOW_H + +#include +#include +#include +#include +using std::string; + +namespace Ingen { namespace Client { class PatchModel; } } +using Ingen::Client::PatchModel; + +namespace Ingen { +namespace GUI { + + +/** Patch Properties Window. + * + * Loaded by libglade as a derived object. + * + * \ingroup GUI + */ +class PatchPropertiesWindow : public Gtk::Window +{ +public: + PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); + + void present(SharedPtr patch_model) { set_patch(patch_model); Gtk::Window::present(); } + void set_patch(SharedPtr patch_model); + + void cancel_clicked(); + void ok_clicked(); + +private: + SharedPtr _patch_model; + + Gtk::Entry* _author_entry; + Gtk::TextView* _textview; + Gtk::Button* _cancel_button; + Gtk::Button* _ok_button; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // PATCHPROPERTIESWINDOW_H diff --git a/src/libs/gui/PatchTreeWindow.cpp b/src/libs/gui/PatchTreeWindow.cpp new file mode 100644 index 00000000..b77508c1 --- /dev/null +++ b/src/libs/gui/PatchTreeWindow.cpp @@ -0,0 +1,270 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "interface/EngineInterface.h" +#include "client/OSCEngineSender.h" +#include "client/Store.h" +#include "client/PatchModel.h" +#include "App.h" +#include "PatchTreeWindow.h" +#include "SubpatchModule.h" +#include "WindowFactory.h" + +namespace Ingen { +namespace GUI { + + +PatchTreeWindow::PatchTreeWindow(BaseObjectType* cobject, + const Glib::RefPtr& xml) +: Gtk::Window(cobject), + _enable_signal(true) +{ + xml->get_widget_derived("patches_treeview", _patches_treeview); + + _patch_treestore = Gtk::TreeStore::create(_patch_tree_columns); + _patches_treeview->set_window(this); + _patches_treeview->set_model(_patch_treestore); + Gtk::TreeViewColumn* name_col = Gtk::manage(new Gtk::TreeViewColumn( + "Patch", _patch_tree_columns.name_col)); + Gtk::TreeViewColumn* enabled_col = Gtk::manage(new Gtk::TreeViewColumn( + "Run", _patch_tree_columns.enabled_col)); + name_col->set_resizable(true); + name_col->set_expand(true); + + _patches_treeview->append_column(*name_col); + _patches_treeview->append_column(*enabled_col); + Gtk::CellRendererToggle* enabled_renderer = dynamic_cast( + _patches_treeview->get_column_cell_renderer(1)); + enabled_renderer->property_activatable() = true; + + _patch_tree_selection = _patches_treeview->get_selection(); + + //m_patch_tree_selection->signal_changed().connect( + // sigc::mem_fun(this, &PatchTreeWindow::event_patch_selected)); + _patches_treeview->signal_row_activated().connect( + sigc::mem_fun(this, &PatchTreeWindow::event_patch_activated)); + enabled_renderer->signal_toggled().connect( + sigc::mem_fun(this, &PatchTreeWindow::event_patch_enabled_toggled)); + + _patches_treeview->columns_autosize(); +} + + +void +PatchTreeWindow::init(Store& store) +{ + store.new_object_sig.connect(sigc::mem_fun(this, &PatchTreeWindow::new_object)); +} + + +void +PatchTreeWindow::new_object(SharedPtr object) +{ + SharedPtr patch = PtrCast(object); + if (patch) + add_patch(patch); +} + + +void +PatchTreeWindow::add_patch(SharedPtr pm) +{ + if (!pm->parent()) { + Gtk::TreeModel::iterator iter = _patch_treestore->append(); + Gtk::TreeModel::Row row = *iter; + if (pm->path() == "/") { + SharedPtr osc_sender = PtrCast(App::instance().engine()); + string root_name = osc_sender ? osc_sender->engine_url() : "Internal"; + // Hack off trailing '/' if it's there (ugly) + //if (root_name.substr(root_name.length()-1,1) == "/") + // root_name = root_name.substr(0, root_name.length()-1); + //root_name.append(":/"); + row[_patch_tree_columns.name_col] = root_name; + } else { + row[_patch_tree_columns.name_col] = pm->path().name(); + } + row[_patch_tree_columns.enabled_col] = false; + row[_patch_tree_columns.patch_model_col] = pm; + _patches_treeview->expand_row(_patch_treestore->get_path(iter), true); + } else { + Gtk::TreeModel::Children children = _patch_treestore->children(); + Gtk::TreeModel::iterator c = find_patch(children, pm->parent()->path()); + + if (c != children.end()) { + Gtk::TreeModel::iterator iter = _patch_treestore->append(c->children()); + Gtk::TreeModel::Row row = *iter; + row[_patch_tree_columns.name_col] = pm->path().name(); + row[_patch_tree_columns.enabled_col] = false; + row[_patch_tree_columns.patch_model_col] = pm; + _patches_treeview->expand_row(_patch_treestore->get_path(iter), true); + } + } + + pm->enabled_sig.connect(sigc::bind(sigc::mem_fun(this, &PatchTreeWindow::patch_enabled), pm->path())); + pm->disabled_sig.connect(sigc::bind(sigc::mem_fun(this, &PatchTreeWindow::patch_disabled), pm->path())); +} + + +void +PatchTreeWindow::remove_patch(const Path& path) +{ + Gtk::TreeModel::iterator i = find_patch(_patch_treestore->children(), path); + if (i != _patch_treestore->children().end()) + _patch_treestore->erase(i); +} + + +Gtk::TreeModel::iterator +PatchTreeWindow::find_patch(Gtk::TreeModel::Children root, const Path& path) +{ + for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { + SharedPtr pm = (*c)[_patch_tree_columns.patch_model_col]; + if (pm->path() == path) { + return c; + } else if ((*c)->children().size() > 0) { + Gtk::TreeModel::iterator ret = find_patch(c->children(), path); + if (ret != c->children().end()) + return ret; + } + } + return root.end(); +} + +/* +void +PatchTreeWindow::event_patch_selected() +{ + Gtk::TreeModel::iterator active = _patch_tree_selection->get_selected(); + if (active) { + Gtk::TreeModel::Row row = *active; + SharedPtr pm = row[_patch_tree_columns.patch_model_col]; + } +} +*/ + + +/** Show the context menu for the selected patch in the patches treeview. + */ +void +PatchTreeWindow::show_patch_menu(GdkEventButton* ev) +{ + Gtk::TreeModel::iterator active = _patch_tree_selection->get_selected(); + if (active) { + Gtk::TreeModel::Row row = *active; + SharedPtr pm = row[_patch_tree_columns.patch_model_col]; + if (pm) + cerr << "FIXME: patch menu\n"; + //pm->show_menu(ev); + } +} + + +void +PatchTreeWindow::event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col) +{ + Gtk::TreeModel::iterator active = _patch_treestore->get_iter(path); + Gtk::TreeModel::Row row = *active; + SharedPtr pm = row[_patch_tree_columns.patch_model_col]; + + App::instance().window_factory()->present_patch(pm); +} + + +void +PatchTreeWindow::event_patch_enabled_toggled(const Glib::ustring& path_str) +{ + Gtk::TreeModel::Path path(path_str); + Gtk::TreeModel::iterator active = _patch_treestore->get_iter(path); + Gtk::TreeModel::Row row = *active; + + SharedPtr pm = row[_patch_tree_columns.patch_model_col]; + Glib::ustring patch_path = pm->path(); + + assert(pm); + + if ( ! pm->enabled()) { + if (_enable_signal) + App::instance().engine()->enable_patch(patch_path); + //row[_patch_tree_columns.enabled_col] = true; + } else { + if (_enable_signal) + App::instance().engine()->disable_patch(patch_path); + //row[_patch_tree_columns.enabled_col] = false; + } +} + + +void +PatchTreeWindow::patch_enabled(const Path& path) +{ + _enable_signal = false; + + Gtk::TreeModel::iterator i + = find_patch(_patch_treestore->children(), path); + + if (i != _patch_treestore->children().end()) { + Gtk::TreeModel::Row row = *i; + row[_patch_tree_columns.enabled_col] = true; + } else { + cerr << "[PatchTreeWindow] Unable to find patch " << path << endl; + } + + _enable_signal = true; +} + + +void +PatchTreeWindow::patch_disabled(const Path& path) +{ + _enable_signal = false; + + Gtk::TreeModel::iterator i + = find_patch(_patch_treestore->children(), path); + + if (i != _patch_treestore->children().end()) { + Gtk::TreeModel::Row row = *i; + row[_patch_tree_columns.enabled_col] = false; + } else { + cerr << "[PatchTreeWindow] Unable to find patch " << path << endl; + } + + _enable_signal = true; +} + + +void +PatchTreeWindow::patch_renamed(const Path& old_path, const Path& new_path) +{ + _enable_signal = false; + + Gtk::TreeModel::iterator i + = find_patch(_patch_treestore->children(), old_path); + + if (i != _patch_treestore->children().end()) { + Gtk::TreeModel::Row row = *i; + row[_patch_tree_columns.name_col] = new_path.name(); + } else { + cerr << "[PatchTreeWindow] Unable to find patch " << old_path << endl; + } + + _enable_signal = true; +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/PatchTreeWindow.h b/src/libs/gui/PatchTreeWindow.h new file mode 100644 index 00000000..9868d363 --- /dev/null +++ b/src/libs/gui/PatchTreeWindow.h @@ -0,0 +1,112 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PATCHTREEWINDOW_H +#define PATCHTREEWINDOW_H + +#include +#include +#include + +namespace Ingen { namespace Client { + class Store; +} } +using Ingen::Client::Store; + +namespace Ingen { +namespace GUI { + +class PatchWindow; +class PatchTreeView; + + +/** Window with a TreeView of all loaded patches. + * + * \ingroup GUI + */ +class PatchTreeWindow : public Gtk::Window +{ +public: + PatchTreeWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); + + void init(Store& store); + + void new_object(SharedPtr object); + + void patch_enabled(const Path& path); + void patch_disabled(const Path& path); + void patch_renamed(const Path& old_path, const Path& new_path); + + void add_patch(SharedPtr pm); + void remove_patch(const Path& path); + void show_patch_menu(GdkEventButton* ev); + +protected: + //void event_patch_selected(); + void event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col); + void event_patch_enabled_toggled(const Glib::ustring& path_str); + + Gtk::TreeModel::iterator find_patch(Gtk::TreeModel::Children root, const Path& path); + + PatchTreeView* _patches_treeview; + + struct PatchTreeModelColumns : public Gtk::TreeModel::ColumnRecord + { + PatchTreeModelColumns() + { add(name_col); add(enabled_col); add(patch_model_col); } + + Gtk::TreeModelColumn name_col; + Gtk::TreeModelColumn enabled_col; + Gtk::TreeModelColumn > patch_model_col; + }; + + bool _enable_signal; + PatchTreeModelColumns _patch_tree_columns; + Glib::RefPtr _patch_treestore; + Glib::RefPtr _patch_tree_selection; +}; + + +/** Derived TreeView class to support context menus for patches */ +class PatchTreeView : public Gtk::TreeView +{ +public: + PatchTreeView(BaseObjectType* cobject, const Glib::RefPtr& xml) + : Gtk::TreeView(cobject) + {} + + void set_window(PatchTreeWindow* win) { _window = win; } + + bool on_button_press_event(GdkEventButton* ev) { + bool ret = Gtk::TreeView::on_button_press_event(ev); + + if ((ev->type == GDK_BUTTON_PRESS) && (ev->button == 3)) + _window->show_patch_menu(ev); + + return ret; + } + +private: + PatchTreeWindow* _window; + +}; // struct PatchTreeView + + +} // namespace GUI +} // namespace Ingen + +#endif // PATCHTREEWINDOW_H diff --git a/src/libs/gui/PatchView.cpp b/src/libs/gui/PatchView.cpp new file mode 100644 index 00000000..7b12fe40 --- /dev/null +++ b/src/libs/gui/PatchView.cpp @@ -0,0 +1,162 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "App.h" +#include "PatchView.h" +#include "PatchCanvas.h" +#include "LoadPluginWindow.h" +#include "NewSubpatchWindow.h" +#include "LoadSubpatchWindow.h" +#include "NodeControlWindow.h" +#include "PatchPropertiesWindow.h" +#include "PatchTreeWindow.h" +#include "GladeFactory.h" + +namespace Ingen { +namespace GUI { + + +PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::Box(cobject), + _breadcrumb_container(NULL), + _enable_signal(true) +{ + property_visible() = false; + + xml->get_widget("patch_view_breadcrumb_container", _breadcrumb_container); + xml->get_widget("patch_view_process_but", _process_but); + xml->get_widget("patch_view_poly_spin", _poly_spin); + xml->get_widget("patch_view_clear_but", _clear_but); + xml->get_widget("patch_view_destroy_but", _destroy_but); + xml->get_widget("patch_view_refresh_but", _refresh_but); + xml->get_widget("patch_view_save_but", _save_but); + xml->get_widget("patch_view_zoom_full_but", _zoom_full_but); + xml->get_widget("patch_view_zoom_normal_but", _zoom_normal_but); + xml->get_widget("patch_view_scrolledwindow", _canvas_scrolledwindow); +} + + +void +PatchView::set_patch(SharedPtr patch) +{ + assert(!_canvas); // FIXME: remove + + cerr << "Creating view for " << patch->path() << endl; + + assert(_breadcrumb_container); // ensure created + + _patch = patch; + _canvas = SharedPtr(new PatchCanvas(patch, 1600*2, 1200*2)); + _canvas->build(); + + _canvas_scrolledwindow->add(*_canvas); + + _poly_spin->set_value(patch->poly()); + _destroy_but->set_sensitive(patch->path() != "/"); + patch->enabled() ? enable() : disable(); + + // Connect model signals to track state + patch->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable)); + patch->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable)); + + // Connect widget signals to do things + _process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled)); + _clear_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::clear_clicked)); + _refresh_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::refresh_clicked)); + + _zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun( + _canvas.get(), &FlowCanvas::set_zoom), 1.0)); + + _zoom_full_but->signal_clicked().connect( + sigc::mem_fun(_canvas.get(), &FlowCanvas::zoom_full)); +} + + +PatchView::~PatchView() +{ + cerr << "Destroying view for " << _patch->path() << endl; +} + + +SharedPtr +PatchView::create(SharedPtr patch) + +{ + const Glib::RefPtr& xml = GladeFactory::new_glade_reference("patch_view_box"); + PatchView* result = NULL; + xml->get_widget_derived("patch_view_box", result); + assert(result); + result->set_patch(patch); + return SharedPtr(result); +} + + +void +PatchView::process_toggled() +{ + if (!_enable_signal) + return; + + if (_process_but->get_active()) { + App::instance().engine()->enable_patch(_patch->path()); + App::instance().patch_tree()->patch_enabled(_patch->path()); + } else { + App::instance().engine()->disable_patch(_patch->path()); + App::instance().patch_tree()->patch_disabled(_patch->path()); + } +} + + +void +PatchView::clear_clicked() +{ + App::instance().engine()->clear_patch(_patch->path()); +} + + +void +PatchView::refresh_clicked() +{ + App::instance().engine()->request_object(_patch->path()); +} + + +void +PatchView::enable() +{ + _enable_signal = false; + _process_but->set_active(true); + _enable_signal = true; +} + + +void +PatchView::disable() +{ + _enable_signal = false; + _process_but->set_active(false); + _enable_signal = true; +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/PatchView.h b/src/libs/gui/PatchView.h new file mode 100644 index 00000000..72d773fa --- /dev/null +++ b/src/libs/gui/PatchView.h @@ -0,0 +1,102 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PATCHVIEW_H +#define PATCHVIEW_H + +#include +#include +#include +#include +#include +#include "client/PatchModel.h" + +using std::string; + +namespace Ingen { namespace Client { + class PortModel; + class ControlModel; + class MetadataModel; +} } +using namespace Ingen::Client; + + +namespace Ingen { +namespace GUI { + +class PatchCanvas; +class LoadPluginWindow; +class NewSubpatchWindow; +class LoadSubpatchWindow; +class NewSubpatchWindow; +class NodeControlWindow; +class PatchDescriptionWindow; +class SubpatchModule; +class OmPort; + + +/** The patch specific contents of a PatchWindow (ie the canvas and whatever else). + * + * \ingroup GUI + */ +class PatchView : public Gtk::Box +{ +public: + PatchView(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); + ~PatchView(); + + SharedPtr canvas() const { return _canvas; } + SharedPtr patch() const { return _patch; } + Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; } + + static SharedPtr create(SharedPtr patch); + +private: + void set_patch(SharedPtr patch); + + void process_toggled(); + void clear_clicked(); + void refresh_clicked(); + + void enable(); + void disable(); + + void zoom_full(); + + SharedPtr _patch; + SharedPtr _canvas; + + Gtk::ScrolledWindow* _canvas_scrolledwindow; + + Gtk::ToggleToolButton* _process_but; + Gtk::SpinButton* _poly_spin; + Gtk::ToolButton* _clear_but; + Gtk::ToolButton* _destroy_but; + Gtk::ToolButton* _refresh_but; + Gtk::ToolButton* _save_but; + Gtk::ToolButton* _zoom_normal_but; + Gtk::ToolButton* _zoom_full_but; + Gtk::Viewport* _breadcrumb_container; + + bool _enable_signal; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // PATCHVIEW_H diff --git a/src/libs/gui/PatchWindow.cpp b/src/libs/gui/PatchWindow.cpp new file mode 100644 index 00000000..ff2a6a4a --- /dev/null +++ b/src/libs/gui/PatchWindow.cpp @@ -0,0 +1,467 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "PatchWindow.h" +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "client/Store.h" +#include "App.h" +#include "PatchCanvas.h" +#include "LoadPluginWindow.h" +#include "NewSubpatchWindow.h" +#include "LoadPatchWindow.h" +#include "LoadSubpatchWindow.h" +#include "NodeControlWindow.h" +#include "PatchPropertiesWindow.h" +#include "ConfigWindow.h" +#include "MessagesWindow.h" +#include "PatchTreeWindow.h" +#include "BreadCrumbBox.h" +#include "ConnectWindow.h" +#include "ThreadedLoader.h" +#include "WindowFactory.h" +#include "PatchView.h" + +namespace Ingen { +namespace GUI { + + +PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) +: Gtk::Window(cobject), + _enable_signal(true), + _position_stored(false), + _x(0), + _y(0), + _breadcrumb_box(NULL) +{ + property_visible() = false; + + xml->get_widget("patch_win_vbox", _vbox); + xml->get_widget("patch_win_viewport", _viewport); + //xml->get_widget("patch_win_status_bar", _status_bar); + //xml->get_widget("patch_open_menuitem", _menu_open); + xml->get_widget("patch_import_menuitem", _menu_import); + xml->get_widget("patch_import_location_menuitem", _menu_import_location); + //xml->get_widget("patch_open_into_menuitem", _menu_open_into); + xml->get_widget("patch_save_menuitem", _menu_save); + xml->get_widget("patch_save_as_menuitem", _menu_save_as); + xml->get_widget("patch_upload_menuitem", _menu_upload); + xml->get_widget("patch_cut_menuitem", _menu_cut); + xml->get_widget("patch_copy_menuitem", _menu_copy); + xml->get_widget("patch_paste_menuitem", _menu_paste); + xml->get_widget("patch_delete_menuitem", _menu_delete); + xml->get_widget("patch_close_menuitem", _menu_close); + xml->get_widget("patch_configuration_menuitem", _menu_configuration); + xml->get_widget("patch_quit_menuitem", _menu_quit); + xml->get_widget("patch_view_control_window_menuitem", _menu_view_control_window); + xml->get_widget("patch_view_engine_window_menuitem", _menu_view_engine_window); + xml->get_widget("patch_properties_menuitem", _menu_view_patch_properties); + xml->get_widget("patch_fullscreen_menuitem", _menu_fullscreen); + xml->get_widget("patch_arrange_menuitem", _menu_arrange); + xml->get_widget("patch_clear_menuitem", _menu_clear); + xml->get_widget("patch_destroy_menuitem", _menu_destroy_patch); + xml->get_widget("patch_view_messages_window_menuitem", _menu_view_messages_window); + xml->get_widget("patch_view_patch_tree_window_menuitem", _menu_view_patch_tree_window); + xml->get_widget("patch_help_about_menuitem", _menu_help_about); + + _menu_view_control_window->property_sensitive() = false; + //m_status_bar->push(App::instance().engine()->engine_url()); + //m_status_bar->pack_start(*Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_MENU)), false, false); + + /*_menu_open->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_open));*/ + _menu_import->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_import)); + _menu_import_location->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_import_location)); + _menu_save->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_save)); + _menu_save_as->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_save_as)); + _menu_upload->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_upload)); + _menu_copy->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_copy)); + _menu_delete->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_delete)); + _menu_quit->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_quit)); + _menu_configuration->signal_activate().connect( + sigc::mem_fun(App::instance().configuration_dialog(), &ConfigWindow::show)); + _menu_fullscreen->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_fullscreen_toggled)); + _menu_arrange->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_arrange)); + _menu_view_engine_window->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_show_engine)); + _menu_view_control_window->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_show_controls)); + _menu_view_patch_properties->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_show_properties)); + _menu_destroy_patch->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_destroy)); + _menu_clear->signal_activate().connect( + sigc::mem_fun(this, &PatchWindow::event_clear)); + _menu_view_messages_window->signal_activate().connect( + sigc::mem_fun(App::instance().messages_dialog(), &MessagesWindow::present)); + _menu_view_patch_tree_window->signal_activate().connect( + sigc::mem_fun(App::instance().patch_tree(), &PatchTreeWindow::present)); + + _menu_help_about->signal_activate().connect( + sigc::mem_fun(App::instance().about_dialog(), &Gtk::Dialog::present)); + + _breadcrumb_box = new BreadCrumbBox(); + _breadcrumb_box->signal_patch_selected.connect(sigc::mem_fun(this, &PatchWindow::set_patch_from_path)); +} + + +PatchWindow::~PatchWindow() +{ + // Prevents deletion + //m_patch->claim_patch_view(); + + delete _breadcrumb_box; +} + + +/** Set the patch controller from a Path (for use by eg. BreadCrumbBox) + */ +void +PatchWindow::set_patch_from_path(const Path& path, SharedPtr view) +{ + if (view) { + assert(view->patch()->path() == path); + App::instance().window_factory()->present_patch(view->patch(), this, view); + } else { + SharedPtr model = PtrCast(App::instance().store()->object(path)); + if (model) + App::instance().window_factory()->present_patch(model, this); + } +} + + +/** Sets the patch controller for this window and initializes everything. + * + * If @a view is NULL, a new view will be created. + */ +void +PatchWindow::set_patch(SharedPtr patch, SharedPtr view) +{ + if (!patch || patch == _patch) + return; + + _enable_signal = false; + + _patch = patch; + + _view = view; + + if (!_view) + _view = _breadcrumb_box->view(patch->path()); + + if (!_view) + _view = PatchView::create(patch); + + assert(_view); + + // Add view to our viewport + if (_view->get_parent()) + _view->get_parent()->remove(*_view.get()); + + _viewport->remove(); + _viewport->add(*_view.get()); + + + if (_breadcrumb_box->get_parent()) + _breadcrumb_box->get_parent()->remove(*_breadcrumb_box); + + _view->breadcrumb_container()->remove(); + _view->breadcrumb_container()->add(*_breadcrumb_box); + _view->breadcrumb_container()->show(); + + _breadcrumb_box->build(patch->path(), _view); + _breadcrumb_box->show(); + + _menu_view_control_window->property_sensitive() = false; + + for (PortModelList::const_iterator p = patch->ports().begin(); + p != patch->ports().end(); ++p) { + if ((*p)->is_control()) { + _menu_view_control_window->property_sensitive() = true; + break; + } + } + + int width, height; + get_size(width, height); + _view->canvas()->scroll_to( + ((int)_view->canvas()->width() - width)/2, + ((int)_view->canvas()->height() - height)/2); + + set_title(_patch->path() + " - Ingenuity"); + + //m_properties_window->patch_model(pc->patch_model()); + + if (patch->path() == "/") + _menu_destroy_patch->set_sensitive(false); + else + _menu_destroy_patch->set_sensitive(true); + + show_all(); + + _enable_signal = true; +} + + +void +PatchWindow::event_show_engine() +{ + if (_patch) + App::instance().connect_window()->show(); +} + + +void +PatchWindow::event_show_controls() +{ + App::instance().window_factory()->present_controls(_patch); +} + + +void +PatchWindow::event_show_properties() +{ + App::instance().window_factory()->present_properties(_patch); +} + + +void +PatchWindow::event_import() +{ + App::instance().window_factory()->present_load_patch(_patch); +} + + +void +PatchWindow::event_import_location() +{ + App::instance().window_factory()->present_load_remote_patch(_patch); +} + + +void +PatchWindow::event_save() +{ + if (_patch->filename() == "") + event_save_as(); + else + App::instance().loader()->save_patch(_patch, _patch->filename(), false); +} + + +void +PatchWindow::event_save_as() +{ + Gtk::FileChooserDialog dialog(*this, "Save Patch", Gtk::FILE_CHOOSER_ACTION_SAVE); + + /*Gtk::VBox* box = dialog.get_vbox(); + Gtk::Label warning("Warning: Recursively saving will overwrite any subpatch files \ + without confirmation."); + box->pack_start(warning, false, false, 2); + Gtk::CheckButton recursive_checkbutton("Recursively save all subpatches"); + box->pack_start(recursive_checkbutton, false, false, 0); + recursive_checkbutton.show(); + */ + + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + Gtk::Button* save_button = dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); + save_button->property_has_default() = true; + + // Set current folder to most sensible default + const string& current_filename = _patch->filename(); + if (current_filename.length() > 0) + dialog.set_filename(current_filename); + else if (App::instance().configuration()->patch_folder().length() > 0) + dialog.set_current_folder(App::instance().configuration()->patch_folder()); + + int result = dialog.run(); + //bool recursive = recursive_checkbutton.get_active(); + + assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); + + if (result == Gtk::RESPONSE_OK) { + string filename = dialog.get_filename(); + if (filename.length() < 11 || filename.substr(filename.length()-10) != ".ingen.ttl") + filename += ".ingen.ttl"; + + bool confirm = false; + std::fstream fin; + fin.open(filename.c_str(), std::ios::in); + if (fin.is_open()) { // File exists + string msg = "File already exists! Are you sure you want to overwrite "; + msg += filename + "?"; + Gtk::MessageDialog confirm_dialog(*this, + msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + if (confirm_dialog.run() == Gtk::RESPONSE_YES) + confirm = true; + else + confirm = false; + } else { // File doesn't exist + confirm = true; + } + fin.close(); + + if (confirm) { + App::instance().loader()->save_patch(_patch, filename, true); + _patch->set_filename(filename); + //_patch->set_metadata("filename", Atom(filename.c_str())); + } + } + App::instance().configuration()->set_patch_folder(dialog.get_current_folder()); +} + + +void +PatchWindow::event_upload() +{ + App::instance().window_factory()->present_upload_patch(_patch); +} + + +void +PatchWindow::event_copy() +{ + if (_view) + _view->canvas()->copy_selection(); +} + + +void +PatchWindow::event_delete() +{ + if (_view) + _view->canvas()->destroy_selection(); +} + + +void +PatchWindow::on_show() +{ + if (_position_stored) + move(_x, _y); + + Gtk::Window::on_show(); +} + + +void +PatchWindow::on_hide() +{ + _position_stored = true; + get_position(_x, _y); + Gtk::Window::on_hide(); +} + + +bool +PatchWindow::on_key_press_event(GdkEventKey* event) +{ + if (event->keyval == GDK_Delete) { + cerr << "FIXME: delete key\n"; + /* + if (_patch && _patch->get_view()) { + assert(_patch->get_view()->canvas()); + _patch->get_view()->canvas()->destroy_selected(); + }*/ + return true; + } else { + return Gtk::Window::on_key_press_event(event); + } +} + + +void +PatchWindow::event_quit() +{ + Gtk::MessageDialog d(*this, "Would you like to quit just Ingenuity\nor kill the engine as well?", + true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true); + d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + + Gtk::Button* b = d.add_button(Gtk::Stock::REMOVE, 2); // kill + b->set_label("_Kill Engine"); + Gtk::Widget* kill_img = Gtk::manage(new Gtk::Image(Gtk::Stock::CLOSE, Gtk::ICON_SIZE_BUTTON)); + b->set_image(*kill_img); + + b = d.add_button(Gtk::Stock::QUIT, 1); // just exit + b->set_label("_Quit"); + Gtk::Widget* close_img = Gtk::manage(new Gtk::Image(Gtk::Stock::QUIT, Gtk::ICON_SIZE_BUTTON)); + b->set_image(*close_img); + b->grab_default(); + + int ret = d.run(); + if (ret == 1) { + App::instance().quit(); + } else if (ret == 2) { + App::instance().engine()->quit(); + App::instance().quit(); + } + // Otherwise cancelled, do nothing +} + + +void +PatchWindow::event_destroy() +{ + App::instance().engine()->destroy(_patch->path()); +} + + +void +PatchWindow::event_clear() +{ + App::instance().engine()->clear_patch(_patch->path()); +} + + +void +PatchWindow::event_arrange() +{ + _view->canvas()->arrange(); +} + + +void +PatchWindow::event_fullscreen_toggled() +{ + // FIXME: ugh, use GTK signals to track state and know for sure + static bool is_fullscreen = false; + + if (!is_fullscreen) { + fullscreen(); + is_fullscreen = true; + } else { + unfullscreen(); + is_fullscreen = false; + } +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/PatchWindow.h b/src/libs/gui/PatchWindow.h new file mode 100644 index 00000000..6e95c3d8 --- /dev/null +++ b/src/libs/gui/PatchWindow.h @@ -0,0 +1,143 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PATCHWINDOW_H +#define PATCHWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include "client/PatchModel.h" +#include "PatchView.h" +using Ingen::Client::PatchModel; + +using std::string; using std::list; + + +namespace Ingen { namespace Client { + class PatchModel; + class PortModel; + class ControlModel; + class MetadataModel; +} } +using namespace Ingen::Client; + + +namespace Ingen { +namespace GUI { + +class LoadPluginWindow; +class LoadPatchWindow; +class NewSubpatchWindow; +class LoadSubpatchWindow; +class NewSubpatchWindow; +class NodeControlWindow; +class PatchDescriptionWindow; +class SubpatchModule; +class OmPort; +class BreadCrumbBox; + + +/** A window for a patch. + * + * \ingroup GUI + */ +class PatchWindow : public Gtk::Window +{ +public: + PatchWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); + ~PatchWindow(); + + void set_patch_from_path(const Path& path, SharedPtr view); + void set_patch(SharedPtr pc, SharedPtr view); + + SharedPtr patch() const { return _patch; } + + Gtk::MenuItem* menu_view_control_window() { return _menu_view_control_window; } + +protected: + void on_show(); + void on_hide(); + bool on_key_press_event(GdkEventKey* event); + +private: + void event_import(); + void event_import_location(); + void event_save(); + void event_save_as(); + void event_upload(); + void event_copy(); + void event_delete(); + void event_quit(); + void event_destroy(); + void event_clear(); + void event_fullscreen_toggled(); + void event_arrange(); + void event_show_properties(); + void event_show_controls(); + void event_show_engine(); + + SharedPtr _patch; + SharedPtr _view; + + bool _enable_signal; + bool _position_stored; + int _x; + int _y; + + Gtk::MenuItem* _menu_import; + Gtk::MenuItem* _menu_import_location; + Gtk::MenuItem* _menu_save; + Gtk::MenuItem* _menu_save_as; + Gtk::MenuItem* _menu_upload; + Gtk::MenuItem* _menu_cut; + Gtk::MenuItem* _menu_copy; + Gtk::MenuItem* _menu_paste; + Gtk::MenuItem* _menu_delete; + Gtk::MenuItem* _menu_configuration; + Gtk::MenuItem* _menu_close; + Gtk::MenuItem* _menu_quit; + Gtk::MenuItem* _menu_fullscreen; + Gtk::MenuItem* _menu_clear; + Gtk::MenuItem* _menu_destroy_patch; + Gtk::MenuItem* _menu_arrange; + Gtk::MenuItem* _menu_view_engine_window; + Gtk::MenuItem* _menu_view_control_window; + Gtk::MenuItem* _menu_view_patch_properties; + Gtk::MenuItem* _menu_view_messages_window; + Gtk::MenuItem* _menu_view_patch_tree_window; + Gtk::MenuItem* _menu_help_about; + + Gtk::VBox* _vbox; + Gtk::Viewport* _viewport; + BreadCrumbBox* _breadcrumb_box; + + //Gtk::Statusbar* _status_bar; + + /** Invisible bin used to store breadcrumbs when not shown by a view */ + Gtk::Alignment _breadcrumb_bin; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // PATCHWINDOW_H diff --git a/src/libs/gui/Port.cpp b/src/libs/gui/Port.cpp new file mode 100644 index 00000000..9b21b8be --- /dev/null +++ b/src/libs/gui/Port.cpp @@ -0,0 +1,61 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "client/PortModel.h" +#include "client/ControlModel.h" +#include "Configuration.h" +#include "App.h" +#include "Port.h" +using std::cerr; using std::endl; + +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + + +/** @param flip Make an input port appear as an output port, and vice versa. + */ +Port::Port(boost::shared_ptr module, SharedPtr pm, bool flip, bool destroyable) +: LibFlowCanvas::Port(module, + pm->path().name(), + flip ? (!pm->is_input()) : pm->is_input(), + App::instance().configuration()->get_port_color(pm.get())), + _port_model(pm) +{ + assert(module); + assert(_port_model); + + if (destroyable) + _menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Destroy", + sigc::mem_fun(this, &Port::on_menu_destroy))); +} + + +void +Port::on_menu_destroy() +{ + App::instance().engine()->destroy(_port_model->path()); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/Port.h b/src/libs/gui/Port.h new file mode 100644 index 00000000..b798cbca --- /dev/null +++ b/src/libs/gui/Port.h @@ -0,0 +1,57 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PORT_H +#define PORT_H + +#include +#include +#include +#include + +namespace Ingen { namespace Client { class PortModel; } } +using Ingen::Client::PortModel; + +namespace Ingen { +namespace GUI { + + +/** A Port on an Module. + * + * \ingroup GUI + */ +class Port : public LibFlowCanvas::Port +{ +public: + Port(boost::shared_ptr module, SharedPtr pm, bool flip = false, bool destroyable = false); + + virtual ~Port() {} + + SharedPtr model() const { return _port_model; } + +private: + + void on_menu_destroy(); + + SharedPtr _port_model; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // PORT_H diff --git a/src/libs/gui/PortPropertiesWindow.cpp b/src/libs/gui/PortPropertiesWindow.cpp new file mode 100644 index 00000000..10b65641 --- /dev/null +++ b/src/libs/gui/PortPropertiesWindow.cpp @@ -0,0 +1,175 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/NodeModel.h" +#include "client/PluginModel.h" +#include "App.h" +#include "ControlGroups.h" +#include "PortPropertiesWindow.h" + +using std::string; + +namespace Ingen { +namespace GUI { + + +PortPropertiesWindow::PortPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) + : Gtk::Dialog(cobject) + , _enable_signal(false) + , _control(NULL) +{ + xml->get_widget("port_properties_min_spinner", _min_spinner); + xml->get_widget("port_properties_max_spinner", _max_spinner); + xml->get_widget("port_properties_cancel_button", _cancel_button); + xml->get_widget("port_properties_ok_button", _ok_button); + + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, + &PortPropertiesWindow::cancel)); + + _ok_button->signal_clicked().connect(sigc::mem_fun(this, + &PortPropertiesWindow::ok)); +} + + +/** Set the port this window is associated with. + * This function MUST be called before using this object in any way. + */ +void +PortPropertiesWindow::init(ControlGroup* control, SharedPtr pm) +{ + assert(pm); + assert(control); + + _port_model = pm; + _control = control; + + + set_title(pm->path() + " Properties"); + + // FIXME: code duplication w/ ControlGroups.cpp + float min = 0.0f; + float max = 1.0f; + + const Atom& min_atom = pm->get_metadata("ingen:minimum"); + const Atom& max_atom = pm->get_metadata("ingen_maximum"); + if (min_atom.type() == Atom::FLOAT && max_atom.type() == Atom::FLOAT) { + min = min_atom.get_float(); + max = max_atom.get_float(); + } + + const SharedPtr parent = PtrCast(pm->parent()); + + if (parent && parent->plugin() && parent->plugin()->type() == PluginModel::LV2) { + min = slv2_port_get_minimum_value( + parent->plugin()->slv2_plugin(), + slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), + pm->path().name().c_str())); + max = slv2_port_get_maximum_value( + parent->plugin()->slv2_plugin(), + slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), + pm->path().name().c_str())); + } + + if (max <= min) + max = min + 1.0f; + + _initial_min = min; + _initial_max = max; + + _min_spinner->set_value(min); + _min_spinner->signal_value_changed().connect(sigc::mem_fun(*this, &PortPropertiesWindow::min_changed)); + _max_spinner->set_value(max); + _max_spinner->signal_value_changed().connect(sigc::mem_fun(*this, &PortPropertiesWindow::max_changed)); + + pm->metadata_update_sig.connect(sigc::mem_fun(this, &PortPropertiesWindow::metadata_update)); + + _enable_signal = true; +} + + +void +PortPropertiesWindow::metadata_update(const string& key, const Atom& value) +{ + _enable_signal = false; + + if ( (key == "ingen:minimum") && value.type() == Atom::FLOAT) + _min_spinner->set_value(value.get_float()); + else if ( (key == "ingen:maximum") && value.type() == Atom::FLOAT) + _max_spinner->set_value(value.get_float()); + + _enable_signal = true; +} + + +void +PortPropertiesWindow::min_changed() +{ + float min = _min_spinner->get_value(); + const float max = _max_spinner->get_value(); + + if (min >= max) { + min = max - 1.0; + _min_spinner->set_value(min); + } + + _control->set_range(min, max); + + if (_enable_signal) + App::instance().engine()->set_metadata(_port_model->path(), "ingen:minimum", min); +} + + +void +PortPropertiesWindow::max_changed() +{ + const float min = _min_spinner->get_value(); + float max = _max_spinner->get_value(); + + if (max <= min) { + max = min + 1.0; + _max_spinner->set_value(max); + } + + _control->set_range(min, max); + + if (_enable_signal) + App::instance().engine()->set_metadata(_port_model->path(), "ingen:maximum", max); +} + + +void +PortPropertiesWindow::cancel() +{ + App::instance().engine()->set_metadata(_port_model->path(), "ingen:minimum", _initial_min); + App::instance().engine()->set_metadata(_port_model->path(), "ingen:maximum", _initial_max); + delete this; +} + + +void +PortPropertiesWindow::ok() +{ + delete this; +} + + +} // namespace GUI +} // namespace Ingen + diff --git a/src/libs/gui/PortPropertiesWindow.h b/src/libs/gui/PortPropertiesWindow.h new file mode 100644 index 00000000..b7900bc6 --- /dev/null +++ b/src/libs/gui/PortPropertiesWindow.h @@ -0,0 +1,70 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PORTPROPERTIESWINDOW_H +#define PORTPROPERTIESWINDOW_H + +#include +#include +#include +#include "client/PortModel.h" +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + +class ControlGroup; + + +/** Port properties window. + * + * Loaded by libglade as a derived object. + * + * \ingroup GUI + */ +class PortPropertiesWindow : public Gtk::Dialog +{ +public: + PortPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); + + void init(ControlGroup* control, SharedPtr port_model); + +private: + void metadata_update(const string& key, const Atom& value); + void min_changed(); + void max_changed(); + + void ok(); + void cancel(); + + bool _enable_signal; + + float _initial_min; + float _initial_max; + + ControlGroup* _control; + SharedPtr _port_model; + Gtk::SpinButton* _min_spinner; + Gtk::SpinButton* _max_spinner; + Gtk::Button* _cancel_button; + Gtk::Button* _ok_button; +}; + +} // namespace GUI +} // namespace Ingen + +#endif // PORTPROPERTIESWINDOW_H diff --git a/src/libs/gui/RenameWindow.cpp b/src/libs/gui/RenameWindow.cpp new file mode 100644 index 00000000..d9c474a8 --- /dev/null +++ b/src/libs/gui/RenameWindow.cpp @@ -0,0 +1,117 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "interface/EngineInterface.h" +#include "client/ObjectModel.h" +#include "client/Store.h" +#include "App.h" +#include "RenameWindow.h" + +using std::string; + +namespace Ingen { +namespace GUI { + + +RenameWindow::RenameWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) +: Gtk::Window(cobject) +{ + glade_xml->get_widget("rename_name_entry", _name_entry); + glade_xml->get_widget("rename_message_label", _message_label); + glade_xml->get_widget("rename_cancel_button", _cancel_button); + glade_xml->get_widget("rename_ok_button", _ok_button); + + _name_entry->signal_changed().connect(sigc::mem_fun(this, &RenameWindow::name_changed)); + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &RenameWindow::cancel_clicked)); + _ok_button->signal_clicked().connect(sigc::mem_fun(this, &RenameWindow::ok_clicked)); + + _ok_button->property_sensitive() = false; +} + + +/** Set the object this window is renaming. + * This function MUST be called before using this object in any way. + */ +void +RenameWindow::set_object(SharedPtr object) +{ + _object = object; + _name_entry->set_text(object->path().name()); +} + + +/** Called every time the user types into the name input box. + * Used to display warning messages, and enable/disable the rename button. + */ +void +RenameWindow::name_changed() +{ + assert(_name_entry); + assert(_message_label); + assert(_object); + assert(_object->parent()); + + string name = _name_entry->get_text(); + if (name.find("/") != string::npos) { + _message_label->set_text("Name may not contain '/'"); + _ok_button->property_sensitive() = false; + //} else if (_object->parent()->patch_model()->get_node(name) != NULL) { + } else if (App::instance().store()->object(_object->parent()->path().base() + name)) { + _message_label->set_text("An object already exists with that name."); + _ok_button->property_sensitive() = false; + } else if (name.length() == 0) { + _message_label->set_text(""); + _ok_button->property_sensitive() = false; + } else { + _message_label->set_text(""); + _ok_button->property_sensitive() = true; + } +} + + +void +RenameWindow::cancel_clicked() +{ + cout << "cancel\n"; + _name_entry->set_text(""); + hide(); +} + + +/** Rename the object. + * + * It shouldn't be possible for this to be called with an invalid name set + * (since the Rename button should be deactivated). This is just shinification + * though - the engine will handle invalid names gracefully. + */ +void +RenameWindow::ok_clicked() +{ + string name = _name_entry->get_text(); + assert(name.length() > 0); + assert(name.find("/") == string::npos); + + App::instance().engine()->rename(_object->path(), name); + + hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/RenameWindow.h b/src/libs/gui/RenameWindow.h new file mode 100644 index 00000000..56ee3d5a --- /dev/null +++ b/src/libs/gui/RenameWindow.h @@ -0,0 +1,60 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RENAMEWINDOW_H +#define RENAMEWINDOW_H + +#include +#include +#include +#include "client/ObjectModel.h" +using Ingen::Client::ObjectModel; + +namespace Ingen { +namespace GUI { + + +/** Rename window. Handles renaming of any (Ingen) object. + * + * \ingroup GUI + */ +class RenameWindow : public Gtk::Window +{ +public: + RenameWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); + + void present(SharedPtr object) { set_object(object); Gtk::Window::present(); } + +private: + void set_object(SharedPtr object); + + void name_changed(); + void cancel_clicked(); + void ok_clicked(); + + SharedPtr _object; + + Gtk::Entry* _name_entry; + Gtk::Label* _message_label; + Gtk::Button* _cancel_button; + Gtk::Button* _ok_button; +}; + +} // namespace GUI +} // namespace Ingen + +#endif // RENAMEWINDOW_H diff --git a/src/libs/gui/SubpatchModule.cpp b/src/libs/gui/SubpatchModule.cpp new file mode 100644 index 00000000..475774bc --- /dev/null +++ b/src/libs/gui/SubpatchModule.cpp @@ -0,0 +1,95 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "SubpatchModule.h" +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "App.h" +#include "NodeModule.h" +#include "NodeControlWindow.h" +#include "PatchWindow.h" +#include "PatchCanvas.h" +#include "Port.h" +#include "WindowFactory.h" +using std::cerr; using std::cout; using std::endl; + +namespace Ingen { +namespace GUI { + + +SubpatchModule::SubpatchModule(boost::shared_ptr canvas, SharedPtr patch) +: NodeModule(canvas, patch), + _patch(patch) +{ + assert(canvas); + assert(patch); +} + + +void +SubpatchModule::on_double_click(GdkEventButton* event) +{ + assert(_patch); + + SharedPtr parent = PtrCast(_patch->parent()); + + PatchWindow* const preferred = ( (parent && (event->state & GDK_SHIFT_MASK)) + ? NULL + : App::instance().window_factory()->patch_window(parent) ); + + App::instance().window_factory()->present_patch(_patch, preferred); +} + + + +/** Browse to this patch in current (parent's) window + * (unless an existing window is displaying it) + */ +void +SubpatchModule::browse_to_patch() +{ + assert(_patch->parent()); + + SharedPtr parent = PtrCast(_patch->parent()); + + PatchWindow* const preferred = ( (parent) + ? App::instance().window_factory()->patch_window(parent) + : NULL ); + + App::instance().window_factory()->present_patch(_patch, preferred); +} + + + +void +SubpatchModule::show_dialog() +{ + cerr << "FIXME: dialog\n"; + //m_patch->show_control_window(); +} + + +void +SubpatchModule::menu_remove() +{ + App::instance().engine()->destroy(_patch->path()); +} + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/SubpatchModule.h b/src/libs/gui/SubpatchModule.h new file mode 100644 index 00000000..4dc17e8b --- /dev/null +++ b/src/libs/gui/SubpatchModule.h @@ -0,0 +1,71 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef SUBPATCHMODULE_H +#define SUBPATCHMODULE_H + +#include +#include +#include +#include "client/PatchModel.h" +#include "PatchPortModule.h" +#include "NodeModule.h" +using std::string; using std::list; + +namespace Ingen { namespace Client { + class PatchModel; + class NodeModel; + class PortModel; + class PatchWindow; +} } +using namespace Ingen::Client; + +namespace Ingen { +namespace GUI { + +class PatchCanvas; +class NodeControlWindow; + + +/** A module to represent a subpatch + * + * \ingroup GUI + */ +class SubpatchModule : public NodeModule +{ +public: + SubpatchModule(boost::shared_ptr canvas, SharedPtr controller); + virtual ~SubpatchModule() {} + + void on_double_click(GdkEventButton* ev); + + void show_dialog(); + void browse_to_patch(); + void menu_remove(); + + SharedPtr patch() { return _patch; } + +protected: + SharedPtr _patch; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // SUBPATCHMODULE_H diff --git a/src/libs/gui/ThreadedLoader.cpp b/src/libs/gui/ThreadedLoader.cpp new file mode 100644 index 00000000..120d9b6c --- /dev/null +++ b/src/libs/gui/ThreadedLoader.cpp @@ -0,0 +1,141 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "client/PatchModel.h" +#include "module/Module.h" +#include "App.h" +#include "ThreadedLoader.h" +using std::cout; using std::endl; + +namespace Ingen { +namespace GUI { + + +ThreadedLoader::ThreadedLoader(SharedPtr engine) + : _serialisation_module(Ingen::Shared::load_module("ingen_serialisation")) + , _engine(engine) + , _deprecated_loader(engine) + , _serializer(*App::instance().rdf_world()) +{ + // FIXME: rework this so the thread is only present when it's doing something (save mem) + if (_serialisation_module) { + Loader* (*new_loader)() = NULL; + bool found = _serialisation_module->get_symbol("new_loader", (void*&)new_loader); + if (found) + _loader = SharedPtr(new_loader()); + } + + if (_loader) { + start(); + } else { + cerr << "WARNING: Failed to load ingen_serialisation module, unable to load patches." << endl;; + cerr << "If you are running from the source tree, run ingenuity_dev." << endl; + } +} + + +ThreadedLoader::~ThreadedLoader() +{ +} + + +void +ThreadedLoader::_whipped() +{ + _mutex.lock(); + + while ( ! _events.empty() ) { + _events.front()(); + _events.pop_front(); + } + + _mutex.unlock(); +} + +/** FIXME: use poly parameter */ +void +ThreadedLoader::load_patch(bool merge, + const string& data_base_uri, + const Path& data_path, + MetadataMap engine_data, + optional engine_parent, + optional engine_name, + optional engine_poly) +{ + _mutex.lock(); + + // FIXME: Filthy hack to load deprecated patches based on file extension + if (data_base_uri.substr(data_base_uri.length()-3) == ".om") { + _events.push_back(sigc::hide_return(sigc::bind( + sigc::mem_fun(_deprecated_loader, &DeprecatedLoader::load_patch), + data_base_uri, + engine_parent, + (engine_name) ? engine_name.get() : "", + (engine_poly) ? engine_poly.get() : 1, + engine_data, + false))); + } else { + _events.push_back(sigc::hide_return(sigc::bind( + sigc::mem_fun(_loader.get(), &Ingen::Serialisation::Loader::load), + App::instance().engine(), + App::instance().rdf_world(), + data_base_uri, + engine_parent, + (engine_name) ? engine_name.get() : "", + // FIXME: poly here + "", + engine_data ))); + } + + _mutex.unlock(); + + whip(); +} + + +void +ThreadedLoader::save_patch(SharedPtr model, const string& filename, bool recursive) +{ + _mutex.lock(); + + _events.push_back(sigc::hide_return(sigc::bind( + sigc::mem_fun(this, &ThreadedLoader::save_patch_event), + model, filename, recursive))); + + _mutex.unlock(); + + whip(); +} + + +void +ThreadedLoader::save_patch_event(SharedPtr model, const string& filename, bool recursive) +{ + if (recursive) + cerr << "FIXME: Recursive save." << endl; + + _serializer.start_to_filename(filename); + _serializer.serialize(model); + _serializer.finish(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/ThreadedLoader.h b/src/libs/gui/ThreadedLoader.h new file mode 100644 index 00000000..58a18fae --- /dev/null +++ b/src/libs/gui/ThreadedLoader.h @@ -0,0 +1,99 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef THREADEDLOADER_H +#define THREADEDLOADER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/PatchModel.h" +#include "client/Serializer.h" +#include "client/DeprecatedLoader.h" +#include "serialisation/Loader.h" +using std::string; +using std::list; +using boost::optional; + +using namespace Ingen::Client; +using namespace Ingen::Serialisation; + +namespace Ingen { +namespace GUI { + + +/** Thread for loading patch files. + * + * This is a seperate thread so it can send all the loading message without + * blocking everything else, so the app can respond to the incoming events + * caused as a result of the patch loading, while the patch loads. + * + * Implemented as a slave with a list of closures (events) which processes + * all events in the (mutex protected) list each time it's whipped. + * + * \ingroup GUI + */ +class ThreadedLoader : public Raul::Slave +{ +public: + ThreadedLoader(SharedPtr engine); + ~ThreadedLoader(); + + // FIXME: there's a pattern here.... + // (same core interface as Loader/Serializer) + + void load_patch(bool merge, + const string& data_base_uri, + const Path& data_path, + MetadataMap engine_data, + optional engine_parent, + optional engine_name = optional(), + optional engine_poly = optional()); + + void save_patch(SharedPtr model, const string& filename, bool recursive); + +private: + + void save_patch_event(SharedPtr model, const string& filename, bool recursive); + + /** Returns nothing and takes no parameters (because they have all been bound) */ + typedef sigc::slot Closure; + + void _whipped(); + + SharedPtr _serialisation_module; + + SharedPtr _engine; + SharedPtr _loader; + + DeprecatedLoader _deprecated_loader; + Serializer _serializer; + Raul::Mutex _mutex; + list _events; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // LOADERRTHREAD_H diff --git a/src/libs/gui/UploadPatchWindow.cpp b/src/libs/gui/UploadPatchWindow.cpp new file mode 100644 index 00000000..7def01a0 --- /dev/null +++ b/src/libs/gui/UploadPatchWindow.cpp @@ -0,0 +1,283 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "interface/EngineInterface.h" +#include "client/Serializer.h" +#include "client/PatchModel.h" +#include "UploadPatchWindow.h" +#include "App.h" +#include "Configuration.h" +#include "ThreadedLoader.h" + +using boost::optional; +using namespace Raul; +using namespace std; + +namespace Ingen { +namespace GUI { + + +UploadPatchWindow::UploadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) + : Gtk::Dialog(cobject) + , _thread(NULL) + , _progress_pct(0) + , _response(0) +{ + xml->get_widget("upload_patch_symbol_entry", _symbol_entry); + xml->get_widget("upload_patch_short_name_entry", _short_name_entry); + xml->get_widget("upload_patch_progress", _upload_progress); + xml->get_widget("upload_patch_cancel_button", _cancel_button); + xml->get_widget("upload_patch_upload_button", _upload_button); + + + _symbol_entry->signal_changed().connect(sigc::mem_fun(this, &UploadPatchWindow::symbol_changed)); + _short_name_entry->signal_changed().connect(sigc::mem_fun(this, &UploadPatchWindow::short_name_changed)); + _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &UploadPatchWindow::cancel_clicked)); + _upload_button->signal_clicked().connect(sigc::mem_fun(this, &UploadPatchWindow::upload_clicked)); +} + + +void +UploadPatchWindow::present(SharedPtr patch) +{ + _patch = patch; + + Gtk::Window::present(); +} + + +void +UploadPatchWindow::on_show() +{ + Gtk::Dialog::on_show(); + + Raul::Atom atom = _patch->get_metadata("lv2:symbol"); + if (atom) + _symbol_entry->set_text(atom.get_string()); + + atom = _patch->get_metadata("doap:name"); + if (atom) + _short_name_entry->set_text(atom.get_string()); +} + + +void +UploadPatchWindow::on_hide() +{ + Gtk::Dialog::on_hide(); + + delete _thread; + _thread = NULL; +} + + +bool +UploadPatchWindow::is_symbol(const Glib::ustring& s) +{ + if (s.length() == 0) + return false; + + for (unsigned i=0; i < s.length(); ++i) + if ( !( (s[i] >= 'a' && s[i] <= 'z') + || (s[i] >= 'A' && s[i] <= 'Z') + || (s[i] == '_') + || (i > 0 && s[i] >= '0' && s[i] <= '9') ) ) + return false; + + return true; +} + + +void +UploadPatchWindow::symbol_changed() +{ + _upload_button->property_sensitive() = ( + is_symbol(_symbol_entry->get_text()) + && _short_name_entry->get_text().length() > 0); +} + + +void +UploadPatchWindow::short_name_changed() +{ + _upload_button->property_sensitive() = ( + is_symbol(_symbol_entry->get_text()) + && _short_name_entry->get_text().length() > 0); +} + + +size_t +UploadThread::curl_read_cb(void *ptr, size_t size, size_t nmemb, void *data) +{ + assert(size == 1); + + istringstream* ss = (istringstream*)data; + + return ss->readsome((char*)ptr, nmemb); +} + + +int +UploadThread::curl_progress_cb(void *thread, + double dltotal, + double dlnow, + double ultotal, + double ulnow) +{ + UploadThread* me = (UploadThread*)thread; + me->_win->set_progress(min( + (int)(min(ulnow, (double)me->_length) / me->_length * 100.0), + 99)); + return 0; +} + + +UploadThread::UploadThread(UploadPatchWindow* win, const string& str, const string& url) + : Thread("Upload") + , _curl(NULL) + , _headers(NULL) + , _win(win) + , _length(str.length()) + , _stream(str) + , _url(url) +{ + _curl = curl_easy_init(); + _headers = curl_slist_append(NULL, "Content-type: application/x-turtle"); + + curl_easy_setopt(_curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, _headers); + curl_easy_setopt(_curl, CURLOPT_UPLOAD, 1); + curl_easy_setopt(_curl, CURLOPT_READDATA, &_stream); + curl_easy_setopt(_curl, CURLOPT_READFUNCTION, &UploadThread::curl_read_cb); + curl_easy_setopt(_curl, CURLOPT_INFILESIZE, sizeof(char) * str.length()); + curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, FALSE); + curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &UploadThread::curl_progress_cb); + curl_easy_setopt(_curl, CURLOPT_PROGRESSDATA, this); +} + + +void +UploadThread::_run() +{ + curl_easy_perform(_curl); + + long response; + curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &response); + + printf("Server returned %ld\n", response); + + _win->set_response(response); + _win->set_progress(100); + + curl_slist_free_all(_headers); + curl_easy_cleanup(_curl); + + _headers = NULL; + _curl = NULL; +} + + +bool +UploadPatchWindow::progress_callback() +{ + const int progress = _progress_pct.get(); + const int response = _response.get(); + + _upload_progress->set_fraction(progress / 100.0); + + if (progress == 100) { + if (response == 200) { + _upload_progress->set_text("Transfer completed"); + } else { + _upload_progress->set_fraction(0.0); + char status[4]; + snprintf(status, 4, "%d", (unsigned)response); + string msg = "Transfer failed: Server returned "; + msg.append(status); + _upload_progress->set_text(msg); + } + delete _thread; + _thread = NULL; + _upload_button->set_sensitive(true); + return false; + } else { + return true; + } +} + + +void +UploadPatchWindow::upload_clicked() +{ + assert(!_thread); + + Glib::ustring symbol = _symbol_entry->get_text(); + Glib::ustring short_name = _short_name_entry->get_text(); + + _patch->set_metadata("lv2:symbol", Atom(symbol)); + App::instance().engine()->set_metadata(_patch->path(), "lv2:symbol", Atom(symbol)); + + _patch->set_metadata("doap:name", Atom(short_name)); + App::instance().engine()->set_metadata(_patch->path(), "doap:name", Atom(short_name)); + + _response = 0; + _progress_pct = 0; + + _upload_progress->set_fraction(0.0); + _upload_progress->set_text(""); + + Serializer s(*App::instance().rdf_world()); + s.start_to_string(); + s.serialize(_patch); + const string str = s.finish(); + istringstream stream(str); + + string url = "http://rdf.drobilla.net/ingen_patches/"; + url += symbol + ".ingen.ttl"; + + _thread = new UploadThread(this, str, url); + + _thread->start(); + + _upload_button->set_sensitive(false); + + Glib::signal_timeout().connect( + sigc::mem_fun(this, &UploadPatchWindow::progress_callback), 100); +} + + +void +UploadPatchWindow::cancel_clicked() +{ + if (_thread) { + delete _thread; + _thread = NULL; + } + + hide(); +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/UploadPatchWindow.h b/src/libs/gui/UploadPatchWindow.h new file mode 100644 index 00000000..13272215 --- /dev/null +++ b/src/libs/gui/UploadPatchWindow.h @@ -0,0 +1,105 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UPLOADPATCHWINDOW_H +#define UPLOADPATCHWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include "client/PatchModel.h" +#include "client/PluginModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; + +namespace Ingen { +namespace GUI { + +class UploadPatchWindow; + + +class UploadThread : public Raul::Thread { +public: + UploadThread(UploadPatchWindow* win, + const string& str, + const string& url); + +private: + static size_t curl_read_cb(void* ptr, size_t size, size_t nmemb, void *stream); + static int curl_progress_cb(void* thread, double dltotal, double dlnow, double ultotal, double ulnow); + + void _run(); + + CURL* _curl; + curl_slist* _headers; + UploadPatchWindow* _win; + size_t _length; + std::istringstream _stream; + std::string _url; +}; + + +/* Upload patch dialog. + * + * \ingroup GUI + */ +class UploadPatchWindow : public Gtk::Dialog +{ +public: + UploadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); + + void present(SharedPtr patch); + + Gtk::ProgressBar* progress_bar() { return _upload_progress; } + + void set_response(int response) { _response = response; } + void set_progress(int pct) { _progress_pct = pct; } + +private: + bool is_symbol(const Glib::ustring& str); + void symbol_changed(); + void short_name_changed(); + void cancel_clicked(); + void upload_clicked(); + void on_show(); + void on_hide(); + bool progress_callback(); + + UploadThread* _thread; + + SharedPtr _patch; + + Raul::AtomicInt _progress_pct; + Raul::AtomicInt _response; + + Gtk::Entry* _symbol_entry; + Gtk::Entry* _short_name_entry; + Gtk::ProgressBar* _upload_progress; + Gtk::Button* _cancel_button; + Gtk::Button* _upload_button; + +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // UPLOADPATCHWINDOW_H diff --git a/src/libs/gui/WindowFactory.cpp b/src/libs/gui/WindowFactory.cpp new file mode 100644 index 00000000..7c2e3eaa --- /dev/null +++ b/src/libs/gui/WindowFactory.cpp @@ -0,0 +1,357 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "WindowFactory.h" +#include "App.h" +#include "PatchWindow.h" +#include "GladeFactory.h" +#include "NodePropertiesWindow.h" +#include "PatchPropertiesWindow.h" +#include "NodeControlWindow.h" +#include "LoadPluginWindow.h" +#include "LoadPatchWindow.h" +#include "LoadRemotePatchWindow.h" +#include "UploadPatchWindow.h" +#include "LoadSubpatchWindow.h" +#include "RenameWindow.h" +#include "NewSubpatchWindow.h" + +namespace Ingen { +namespace GUI { + + +WindowFactory::WindowFactory() +: _load_plugin_win(NULL) +, _load_patch_win(NULL) +, _load_remote_patch_win(NULL) +, _upload_patch_win(NULL) +, _new_subpatch_win(NULL) +, _load_subpatch_win(NULL) +, _node_properties_win(NULL) +, _patch_properties_win(NULL) +{ + Glib::RefPtr xml = GladeFactory::new_glade_reference(); + + xml->get_widget_derived("load_plugin_win", _load_plugin_win); + xml->get_widget_derived("load_patch_win", _load_patch_win); + xml->get_widget_derived("load_remote_patch_win", _load_remote_patch_win); + xml->get_widget_derived("upload_patch_win", _upload_patch_win); + xml->get_widget_derived("new_subpatch_win", _new_subpatch_win); + xml->get_widget_derived("load_subpatch_win", _load_subpatch_win); + xml->get_widget_derived("node_properties_win", _node_properties_win); + xml->get_widget_derived("patch_properties_win", _patch_properties_win); +} + + +WindowFactory::~WindowFactory() +{ + for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) + delete i->second; + + for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i) + delete i->second; + +} + + +void +WindowFactory::clear() +{ + for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) + delete i->second; + + _patch_windows.clear(); + + for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i) + delete i->second; + + _control_windows.clear(); +} + + +/** Returns the number of Patch windows currently visible. + */ +size_t +WindowFactory::num_open_patch_windows() +{ + size_t ret = 0; + for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) + if (i->second->is_visible()) + ++ret; + + return ret; +} + + + +PatchWindow* +WindowFactory::patch_window(SharedPtr patch) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + return (w == _patch_windows.end()) ? NULL : w->second; +} + + +NodeControlWindow* +WindowFactory::control_window(SharedPtr node) +{ + ControlWindowMap::iterator w = _control_windows.find(node->path()); + + return (w == _control_windows.end()) ? NULL : w->second; +} + + +/** Present a PatchWindow for a Patch. + * + * If @a preferred is not NULL, it will be set to display @a patch if the patch + * does not already have a visible window, otherwise that window will be presented and + * @a preferred left unmodified. + */ +void +WindowFactory::present_patch(SharedPtr patch, PatchWindow* preferred, SharedPtr view) +{ + assert( !view || view->patch() == patch); + + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + if (w != _patch_windows.end()) { + (*w).second->present(); + } else if (preferred) { + w = _patch_windows.find(preferred->patch()->path()); + assert((*w).second == preferred); + + preferred->set_patch(patch, view); + _patch_windows.erase(w); + _patch_windows[patch->path()] = preferred; + preferred->present(); + + } else { + PatchWindow* win = new_patch_window(patch, view); + win->present(); + } +} + + +PatchWindow* +WindowFactory::new_patch_window(SharedPtr patch, SharedPtr view) +{ + assert( !view || view->patch() == patch); + + Glib::RefPtr xml = GladeFactory::new_glade_reference("patch_win"); + + PatchWindow* win = NULL; + xml->get_widget_derived("patch_win", win); + assert(win); + + win->set_patch(patch, view); + _patch_windows[patch->path()] = win; + + win->signal_delete_event().connect(sigc::bind<0>( + sigc::mem_fun(this, &WindowFactory::remove_patch_window), win)); + + return win; +} + + +bool +WindowFactory::remove_patch_window(PatchWindow* win, GdkEventAny* ignored) +{ + if (_patch_windows.size() <= 1) { + Gtk::MessageDialog d(*win, "This is the last remaining open patch " + "window. Closing this window will exit Ingenuity (the engine will " + "remain running).\n\nAre you sure you want to quit?", + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); + d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); + int ret = d.run(); + if (ret == Gtk::RESPONSE_CLOSE) + App::instance().quit(); + else + return true; + } + + PatchWindowMap::iterator w = _patch_windows.find(win->patch()->path()); + + assert((*w).second == win); + _patch_windows.erase(w); + + delete win; + + return false; +} + + +void +WindowFactory::present_controls(SharedPtr node) +{ + NodeControlWindow* win = control_window(node); + + if (win) { + win->present(); + } else { + win = new_control_window(node); + win->present(); + } +} + + +NodeControlWindow* +WindowFactory::new_control_window(SharedPtr node) +{ + size_t poly = 1; + if (node->polyphonic()) + poly = ((PatchModel*)node->parent().get())->poly(); + + NodeControlWindow* win = new NodeControlWindow(node, poly); + + _control_windows[node->path()] = win; + + win->signal_delete_event().connect(sigc::bind<0>( + sigc::mem_fun(this, &WindowFactory::remove_control_window), win)); + + return win; +} + + +bool +WindowFactory::remove_control_window(NodeControlWindow* win, GdkEventAny* ignored) +{ + ControlWindowMap::iterator w = _control_windows.find(win->node()->path()); + + assert((*w).second == win); + _control_windows.erase(w); + + delete win; + + return true; +} + + +void +WindowFactory::present_load_plugin(SharedPtr patch, MetadataMap data) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + if (w != _patch_windows.end()) + _load_plugin_win->set_transient_for(*w->second); + + _load_plugin_win->present(patch, data); +} + + +void +WindowFactory::present_load_patch(SharedPtr patch, MetadataMap data) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + if (w != _patch_windows.end()) + _load_patch_win->set_transient_for(*w->second); + + _load_patch_win->set_merge(); // Import is the only choice + + _load_patch_win->present(patch, data); +} + + +void +WindowFactory::present_load_remote_patch(SharedPtr patch, MetadataMap data) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + if (w != _patch_windows.end()) + _load_remote_patch_win->set_transient_for(*w->second); + + _load_remote_patch_win->set_merge(); // Import is the only choice + + _load_remote_patch_win->present(patch, data); +} + + +void +WindowFactory::present_upload_patch(SharedPtr patch) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + if (w != _patch_windows.end()) + _upload_patch_win->set_transient_for(*w->second); + + _upload_patch_win->present(patch); +} + + +void +WindowFactory::present_new_subpatch(SharedPtr patch, MetadataMap data) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + if (w != _patch_windows.end()) + _new_subpatch_win->set_transient_for(*w->second); + + _new_subpatch_win->present(patch, data); +} + + +void +WindowFactory::present_load_subpatch(SharedPtr patch, MetadataMap data) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + if (w != _patch_windows.end()) + _load_subpatch_win->set_transient_for(*w->second); + + _load_subpatch_win->present(patch, data); +} + + +void +WindowFactory::present_rename(SharedPtr object) +{ + PatchWindowMap::iterator w = _patch_windows.find(object->path()); + + if (w != _patch_windows.end()) + _rename_win->set_transient_for(*w->second); + + _rename_win->present(object); +} + + +void +WindowFactory::present_properties(SharedPtr node) +{ + SharedPtr patch = PtrCast(node); + if (patch) { + + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + if (w != _patch_windows.end()) + _patch_properties_win->set_transient_for(*w->second); + + _patch_properties_win->present(patch); + + } else { + + PatchWindowMap::iterator w = _patch_windows.find(node->parent()->path()); + if (w != _patch_windows.end()) + _node_properties_win->set_transient_for(*w->second); + + _node_properties_win->present(node); + } +} + + +} // namespace GUI +} // namespace Ingen diff --git a/src/libs/gui/WindowFactory.h b/src/libs/gui/WindowFactory.h new file mode 100644 index 00000000..c3170dce --- /dev/null +++ b/src/libs/gui/WindowFactory.h @@ -0,0 +1,105 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef WINDOW_FACTORY_H +#define WINDOW_FACTORY_H + +#include +#include +#include +#include "client/PatchModel.h" +#include "PatchView.h" + +using Ingen::Client::PatchModel; + +namespace Ingen { +namespace GUI { + +class PatchWindow; +class NodeControlWindow; +class NodePropertiesWindow; +class PatchPropertiesWindow; +class LoadPatchWindow; +class LoadRemotePatchWindow; +class UploadPatchWindow; +class RenameWindow; + + +/** Manager/Factory for all windows. + * + * This serves as a nice centralized spot for all window management issues, + * as well as an enumeration of all windows (the goal being to reduce that + * number as much as possible). + */ +class WindowFactory { +public: + WindowFactory(); + ~WindowFactory(); + + size_t num_open_patch_windows(); + + PatchWindow* patch_window(SharedPtr patch); + NodeControlWindow* control_window(SharedPtr node); + + void present_patch(SharedPtr patch, + PatchWindow* preferred = NULL, + SharedPtr patch = SharedPtr()); + + void present_controls(SharedPtr node); + + void present_load_plugin(SharedPtr patch, MetadataMap data = MetadataMap()); + void present_load_patch(SharedPtr patch, MetadataMap data = MetadataMap()); + void present_load_remote_patch(SharedPtr patch, MetadataMap data = MetadataMap()); + void present_upload_patch(SharedPtr patch); + void present_new_subpatch(SharedPtr patch, MetadataMap data = MetadataMap()); + void present_load_subpatch(SharedPtr patch, MetadataMap data = MetadataMap()); + void present_rename(SharedPtr object); + void present_properties(SharedPtr node); + + bool remove_patch_window(PatchWindow* win, GdkEventAny* ignored = NULL); + + void clear(); + +private: + typedef std::map PatchWindowMap; + typedef std::map ControlWindowMap; + + PatchWindow* new_patch_window(SharedPtr patch, SharedPtr view); + + + NodeControlWindow* new_control_window(SharedPtr node); + bool remove_control_window(NodeControlWindow* win, GdkEventAny* ignored); + + PatchWindowMap _patch_windows; + ControlWindowMap _control_windows; + + LoadPluginWindow* _load_plugin_win; + LoadPatchWindow* _load_patch_win; + LoadRemotePatchWindow* _load_remote_patch_win; + UploadPatchWindow* _upload_patch_win; + NewSubpatchWindow* _new_subpatch_win; + LoadSubpatchWindow* _load_subpatch_win; + NodePropertiesWindow* _node_properties_win; + PatchPropertiesWindow* _patch_properties_win; + RenameWindow* _rename_win; +}; + + +} // namespace GUI +} // namespace Ingen + +#endif // WINDOW_FACTORY_H diff --git a/src/libs/gui/cmdline.h b/src/libs/gui/cmdline.h new file mode 100644 index 00000000..6f1f9259 --- /dev/null +++ b/src/libs/gui/cmdline.h @@ -0,0 +1,86 @@ +/* cmdline.h */ + +/* File autogenerated by gengetopt version 2.19.1 */ + +#ifndef CMDLINE_H +#define CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +#define CMDLINE_PARSER_PACKAGE "ingen" +#endif + +#ifndef CMDLINE_PARSER_VERSION +#define CMDLINE_PARSER_VERSION VERSION +#endif + +struct gengetopt_args_info +{ + const char *help_help; /* Print help and exit help description. */ + const char *version_help; /* Print version and exit help description. */ + int engine_flag; /* Run (JACK) engine (default=off). */ + const char *engine_help; /* Run (JACK) engine help description. */ + int engine_port_arg; /* Engine OSC port (default='16180'). */ + char * engine_port_orig; /* Engine OSC port original value given at command line. */ + const char *engine_port_help; /* Engine OSC port help description. */ + char * connect_arg; /* Connect to existing engine at OSC URI (default='osc.udp://localhost:16180'). */ + char * connect_orig; /* Connect to existing engine at OSC URI original value given at command line. */ + const char *connect_help; /* Connect to existing engine at OSC URI help description. */ + int gui_flag; /* Launch the GTK graphical interface (default=on). */ + const char *gui_help; /* Launch the GTK graphical interface help description. */ + int client_port_arg; /* Client OSC port. */ + char * client_port_orig; /* Client OSC port original value given at command line. */ + const char *client_port_help; /* Client OSC port help description. */ + char * load_arg; /* Load patch. */ + char * load_orig; /* Load patch original value given at command line. */ + const char *load_help; /* Load patch help description. */ + char * path_arg; /* Target path for loaded patch. */ + char * path_orig; /* Target path for loaded patch original value given at command line. */ + const char *path_help; /* Target path for loaded patch help description. */ + + int help_given ; /* Whether help was given. */ + int version_given ; /* Whether version was given. */ + int engine_given ; /* Whether engine was given. */ + int engine_port_given ; /* Whether engine-port was given. */ + int connect_given ; /* Whether connect was given. */ + int gui_given ; /* Whether gui was given. */ + int client_port_given ; /* Whether client-port was given. */ + int load_given ; /* Whether load was given. */ + int path_given ; /* Whether path was given. */ + +} ; + +extern const char *gengetopt_args_info_purpose; +extern const char *gengetopt_args_info_usage; +extern const char *gengetopt_args_info_help[]; + +int cmdline_parser (int argc, char * const *argv, + struct gengetopt_args_info *args_info); +int cmdline_parser2 (int argc, char * const *argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +void cmdline_parser_print_help(void); +void cmdline_parser_print_version(void); + +void cmdline_parser_init (struct gengetopt_args_info *args_info); +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* CMDLINE_H */ diff --git a/src/libs/gui/ingen-icon.svg b/src/libs/gui/ingen-icon.svg new file mode 100644 index 00000000..a15ed7e7 --- /dev/null +++ b/src/libs/gui/ingen-icon.svg @@ -0,0 +1,54 @@ + + + + + + + image/svg+xml + + + + + + + + diff --git a/src/libs/gui/ingen.svg b/src/libs/gui/ingen.svg new file mode 100644 index 00000000..a15ed7e7 --- /dev/null +++ b/src/libs/gui/ingen.svg @@ -0,0 +1,54 @@ + + + + + + + image/svg+xml + + + + + + + + diff --git a/src/libs/gui/ingen_gui.glade b/src/libs/gui/ingen_gui.glade new file mode 100644 index 00000000..6eaf300e --- /dev/null +++ b/src/libs/gui/ingen_gui.glade @@ -0,0 +1,3044 @@ + + + + + + Ingenuity + 640 + 480 + ingen.svg + + + True + + + True + + + True + _File + True + + + + + True + Load a patch into the current patch (merge with existing contents). + _Import... + True + + + + + True + gtk-open + 1 + + + + + + + True + Import a patch from a URI + Import _Location... + True + + + + + True + gtk-open + 1 + + + + + + + True + + + + + True + Save this patch + gtk-save + True + True + + + + + + True + Save this patch to a specific file name + Save _As... + True + + + + True + gtk-save-as + 1 + + + + + + + True + _Upload... + True + + + + + True + gtk-network + 1 + + + + + + + True + + + + + True + Configure OmGtk + Confi_guration... + True + + + + True + gtk-preferences + 1 + + + + + + + True + + + + + True + Close this window (patch will not be destroyed) + gtk-close + True + True + + + + + + True + + + + + True + Quit Ingenuity (engine may continue running) + gtk-quit + True + True + + + + + + + + + + True + _Edit + True + + + + + True + Remove all objects from patch + gtk-clear + True + True + + + + + + True + + + + + True + False + gtk-cut + True + True + + + + + + True + gtk-copy + True + True + + + + + + True + False + gtk-paste + True + True + + + + + + True + gtk-delete + True + True + + + + + + + + + + True + _Patch + True + + + + + True + gtk-fullscreen + True + True + + + + + + True + + + + + True + Automatically arrange canvas + _Arrange + True + + + + True + gtk-sort-ascending + 1 + + + + + + + True + View/Edit controls for this patch + _Controls... + True + + + + + True + gtk-preferences + 1 + + + + + + + True + View/Edit properties for this patch + _Properties... + True + + + + + True + gtk-properties + 1 + + + + + + + True + Destoy this patch (remove it from the engine) + _Destroy + True + + + + True + gtk-delete + 1 + + + + + + + + + + + True + _Windows + True + + + + + + True + Connect to, Disconnect from, or Launch Engine + _Engine... + True + + + + + True + gtk-execute + 1 + + + + + + + True + View all patches in the engine as a heirarchial list + _Patch Tree... + True + + + + + True + gtk-index + 1 + + + + + + + True + View error messages from the engine + _Messages... + True + + + + + True + gtk-info + 1 + + + + + + + + + + + True + _Help + True + + + + + + True + Right-click the canvas to add objects + True + + + + True + gtk-info + 1 + + + + + + + True + + + + + True + gtk-about + True + True + + + + + + + + + + False + False + + + + + True + True + GTK_POLICY_NEVER + GTK_POLICY_NEVER + + + True + GTK_SHADOW_NONE + + + + + + + + 1 + + + + + + + 8 + Load Plugin + GTK_WIN_POS_CENTER_ON_PARENT + 640 + 480 + ingen.svg + + + True + 1 + + + True + True + 2 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + + + True + True + All plugins available for loading + 2 + True + True + + + + + + + True + 3 + 3 + 12 + + + True + True + Clear filter text (show all plugins) + gtk-clear + True + + + 2 + 3 + GTK_FILL + + + + + + True + Name contains: + + + GTK_FILL + + + + + + True + True + True + Search string to filter plugin list + * + + + 1 + 2 + 6 + + + + + True + False + True + Add selected plugin to patch + gtk-add + True + + + 2 + 3 + 2 + 3 + GTK_FILL + + + + + + True + + + True + True + Name of new Module + * + + + + + True + True + Polyphonic + True + True + True + + + False + False + 8 + 1 + + + + + 1 + 2 + 2 + 3 + GTK_FILL + GTK_FILL + 6 + + + + + True + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + 1 + Node Name: + True + + + 2 + 3 + GTK_FILL + + + + + + False + False + 1 + + + + + + + 320 + 8 + Create Subpatch + GTK_WIN_POS_CENTER_ON_PARENT + ingen.svg + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + + + True + 2 + 2 + + + True + True + True + * + True + + + 1 + 2 + + 4 + + + + + True + True + 1 0 100 1 10 10 + 1 + + + 1 + 2 + 1 + 2 + GTK_FILL + + 4 + + + + + True + 0 + Polyphony: + + + 1 + 2 + GTK_FILL + GTK_EXPAND + 5 + + + + + True + 0 + Name: + + + GTK_FILL + GTK_EXPAND + 5 + + + + + + + True + True + + + False + False + 1 + + + + + True + 4 + GTK_BUTTONBOX_END + + + True + True + gtk-cancel + True + + + + + True + True + True + True + + + True + 0 + 0 + + + True + 2 + + + True + gtk-ok + + + False + False + + + + + True + Create + True + + + False + False + 1 + + + + + + + + + 1 + + + + + 2 + + + + + + + Load Subpatch + GTK_WIN_POS_CENTER_ON_PARENT + ingen.svg + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + 24 + + + True + 2 + 4 + 12 + 4 + + + True + + + True + True + Specify the name for the new patch + Specify: + True + True + load_subpatch_name_from_file_radio + + + False + False + + + + + True + False + True + Specify the name for the new patch + * + True + + + False + 1 + + + + + 3 + 4 + GTK_FILL + + + + + True + 0 + + + 2 + 3 + GTK_FILL + + + + + + True + True + Set polyphony to the same value as the parent (containing) patch + Same as parent (?) + True + True + load_subpatch_poly_from_file_radio + + + 2 + 3 + 1 + 2 + GTK_FILL + + + + + + True + + + True + True + Specify a custom polyphony value for new patch + Specify: + True + True + load_subpatch_poly_from_file_radio + + + False + False + + + + + True + False + True + Specify a custom polyphony value for new patch + 1 0 1000 1 10 10 + 1 + + + False + 1 + + + + + 3 + 4 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + True + Use the polyphony value stored in the patch file + Load from file + True + True + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + True + Use the name stored in the patch file + Load from file + True + True + True + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + <b>Polyphony: </b> + True + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + <b>Name: </b> + True + + + GTK_FILL + + + + + + False + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + -6 + + + + + True + True + True + True + gtk-open + True + -5 + + + 1 + + + + + False + GTK_PACK_END + + + + + + + Load Patch + GTK_WIN_POS_CENTER_ON_PARENT + ingen.svg + GDK_WINDOW_TYPE_HINT_DIALOG + + + 24 + + + True + 1 + 4 + 12 + 4 + + + True + + + True + True + Specify: + True + True + load_patch_poly_from_current_radio + + + False + False + + + + + True + False + True + Specify a custom polyphony value for new patch + 1 0 100 1 10 10 + 1 + + + False + 1 + + + + + 3 + 4 + GTK_FILL + GTK_FILL + + + + + True + True + Use the polyphony value stored in the patch file + Load from file + True + True + load_patch_poly_from_current_radio + + + 2 + 3 + GTK_FILL + + + + + + True + True + Use the same polyphony as the current patch + Keep current + True + True + True + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + <b>Polyphony: </b> + True + + + GTK_FILL + + + + + + False + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + -6 + + + + + True + True + True + True + gtk-open + True + -5 + + + 1 + + + + + False + GTK_PACK_END + + + + + + + window1 + + + True + 4 + 2 + + + + + + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + 0 + 4 + 4 + <b>Name</b> + True + True + + + False + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 + 1 + 0 + 0 + 2 + 2 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + 0 -9.9999999999999999e+45 1.0000000000000001e+63 1 10 10 + 4 + + + + + 1 + + + + + False + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 -1e+113 1e+137 0 0 0 + 63 + False + + + False + 1 + + + + + 3 + 4 + + + + + True + + + 1 + 2 + GTK_FILL + + + + + True + + + True + + + True + GTK_TOOLBAR_BOTH_HORIZ + + + True + + + True + + + True + GTK_SHADOW_NONE + + + + + + + + + + False + False + + + + + True + + + True + + + + + + False + + + + + + + True + False + + + True + + + False + False + + + + + True + Enable DSP processing + True + gtk-execute + True + + + False + + + + + True + + + True + 4 + gtk-copy + + + + + False + False + + + + + True + + + True + True + 1 0 100 1 10 10 + 1 + + + + + False + False + + + + + True + + + False + False + + + + + True + Save patch to a file + gtk-save + + + False + + + + + True + + + False + False + + + + + True + Clear (Destroy all children) + True + gtk-clear + + + False + + + + + True + Destroy this patch + gtk-delete + + + False + + + + + True + + + False + False + + + + + True + Refresh view + gtk-refresh + + + False + + + + + True + Zoom to normal size + True + gtk-zoom-100 + + + False + + + + + True + Fit patch to window + True + gtk-zoom-fit + + + False + + + + + False + 1 + + + + + False + False + + + + + True + True + 1 + GTK_SHADOW_IN + + + + + + 1 + + + + + 2 + 3 + GTK_FILL + + + + + True + + + True + 0 + + + True + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + + + True + GTK_SHADOW_NONE + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + + + + + + True + True + + + True + Apply changed controls to all voices + All Voices + True + True + + + False + False + + + + + True + 5 + + + True + True + Apply changed controls to one voice only + Specific Voice: + True + True + control_panel_all_voices_radio + + + False + False + + + + + True + False + True + Voice control changes are applied to + 1 1 100 1 10 10 + 1 + True + + + 1 + + + + + False + False + 1 + + + + + False + 5 + 1 + + + + + + + + + 400 + 180 + 8 + Messages - Ingenuity + ingen.svg + + + True + 6 + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + Error messages from the engine since the last time "Clear" was pressed + 5 + 5 + False + GTK_WRAP_WORD + 5 + 5 + False + False + + + + + + + True + 6 + GTK_BUTTONBOX_END + + + True + False + True + True + gtk-clear + True + + + + + True + True + gtk-close + True + + + 1 + + + + + False + 1 + + + + + + + 8 + Configuration - Ingenuity + ingen.svg + + + True + 6 + + + True + 2 + 2 + + + True + 0 + + + 1 + 2 + GTK_FILL + + + + + + True + <i>Example: /foo/bar:/home/john/patches:/usr/share/om/patches</i> + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + True + * + + + 1 + 2 + + + + + + True + <b>Patch Search Path: </b> + True + + + GTK_FILL + + + + + + False + + + + + True + 6 + GTK_BUTTONBOX_END + + + True + True + Save these settings for future sessions + gtk-save + True + + + + + True + True + gtk-cancel + True + + + 1 + + + + + True + True + Apply these settings to this session only + gtk-ok + True + + + 2 + + + + + False + 1 + + + + + + + 400 + 200 + 8 + Patch Description + GTK_WIN_POS_CENTER_ON_PARENT + ingen.svg + + + True + 6 + + + True + 5 + + + True + Author: + + + False + False + + + + + True + True + * + + + 1 + + + + + False + False + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + A short description of the patch to be included in the patch file + GTK_WRAP_WORD + + + + + 1 + + + + + True + 5 + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + + + + + True + True + True + Apply these changes to be saved the next time the patch is saved + gtk-ok + True + + + 1 + + + + + False + False + 2 + + + + + + + 250 + Rename + GTK_WIN_POS_CENTER_ON_PARENT + ingen.svg + + + True + 5 + + + True + + + True + New name: + + + False + False + + + + + True + True + * + True + + + 1 + + + + + + + True + True + + + False + 6 + 1 + + + + + True + 5 + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + + + + + True + True + True + True + + + True + 0 + 0 + + + True + 2 + + + True + gtk-ok + + + False + False + + + + + True + Rename + True + + + False + False + 1 + + + + + + + + + 1 + + + + + False + 2 + + + + + + + 6 + Node Properties - Ingenuity + ingen.svg + + + True + + + True + 0 + <b>Node</b> + True + + + False + False + + + + + True + 12 + 6 + + + True + 4 + + + True + Path: + + + False + False + + + + + True + - + + + False + False + 1 + + + + + False + False + + + + + True + False + True + Polyphonic + True + True + + + False + False + 1 + + + + + 6 + 1 + + + + + 240 + True + 0 + <b>Plugin</b> + True + + + False + False + 2 + + + + + True + 12 + 3 + 2 + 10 + 6 + + + True + 0 + - + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + 0 + Name: + + + 2 + 3 + GTK_FILL + + + + + + True + 0 + - + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + 0 + URI: + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + Type: + + + GTK_FILL + + + + + + True + 0 + - + + + 1 + 2 + GTK_FILL + + + + + + 3 + + + + + + + True + GDK_WINDOW_TYPE_HINT_NORMAL + Ingenuity + Copyright (C) 2005-2007 Dave Robillard <http://drobilla.net> + A graphical client for the Ingen audio system + http://drobilla.net/software/ingen + Licensed under the GNU GPL, Version 2. + +See COPYING file included with this distribution, or http://www.gnu.org/licenses/gpl.txt for more information + Author: + Dave Robillard <dave@drobilla.net> + +Contributors: + Lars Luthman - DSSI enhancements, bugfixes + Mario Lang - SuperCollider bindings, bugfixes + Leonard Ritter - Python bindings + + translator-credits + Usability / UI Design: + Thorsten Wilms + ingen.svg + True + + + + + + + False + GTK_PACK_END + + + + + + + 320 + 340 + 8 + Patches - Ingenuity + ingen.svg + + + True + True + 3 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + All patches loaded in the engine + True + + + + + + + 6 + Engine - Ingenuity + False + ingen.svg + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + 6 + + + True + + + True + + + True + 12 + gtk-disconnect + 3 + + + False + + + + + True + 5 + True + + + True + 0.10000000149 + + + + False + False + + + + + True + 0 + Not Connected + + + False + 1 + + + + + 1 + + + + + False + + + + + True + + + 4 + 1 + + + + + True + 3 + 2 + 8 + + + True + 0 + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + False + True + Use internal engine + True + True + connect_server_radiobutton + + + 2 + 3 + GTK_FILL + + + + + + True + True + Launch and connect to server on port: + True + True + connect_server_radiobutton + + + 1 + 2 + GTK_FILL + + + + + + True + True + Connect to running server at: + True + True + + + GTK_FILL + + + + + + True + + + True + True + * + True + 28 + osc.udp://localhost:16180 + + + + + 1 + 2 + GTK_FILL + GTK_FILL + 8 + + + + + True + + + True + False + True + 16180 1 65535 1 10 10 + 1 + True + + + False + False + + + + + 1 + 2 + 1 + 2 + GTK_FILL + 8 + + + + + 2 + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-quit + True + + + + + True + False + True + True + gtk-disconnect + True + -6 + + + 1 + + + + + True + True + True + True + gtk-connect + True + -6 + + + 2 + + + + + False + False + GTK_PACK_END + + + + + + + True + + + True + Input + True + + + + + True + Add an audio input to this patch + Audio + True + + + + + + True + Add a control input (and a control slider for it) to this patch + Control + True + + + + + + True + Add a MIDI input to this patch + MIDI + True + + + + + + + + True + gtk-connect + 1 + + + + + + + True + Output + True + + + + + True + Add an audio output to this patch + Audio + True + + + + + + True + Add a control output to this patch + Control + True + + + + + + True + Add a MIDI output to this patch + MIDI + True + + + + + + + + True + gtk-connect + 1 + + + + + + + True + Load a plugin as a child of this patch + _Plugin... + True + + + + True + gtk-execute + 1 + + + + + + + True + Load a patch as a child of this patch + _Load Patch... + True + + + + True + gtk-open + 1 + + + + + + + True + Create a new (empty) patch as a child of this patch + _New Patch... + True + + + + True + gtk-new + 1 + + + + + + + 8 + Load Remote Patch + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + 8 + + + True + 8 + + + True + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + + + + + + + True + + + True + URI: + + + False + False + + + + + True + True + * + 78 + + + 1 + + + + + False + 1 + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + -6 + + + + + True + False + True + True + True + gtk-open + True + -5 + + + 1 + + + + + False + GTK_PACK_END + + + + + + + 8 + Upload Patch + False + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + 9 + + + True + 2 + 2 + 8 + + + True + 0 + Short Name: + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + Symbol: + + + GTK_FILL + + + + + + True + True + Enter a short name for this patch, e.g. "Mega Synth" + * + True + + + 1 + 2 + 1 + 2 + + + + + + True + True + Enter a short name suitable for use as an identifier or filename. + +The first character must be one of _, a-z or A-Z and subsequenct characters can be from _, a-z, A-Z or 0-9. + + * + True + + + 1 + 2 + + + + + + 2 + + + + + True + 4 + Succesfully uploaded patches will be available immediately in the remote patch browser. + +By uploading patches, you agree to license them under the Creative Commons Attribution-Share Alike 3.0 License. + +Thank you for contributing. + True + + + False + False + 3 + + + + + True + Upload progress + 0.10000000149 + + + False + False + 4 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-close + True + -7 + + + + + True + False + True + True + True + -5 + + + True + 0 + 0 + + + True + 2 + + + True + gtk-ok + + + False + False + + + + + True + Upload + True + + + False + False + 1 + + + + + + + + + 1 + + + + + False + GTK_PACK_END + + + + + + + + + True + _Properties... + True + + + + True + gtk-properties + 1 + + + + + + + 8 + GTK_WINDOW_POPUP + Port Properties - Ingenuity + False + GTK_WIN_POS_MOUSE + True + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + 8 + + + True + 2 + 2 + 2 + 4 + + + True + 0 + Maximum Value: + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + Minimum Value: + + + GTK_FILL + + + + + + True + True + 1 -99999 99999 1 10 10 + 1 + 5 + True + + + 1 + 2 + 1 + 2 + + + + + + True + True + 0 -100000000 100000000 1 10 10 + 1 + 5 + True + + + 1 + 2 + + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + -6 + + + + + True + True + True + True + gtk-ok + True + -5 + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/src/libs/gui/ingen_gui.gladep b/src/libs/gui/ingen_gui.gladep new file mode 100644 index 00000000..7cd9c6ce --- /dev/null +++ b/src/libs/gui/ingen_gui.gladep @@ -0,0 +1,9 @@ + + + + + Ingenuity + ingenuity + C++ + FALSE + diff --git a/src/libs/module/Module.cpp b/src/libs/module/Module.cpp index d92ee97a..073e612d 100644 --- a/src/libs/module/Module.cpp +++ b/src/libs/module/Module.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #ifndef INGEN_MODULE_DIR @@ -43,7 +44,7 @@ namespace Shared { SharedPtr load_module(const string& name) { - SharedPtr module; + Glib::Module* module = NULL; // Search INGEN_MODULE_PATH first bool module_path_found; @@ -52,24 +53,30 @@ load_module(const string& name) string dir; istringstream iss(module_path); while (getline(iss, dir, ':')) { - module = SharedPtr(new Glib::Module( - Glib::Module::build_path(dir, name), - Glib::MODULE_BIND_LAZY)); + + string filename = Glib::Module::build_path(dir, name); + if (Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { + module = new Glib::Module(filename, Glib::MODULE_BIND_LAZY); - if (module && *module.get()) - return module; + if (*module) { + return SharedPtr(module); + } else { + delete module; + cerr << Glib::Module::get_last_error() << endl; + } + } } } // Try default directory if not found - module = SharedPtr(new Glib::Module( + module = new Glib::Module( Glib::Module::build_path(INGEN_MODULE_DIR, name), - Glib::MODULE_BIND_LAZY)); + Glib::MODULE_BIND_LAZY); - if (*module.get()) { - return module; + if (*module) { + return SharedPtr(module); } else { - cerr << "Unable to load module \"" << name << "\" (you may want to set INGEN_MODULE_PATH)." << endl; + cerr << "Unable to load module \"" << name << "\" (try setting INGEN_MODULE_PATH)." << endl; return SharedPtr(); } } diff --git a/src/progs/Makefile.am b/src/progs/Makefile.am index aa28c47d..f2e1e8ef 100644 --- a/src/progs/Makefile.am +++ b/src/progs/Makefile.am @@ -1,15 +1,15 @@ AM_CXXFLAGS = -I$(top_srcdir)/src/common -DIST_SUBDIRS = python supercollider patch_loader ingenuity server demolition +DIST_SUBDIRS = python supercollider demolition -SUBDIRS = server +SUBDIRS = ingen if BUILD_CONSOLE_CLIENTS SUBDIRS += patch_loader # demolition endif -if BUILD_GTK_CLIENT -SUBDIRS += ingenuity -endif +#if BUILD_GTK_CLIENT +#SUBDIRS += ingenuity +#endif diff --git a/src/progs/ingen/Makefile.am b/src/progs/ingen/Makefile.am new file mode 100644 index 00000000..9915cae5 --- /dev/null +++ b/src/progs/ingen/Makefile.am @@ -0,0 +1,16 @@ +AM_CXXFLAGS = @RAUL_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs -DINGEN_MODULE_DIR=\"$(libdir)/ingen\" + +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = ingen_dev + +desktopfilesdir = $(datadir)/applications +dist_desktopfiles_DATA = ingen.desktop + +bin_PROGRAMS = ingen +ingen_LDADD = @RAUL_LIBS@ ../../libs/module/libingen_module.la +ingen_DEPENDENCIES = ../../libs/module/libingen_module.la + +ingen_SOURCES = \ + main.cpp \ + cmdline.h \ + cmdline.c diff --git a/src/progs/ingen/cmdline.ggo b/src/progs/ingen/cmdline.ggo new file mode 100644 index 00000000..45eae5b0 --- /dev/null +++ b/src/progs/ingen/cmdline.ggo @@ -0,0 +1,19 @@ +# Process this file with gengetopt to generate the necessary code (in cmdline.h, cmdline.c) + +package "ingen" +purpose "A modular realtime audio processing system" + +description "This executable can be used to launch any configuration of Ingen. +Ingen can run as a stand-alone server controlled by OSC, or internal to +another process. The GUI can communicate with the engine via either method, +and many GUIs (or other things) may connect to an engine via OSC. +" + +option "engine" e "Run (JACK) engine" flag off +option "engine-port" E "Engine OSC port" int no default="16180" +option "connect" c "Connect to existing engine at OSC URI" string no default="osc.udp://localhost:16180" +option "gui" g "Launch the GTK graphical interface" flag on +option "client-port" C "Client OSC port" int no +option "load" l "Load patch" string no +option "path" p "Target path for loaded patch" string no + diff --git a/src/progs/ingen/ingen.desktop.in b/src/progs/ingen/ingen.desktop.in new file mode 100644 index 00000000..63f07b67 --- /dev/null +++ b/src/progs/ingen/ingen.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Ingen +Version=@PACKAGE_VERSION@ +Comment=Create synthesizers and effects processors in a modular environment +Exec=ingen -g +Terminal=false +Icon=ingen-icon.svg +Type=Application +Categories=Application;AudioVideo;Sound;Audio diff --git a/src/progs/ingen/ingen_dev b/src/progs/ingen/ingen_dev new file mode 100755 index 00000000..bd8857f7 --- /dev/null +++ b/src/progs/ingen/ingen_dev @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +INGEN_MODULE_PATH=../../libs/engine/.libs ./ingen diff --git a/src/progs/ingen/main.cpp b/src/progs/ingen/main.cpp new file mode 100644 index 00000000..1ca1311a --- /dev/null +++ b/src/progs/ingen/main.cpp @@ -0,0 +1,194 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "module/Module.h" +#include "engine/Engine.h" +#include "engine/QueuedEngineInterface.h" +#include "serialisation/Loader.h" +#include "cmdline.h" + +using namespace std; +using namespace Ingen; + +SharedPtr engine; + + +void +catch_int(int) +{ + signal(SIGINT, catch_int); + signal(SIGTERM, catch_int); + + cout << "[Main] Ingen interrupted." << endl; + engine->quit(); +} + + +int +main(int argc, char** argv) +{ + /* Parse command line options */ + gengetopt_args_info args; + if (cmdline_parser (argc, argv, &args) != 0) + return 1; + + if (argc <= 1) { + cout << "No arguments provided. Try something like:" << endl << endl; + cout << "Run an engine: ingen -e" << endl; + cout << "Run the GUI: ingen -g" << endl; + cout << "Pring full help: ingen -h" << endl << endl; + cmdline_parser_print_help(); + return 0; + } + + SharedPtr engine_module; + SharedPtr gui_module; + + SharedPtr engine_interface; + + /* Run engine */ + if (args.engine_flag) { + + engine_module = Ingen::Shared::load_module("ingen_engine"); + + if (engine_module) { + /*if (args.engine_port_given) { + bool (*launch_engine)(int) = NULL; + if ( ! module->get_symbol("launch_osc_engine", (void*&)launch_engine)) + module.reset(); + else + launch_engine(args.engine_port_arg); + + } else if (args.gui_given || args.load_given) {*/ + Engine* (*new_engine)() = NULL; + if (engine_module->get_symbol("new_engine", (void*&)new_engine)) { + engine = SharedPtr(new_engine()); + engine->start_jack_driver(); + //engine->launch_osc_interface(args.engine_port_arg); + } else { + engine_module.reset(); + } + engine_interface = engine->new_queued_interface(); + /*} else { + cerr << "Nonsense command line parameters, engine not loaded." << endl; + }*/ + } else { + cerr << "Unable to load engine module, engine not loaded." << endl; + cerr << "Try running ingen_dev or setting INGEN_MODULE_PATH." << endl; + } + + } + + + /* Connect to remote engine */ + if (args.connect_given || (args.load_given && !engine_interface)) { + bool found = false; + SharedPtr client_module + = Ingen::Shared::load_module("ingen_client"); + + SharedPtr (*new_osc_interface)(const std::string&) = NULL; + + if (client_module) + found = client_module->get_symbol("new_osc_interface", (void*&)new_osc_interface); + + if (client_module && found) { + engine_interface = new_osc_interface(args.connect_arg); + } else { + cerr << "Unable to load ingen_client module, aborting." << endl; + return -1; + } + } + + + /* Load a patch */ + if (args.load_given) { + + Raul::RDF::World rdf_world; + rdf_world.add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#"); + rdf_world.add_prefix("ingen", "http://drobilla.net/ns/ingen#"); + rdf_world.add_prefix("ingenuity", "http://drobilla.net/ns/ingenuity#"); + rdf_world.add_prefix("lv2", "http://lv2plug.in/ontology#"); + rdf_world.add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); + rdf_world.add_prefix("doap", "http://usefulinc.com/ns/doap#"); + + boost::optional parent_path; + if (args.path_given) + parent_path = args.path_arg; + + bool found = false; + SharedPtr serialisation_module + = Ingen::Shared::load_module("ingen_serialisation"); + + Serialisation::Loader* (*new_loader)() = NULL; + + if (serialisation_module) + found = serialisation_module->get_symbol("new_loader", (void*&)new_loader); + + if (serialisation_module && found) { + SharedPtr loader(new_loader()); + loader->load(engine_interface, &rdf_world, + string("file:") + args.load_arg, parent_path, ""); + } else { + cerr << "Unable to load serialisation module, aborting." << endl; + return -1; + } + } + + + /* Run GUI */ + bool ran_gui = false; + if (args.gui_given) { + gui_module = Ingen::Shared::load_module("ingen_gui"); + void (*run)(int, char**) = NULL; + bool found = gui_module->get_symbol("run", (void*&)run); + + if (found) { + ran_gui = true; + run(argc, argv); + } else { + cerr << "Unable to find GUI module, GUI not loaded." << endl; + cerr << "Try running ingen_dev or setting INGEN_MODULE_PATH." << endl; + } + } + + + /* Didn't run the GUI, do our own main thing. */ + if (engine && !ran_gui) { + + signal(SIGINT, catch_int); + signal(SIGTERM, catch_int); + + engine->start_jack_driver(); + engine->start_osc_driver(args.engine_port_arg); + + engine->activate(); + + engine->main(); + + engine.reset(); + } + + return 0; +} + diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp deleted file mode 100644 index 20b61da6..00000000 --- a/src/progs/ingenuity/App.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "App.h" -#include -#include -#include -#include -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/ObjectModel.h" -#include "client/PatchModel.h" -#include "client/Store.h" -#include "NodeModule.h" -#include "ControlPanel.h" -#include "SubpatchModule.h" -#include "LoadPluginWindow.h" -#include "PatchWindow.h" -#include "MessagesWindow.h" -#include "ConfigWindow.h" -#include "GladeFactory.h" -#include "PatchTreeWindow.h" -#include "Configuration.h" -#include "ConnectWindow.h" -#include "ThreadedLoader.h" -#include "WindowFactory.h" -#ifdef HAVE_LASH -#include "LashController.h" -#endif -using std::cerr; using std::cout; using std::endl; -using std::string; -namespace Ingen { namespace Client { class PluginModel; } } -using namespace Ingen::Client; - -namespace Ingenuity { - -class Port; - - -/// Singleton instance -App* App::_instance = 0; - - -App::App() -: _configuration(new Configuration()), - _about_dialog(NULL), - _window_factory(new WindowFactory()), - _enable_signal(true) -{ - Glib::RefPtr glade_xml = GladeFactory::new_glade_reference(); - - glade_xml->get_widget_derived("connect_win", _connect_window); - glade_xml->get_widget_derived("messages_win", _messages_window); - glade_xml->get_widget_derived("patch_tree_win", _patch_tree_window); - glade_xml->get_widget_derived("config_win", _config_window); - glade_xml->get_widget("about_win", _about_dialog); - - _rdf_world.add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#"); - _rdf_world.add_prefix("ingen", "http://drobilla.net/ns/ingen#"); - _rdf_world.add_prefix("ingenuity", "http://drobilla.net/ns/ingenuity#"); - _rdf_world.add_prefix("lv2", "http://lv2plug.in/ontology#"); - _rdf_world.add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); - _rdf_world.add_prefix("doap", "http://usefulinc.com/ns/doap#"); - - _config_window->configuration(_configuration); - -#ifdef HAVE_SLV2 - SLV2World slv2_world = slv2_world_new_using_rdf_world(_rdf_world.world()); - PluginModel::set_slv2_world(slv2_world); -#endif -} - - -App::~App() -{ -} - - -void -App::instantiate() -{ - if (!_instance) - _instance = new App(); -} - - -void -App::attach(const SharedPtr& engine, const SharedPtr& client) -{ - assert( ! _engine); - assert( ! _client); - assert( ! _store); - assert( ! _loader); - - _engine = engine; - _client = client; - _store = SharedPtr(new Store(engine, client)); - _loader = SharedPtr(new ThreadedLoader(engine)); - - _patch_tree_window->init(*_store); -} - - -void -App::detach() -{ - if (_engine) { - _window_factory->clear(); - _store->clear(); - - _loader.reset(); - _store.reset(); - _client.reset(); - _engine.reset(); - } -} - - -void -App::error_message(const string& str) -{ - _messages_window->post(str); - _messages_window->show(); - _messages_window->raise(); -} - - -/* -bool -App::idle_callback() -{ - _client_hooks->process_events(); - -#ifdef HAVE_LASH - //if (lash_controller->enabled()) - // lash_controller->process_events(); -#endif - - return true; -} -*/ - - -/******** Event Handlers ************/ - - -#if 0 -App::event_load_session() -{ - Gtk::FileChooserDialog* dialog - = new Gtk::FileChooserDialog(*_main_window, "Load Session", Gtk::FILE_CHOOSER_ACTION_OPEN); - - dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - int result = dialog->run(); - string filename = dialog->get_filename(); - delete dialog; - - cout << result << endl; - - assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); - - if (result == Gtk::RESPONSE_OK) - //configuration->load_session(filename); - _controller->load_session(filename); -} - - -void -App::event_save_session_as() -{ - Gtk::FileChooserDialog dialog(*_main_window, "Save Session", Gtk::FILE_CHOOSER_ACTION_SAVE); - - /* - Gtk::VBox* box = dialog.get_vbox(); - Gtk::Label warning("Warning: Recursively saving will overwrite any subpatch files \ - without confirmation."); - box->pack_start(warning, false, false, 2); - Gtk::CheckButton recursive_checkbutton("Recursively save all subpatches"); - box->pack_start(recursive_checkbutton, false, false, 0); - recursive_checkbutton.show(); - */ - dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); - - int result = dialog.run(); - //bool recursive = recursive_checkbutton.get_active(); - - assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); - - if (result == Gtk::RESPONSE_OK) { - string filename = dialog.get_filename(); - if (filename.length() < 11 || filename.substr(filename.length()-10) != ".omsession") - filename += ".omsession"; - - bool confirm = false; - std::fstream fin; - fin.open(filename.c_str(), std::ios::in); - if (fin.is_open()) { // File exists - string msg = "File already exists! Are you sure you want to overwrite "; - msg += filename + "?"; - Gtk::MessageDialog confir_dialog(*_main_window, - msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); - if (confir_dialog.run() == Gtk::RESPONSE_YES) - confirm = true; - else - confirm = false; - } else { // File doesn't exist - confirm = true; - } - fin.close(); - - if (confirm) { - _controller->save_session(filename); - } - } -} -#endif - - -void -App::quit() -{ - Gtk::Main::quit(); -} - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h deleted file mode 100644 index 2ef0891d..00000000 --- a/src/progs/ingenuity/App.h +++ /dev/null @@ -1,137 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef APP_H -#define APP_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using std::string; using std::map; using std::list; -using std::cerr; using std::endl; - -namespace Ingen { - namespace Shared { - class EngineInterface; - } - namespace Client { - class PatchModel; - class PluginModel; - class Store; - class SigClientInterface; - } -} -using namespace Ingen::Client; -using Ingen::Shared::EngineInterface; - -/** \defgroup Ingenuity GTK Client - */ - -/** GTK Graphical client */ -namespace Ingenuity { - -class MessagesWindow; -class ConfigWindow; -class IngenuityObject; -class PatchCanvas; -class PatchTreeView; -class PatchTreeWindow; -class ConnectWindow; -class Configuration; -class ThreadedLoader; -class WindowFactory; - - -/** Singleton master class most everything is contained within. - * - * This is a horrible god-object, but it's shrinking in size as things are - * moved out. Hopefully it will go away entirely some day.. - * - * \ingroup Ingenuity - */ -class App -{ -public: - ~App(); - - void error_message(const string& msg); - - void attach(const SharedPtr& engine, - const SharedPtr& client); - - void detach(); - - void quit(); - - ConnectWindow* connect_window() const { return _connect_window; } - Gtk::Dialog* about_dialog() const { return _about_dialog; } - ConfigWindow* configuration_dialog() const { return _config_window; } - MessagesWindow* messages_dialog() const { return _messages_window; } - PatchTreeWindow* patch_tree() const { return _patch_tree_window; } - Configuration* configuration() const { return _configuration; } - WindowFactory* window_factory() const { return _window_factory; } - - Raul::RDF::World* rdf_world() { return &_rdf_world; } - - const SharedPtr& engine() const { return _engine; } - const SharedPtr& client() const { return _client; } - const SharedPtr& store() const { return _store; } - const SharedPtr& loader() const { return _loader; } - - static inline App& instance() { assert(_instance); return *_instance; } - static void instantiate(); - -protected: - App(); - static App* _instance; - - SharedPtr _engine; - SharedPtr _client; - SharedPtr _store; - SharedPtr _loader; - - Configuration* _configuration; - - ConnectWindow* _connect_window; - MessagesWindow* _messages_window; - PatchTreeWindow* _patch_tree_window; - ConfigWindow* _config_window; - Gtk::Dialog* _about_dialog; - WindowFactory* _window_factory; - - Raul::RDF::World _rdf_world; - - /** Used to avoid feedback loops with (eg) process checkbutton - * FIXME: Maybe this should be globally implemented at the Controller level, - * disable all command sending while handling events to avoid feedback - * issues with widget event callbacks? This same pattern is duplicated - * too much... */ - bool _enable_signal; -}; - - -} // namespace Ingenuity - -#endif // APP_H - diff --git a/src/progs/ingenuity/BreadCrumb.h b/src/progs/ingenuity/BreadCrumb.h deleted file mode 100644 index 1e8b4c9b..00000000 --- a/src/progs/ingenuity/BreadCrumb.h +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef BREADCRUMB_H -#define BREADCRUMB_H - -#include -#include -#include -#include "PatchView.h" - -namespace Ingenuity { - - -/** Breadcrumb button in a PatchWindow. - * - * Each Breadcrumb stores a reference to a PatchView for quick switching. - * So, the amount of allocated PatchViews at a given time is equal to the - * number of visible breadcrumbs (which is the perfect cache for GUI - * responsiveness balanced with mem consumption). - * - * \ingroup Ingenuity - */ -class BreadCrumb : public Gtk::ToggleButton -{ -public: - BreadCrumb(const Path& path, SharedPtr view = SharedPtr()) - : _path(path) - , _view(view) - { - assert( !view || view->patch()->path() == path); - set_border_width(0); - set_path(path); - show_all(); - } - - void set_view(SharedPtr view) { - assert( !view || view->patch()->path() == _path); - _view = view; - } - - const Path& path() const { return _path; } - SharedPtr view() const { return _view; } - - void set_path(const Path& path) - { - remove(); - const string text = (path == "/") ? "/" : path.name(); - Gtk::Label* lab = manage(new Gtk::Label(text)); - lab->set_padding(0, 0); - lab->show(); - add(*lab); - - if (_view && _view->patch()->path() != path) - _view.reset(); - } - -private: - Path _path; - SharedPtr _view; -}; - -} // namespace Ingenuity - -#endif // BREADCRUMB_H diff --git a/src/progs/ingenuity/BreadCrumbBox.cpp b/src/progs/ingenuity/BreadCrumbBox.cpp deleted file mode 100644 index a82a4325..00000000 --- a/src/progs/ingenuity/BreadCrumbBox.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "BreadCrumbBox.h" -#include "BreadCrumb.h" -namespace Ingenuity { - - -BreadCrumbBox::BreadCrumbBox() -: Gtk::HBox() -, _active_path("/") -, _full_path("/") -, _enable_signal(true) -{ -} - - -SharedPtr -BreadCrumbBox::view(const Path& path) -{ - for (std::list::const_iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - if ((*i)->path() == path) - return (*i)->view(); - - return SharedPtr(); -} - - -/** Sets up the crumbs to display @a path. - * - * If @a path is already part of the shown path, it will be selected and the - * children preserved. - */ -void -BreadCrumbBox::build(Path path, SharedPtr view) -{ - bool old_enable_signal = _enable_signal; - _enable_signal = false; - - // Moving to a path we already contain, just switch the active button - if (_breadcrumbs.size() > 0 && (path.is_parent_of(_full_path) || path == _full_path)) { - - for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == path) { - (*i)->set_active(true); - if (!(*i)->view()) - (*i)->set_view(view); - - // views are expensive, having two around for the same patch is a bug - assert((*i)->view() == view); - - } else { - (*i)->set_active(false); - } - } - - _active_path = path; - _enable_signal = old_enable_signal; - - - // Moving to a child of the full path, just append crumbs (preserve view cache) - } else if (_breadcrumbs.size() > 0 && (path.is_child_of(_full_path))) { - - string suffix = path.substr(_full_path.length()); - while (suffix.length() > 0) { - if (suffix[0] == '/') - suffix = suffix.substr(1); - const string name = suffix.substr(0, suffix.find("/")); - _full_path = _full_path.base() + name; - BreadCrumb* but = create_crumb(_full_path, view); - pack_start(*but, false, false, 1); - _breadcrumbs.push_back(but); - but->show(); - if (suffix.find("/") == string::npos) - break; - else - suffix = suffix.substr(suffix.find("/")+1); - } - - for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - (*i)->set_active(false); - _breadcrumbs.back()->set_active(true); - - - // Rebuild from scratch - // Getting here is bad unless absolutely necessary, since the PatchView cache is lost - } else { - - _full_path = path; - _active_path = path; - - // Empty existing breadcrumbs - for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - remove(**i); - _breadcrumbs.clear(); - - // Add root - BreadCrumb* root_but = create_crumb("/", view); - pack_start(*root_but, false, false, 1); - _breadcrumbs.push_front(root_but); - root_but->set_active(root_but->path() == _active_path); - - Path working_path = "/"; - string suffix = path.substr(1); - while (suffix.length() > 0) { - if (suffix[0] == '/') - suffix = suffix.substr(1); - const string name = suffix.substr(0, suffix.find("/")); - working_path = working_path.base() + name; - BreadCrumb* but = create_crumb(working_path, view); - pack_start(*but, false, false, 1); - _breadcrumbs.push_back(but); - but->set_active(working_path == _active_path); - but->show(); - if (suffix.find("/") == string::npos) - break; - else - suffix = suffix.substr(suffix.find("/")+1); - } - } - - _enable_signal = old_enable_signal; -} - - -/** Create a new crumb, assigning it a reference to @a view if their paths - * match, otherwise ignoring @a view. - */ -BreadCrumb* -BreadCrumbBox::create_crumb(const Path& path, - SharedPtr view) -{ - BreadCrumb* but = manage(new BreadCrumb(path, - (view && path == view->patch()->path()) ? view : SharedPtr())); - - but->signal_toggled().connect(sigc::bind(sigc::mem_fun( - this, &BreadCrumbBox::breadcrumb_clicked), but)); - - return but; -} - - -void -BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb) -{ - if (_enable_signal) { - _enable_signal = false; - - if (!crumb->get_active()) { - // Tried to turn off the current active button, bad user, no cookie - crumb->set_active(true); - } else { - signal_patch_selected.emit(crumb->path(), crumb->view()); - if (crumb->path() != _active_path) - crumb->set_active(false); - } - _enable_signal = true; - } -} - - -void -BreadCrumbBox::object_removed(const Path& path) -{ - for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == path) { - // Remove all crumbs after the removed one (inclusive) - for (std::list::iterator j = i; j != _breadcrumbs.end(); ) { - BreadCrumb* bc = *j; - j = _breadcrumbs.erase(j); - remove(*bc); - } - break; - } - } -} - - -void -BreadCrumbBox::object_renamed(const Path& old_path, const Path& new_path) -{ - for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == old_path) - (*i)->set_path(new_path); - } -} - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/BreadCrumbBox.h b/src/progs/ingenuity/BreadCrumbBox.h deleted file mode 100644 index 952e04f1..00000000 --- a/src/progs/ingenuity/BreadCrumbBox.h +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef BREADCRUMBBOX_H -#define BREADCRUMBBOX_H - -#include -#include -#include -#include -#include -#include -#include "PatchView.h" - -namespace Ingenuity { - -class BreadCrumb; - - -/** Collection of breadcrumb buttons forming a path. - * - * This doubles as a cache for PatchViews. - * - * \ingroup Ingenuity - */ -class BreadCrumbBox : public Gtk::HBox -{ -public: - BreadCrumbBox(); - - SharedPtr view(const Path& path); - - void build(Path path, SharedPtr view); - - sigc::signal > signal_patch_selected; - -private: - BreadCrumb* create_crumb(const Path& path, - SharedPtr view = SharedPtr()); - - void breadcrumb_clicked(BreadCrumb* crumb); - - void object_removed(const Path& path); - void object_renamed(const Path& old_path, const Path& new_path); - - Path _active_path; - Path _full_path; - bool _enable_signal; - std::list _breadcrumbs; -}; - -} // namespace Ingenuity - -#endif // BREADCRUMBBOX_H diff --git a/src/progs/ingenuity/ConfigWindow.cpp b/src/progs/ingenuity/ConfigWindow.cpp deleted file mode 100644 index eef81ce3..00000000 --- a/src/progs/ingenuity/ConfigWindow.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include "client/NodeModel.h" -#include "ConfigWindow.h" - -using namespace std; - -namespace Ingenuity { - - -ConfigWindow::ConfigWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::Window(cobject), - _configuration(NULL) -{ - xml->get_widget("config_path_entry", _path_entry); - xml->get_widget("config_save_button", _save_button); - xml->get_widget("config_cancel_button", _cancel_button); - xml->get_widget("config_ok_button", _ok_button); - - _save_button->signal_clicked().connect( sigc::mem_fun(this, &ConfigWindow::save_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &ConfigWindow::cancel_clicked)); - _ok_button->signal_clicked().connect( sigc::mem_fun(this, &ConfigWindow::ok_clicked)); -} - - -/** Sets the state manager for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -ConfigWindow::configuration(Configuration* sm) -{ - _configuration = sm; - _path_entry->set_text(sm->patch_path()); -} - - - -///// Event Handlers ////// - - -void -ConfigWindow::save_clicked() -{ - _configuration->patch_path(_path_entry->get_text()); - _configuration->apply_settings(); - _configuration->save_settings(); -} - - -void -ConfigWindow::cancel_clicked() -{ - hide(); -} - - -void -ConfigWindow::ok_clicked() -{ - _configuration->patch_path(_path_entry->get_text()); - _configuration->apply_settings(); - hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/ConfigWindow.h b/src/progs/ingenuity/ConfigWindow.h deleted file mode 100644 index 31e564bd..00000000 --- a/src/progs/ingenuity/ConfigWindow.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONFIGWINDOW_H -#define CONFIGWINDOW_H - -#include -#include -#include -#include -#include "client/PluginModel.h" -#include "Configuration.h" - -using std::list; -using Ingen::Client::PluginModel; - -namespace Ingenuity { - - -/** 'Configuration' window. - * - * Loaded by glade as a derived object. - * - * \ingroup Ingenuity - */ -class ConfigWindow : public Gtk::Window -{ -public: - ConfigWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void configuration(Configuration* sm); - -private: - void save_clicked(); - void cancel_clicked(); - void ok_clicked(); - - Configuration* _configuration; - - Gtk::Entry* _path_entry; - Gtk::Button* _save_button; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; -}; - - -} // namespace Ingenuity - -#endif // CONFIGWINDOW_H diff --git a/src/progs/ingenuity/Configuration.cpp b/src/progs/ingenuity/Configuration.cpp deleted file mode 100644 index d3d7f295..00000000 --- a/src/progs/ingenuity/Configuration.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "Configuration.h" -#include -#include -#include -#include -#include -#include "client/PortModel.h" -#include "client/PluginModel.h" -#include "client/PatchModel.h" -#include "serialisation/Loader.h" -#include "App.h" - -using std::cerr; using std::cout; using std::endl; -using std::map; using std::string; -using Ingen::Client::PatchModel; - -namespace Ingenuity { - -using namespace Ingen::Client; - - -Configuration::Configuration() -: _patch_path("/usr/share/ingen/patches:/usr/local/share/ingen/patches"), - _audio_port_color( 0x394f66B0), - _control_port_color(0x396639B0), - _midi_port_color( 0x663939B0) -{ -} - - -Configuration::~Configuration() -{ -} - - -/** Loads settings from the rc file. Passing no parameter will load from - * the default location. - */ -void -Configuration::load_settings(string filename) -{ - if (filename == "") - filename = string(getenv("HOME")).append("/.omgtkrc"); - - std::ifstream is; - is.open(filename.c_str(), std::ios::in); - - if ( ! is.good()) { - cout << "[Configuration] Unable to open settings file " << filename << endl; - return; - } else { - cout << "[Configuration] Loading settings from " << filename << endl; - } - - string s; - - is >> s; - if (s != "file_version") { - cerr << "[Configuration] Corrupt settings file, load aborted." << endl; - is.close(); - return; - } - - is >> s; - if (s != "1") { - cerr << "[Configuration] Unknown settings file version number, load aborted." << endl; - is.close(); - return; - } - - is >> s; - if (s != "patch_path") { - cerr << "[Configuration] Corrupt settings file, load aborted." << endl; - is.close(); - return; - } - - is >> s; - _patch_path = s; - - is.close(); -} - - -/** Saves settings to rc file. Passing no parameter will save to the - * default location. - */ -void -Configuration::save_settings(string filename) -{ - if (filename == "") - filename = string(getenv("HOME")).append("/.omgtkrc"); - - std::ofstream os; - os.open(filename.c_str(), std::ios::out); - - if ( ! os.good()) { - cout << "[Configuration] Unable to write to setting file " << filename << endl; - return; - } else { - cout << "[Configuration] Saving settings to " << filename << endl; - } - - os << "file_version 1" << endl; - os << "patch_path " << _patch_path << endl; - - os.close(); -} - - -/** Applies the current loaded settings to whichever parts of the app - * need updating. - */ -void -Configuration::apply_settings() -{ - cerr << "FIXME: patch path" << endl; - //App::instance().loader()->set_patch_path(_patch_path); -} - - -int -Configuration::get_port_color(const PortModel* pi) -{ - assert(pi != NULL); - - if (pi->is_control()) { - return _control_port_color; - } else if (pi->is_audio()) { - return _audio_port_color; - } else if (pi->is_midi()) { - return _midi_port_color; - } - - cerr << "[Configuration] Unknown port type! Port will be bright red, this is an error." << endl; - return 0xFF0000B0; -} - -/* -Coord -Configuration::get_window_location(const string& id) -{ - return _window_locations[id]; -} - - -void -Configuration::set_window_location(const string& id, Coord loc) -{ - _window_locations[id] = loc; -} - - -Coord -Configuration::get_window_size(const string& id) -{ - return _window_sizes[id]; -} - - -void -Configuration::set_window_size(const string& id, Coord size) -{ - _window_sizes[id] = size; -}*/ - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/Configuration.h b/src/progs/ingenuity/Configuration.h deleted file mode 100644 index 786af3d3..00000000 --- a/src/progs/ingenuity/Configuration.h +++ /dev/null @@ -1,77 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONFIG_H -#define CONFIG_H - -#include - -namespace Ingen { namespace Client { class PortModel; } } -using Ingen::Client::PortModel; -using std::string; - -struct Coord { double x; double y; }; - -namespace Ingenuity { - -class Controller; - - -/** Singleton state manager for the entire app. - * - * Stores settings like color preferences, search paths, etc. - * (ie any user-defined preferences to be stoed in the rc file). - * - * \ingroup Ingenuity - */ -class Configuration -{ -public: - Configuration(); - ~Configuration(); - - void load_settings(string filename = ""); - void save_settings(string filename = ""); - - void apply_settings(); - - string patch_path() { return _patch_path; } - void patch_path(const string& path) { _patch_path = path; } - - const string& patch_folder() { return _patch_folder; } - void set_patch_folder(const string& f) { _patch_folder = f; } - - int get_port_color(const PortModel* pi); - -private: - /** Search path for patch files. Colon delimited, as usual. */ - string _patch_path; - - /** Most recent patch folder shown in open dialog */ - string _patch_folder; - - int _audio_port_color; - int _control_port_color; - int _midi_port_color; -}; - - -} // namespace Ingenuity - -#endif // CONFIG_H - - diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp deleted file mode 100644 index 322750ea..00000000 --- a/src/progs/ingenuity/ConnectWindow.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "interface/ClientKey.h" -#include "interface/EngineInterface.h" -#include "engine/tuning.h" -#include "engine/Engine.h" -#include "engine/DirectResponder.h" -#include "engine/QueuedEngineInterface.h" -#include "client/OSCClientReceiver.h" -#include "client/OSCEngineSender.h" -#include "client/ThreadedSigClientInterface.h" -#include "client/Store.h" -#include "client/PatchModel.h" -#include "module/Module.h" -#include "App.h" -#include "WindowFactory.h" -#include "ConnectWindow.h" -using Ingen::QueuedEngineInterface; -using Ingen::Client::ThreadedSigClientInterface; - -namespace Ingenuity { - - -// Paste together some interfaces to get the combination we want - - -struct OSCSigEmitter : public OSCClientReceiver, public ThreadedSigClientInterface { - OSCSigEmitter(size_t queue_size, int listen_port) - : Ingen::Shared::ClientInterface() - , OSCClientReceiver(listen_port) - , ThreadedSigClientInterface(queue_size) - { - } -}; - - -// ConnectWindow - - -ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) - : Gtk::Dialog(cobject) - , _mode(CONNECT_REMOTE) - , _ping_id(-1) - , _attached(false) - , _connect_stage(0) - , _new_engine(NULL) - , _new_queued_engine_interface(NULL) -{ - xml->get_widget("connect_icon", _icon); - xml->get_widget("connect_progress_bar", _progress_bar); - xml->get_widget("connect_progress_label", _progress_label); - xml->get_widget("connect_server_radiobutton", _server_radio); - xml->get_widget("connect_url_entry", _url_entry); - xml->get_widget("connect_launch_radiobutton", _launch_radio); - xml->get_widget("connect_port_spinbutton", _port_spinbutton); - xml->get_widget("connect_internal_radiobutton", _internal_radio); - xml->get_widget("connect_disconnect_button", _disconnect_button); - xml->get_widget("connect_connect_button", _connect_button); - xml->get_widget("connect_quit_button", _quit_button); - - _server_radio->signal_toggled().connect(sigc::mem_fun(this, &ConnectWindow::server_toggled)); - _launch_radio->signal_toggled().connect(sigc::mem_fun(this, &ConnectWindow::launch_toggled)); - _internal_radio->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::internal_toggled)); - _disconnect_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::disconnect)); - _connect_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::connect)); - _quit_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::quit)); - - _engine_module = Ingen::Shared::load_module("ingen_engine"); - - if (!_engine_module) { - cerr << "Unable to load ingen_engine module, internal engine unavailable." << endl; - cerr << "If you are running from the source tree, run ingenuity_dev." << endl; - } - - bool found1 = _engine_module->get_symbol("new_engine", (void*&)_new_engine); - bool found2 = _engine_module->get_symbol("new_queued_engine_interface", - (void*&)_new_queued_engine_interface); - - if (!found1 || !found2) { - cerr << "Unable to find module entry point, internal engine unavailable." << endl; - _engine_module.reset(); - } -} - - -void -ConnectWindow::start() -{ - resize(100, 100); - init(); - show(); - connect(); -} - - -void -ConnectWindow::init() -{ - _icon->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); - _progress_bar->set_fraction(0.0); - _url_entry->set_sensitive(true); - _connect_button->set_sensitive(true); - _disconnect_button->set_sensitive(false); - _port_spinbutton->set_sensitive(false); - _launch_radio->set_sensitive(true); - if (_new_engine) - _internal_radio->set_sensitive(true); - else - _internal_radio->set_sensitive(false); - server_toggled(); - - _progress_label->set_text(string("Disconnected")); -} - - -/** Launch (if applicable) and connect to the Engine. - * - * This will create the EngineInterface and ClientInterface and initialize - * the App with them. - */ -void -ConnectWindow::connect() -{ - assert(!_attached); - assert(!App::instance().engine()); - assert(!App::instance().client()); - - _connect_button->set_sensitive(false); - _disconnect_button->set_label("gtk-cancel"); - _disconnect_button->set_sensitive(true); - - _connect_stage = 0; - - if (_mode == CONNECT_REMOTE) { - SharedPtr engine( - new OSCEngineSender(_url_entry->get_text())); - - OSCSigEmitter* ose = new OSCSigEmitter(1024, 16181); // FIXME: args - SharedPtr client(ose); - App::instance().attach(engine, client); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); - - Glib::signal_timeout().connect( - sigc::mem_fun(ose, &ThreadedSigClientInterface::emit_signals), 2, G_PRIORITY_HIGH_IDLE); - - } else if (_mode == LAUNCH_REMOTE) { - - int port = _port_spinbutton->get_value_as_int(); - char port_str[6]; - snprintf(port_str, 6, "%u", port); - const string cmd = string("ingen --port=").append(port_str); - - if (Raul::Process::launch(cmd)) { - SharedPtr engine( - new OSCEngineSender(string("osc.udp://localhost:").append(port_str))); - - OSCSigEmitter* ose = new OSCSigEmitter(1024, 16181); // FIXME: args - SharedPtr client(ose); - App::instance().attach(engine, client); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); - - Glib::signal_timeout().connect( - sigc::mem_fun(ose, &ThreadedSigClientInterface::emit_signals), - 2, G_PRIORITY_HIGH_IDLE); - } else { - cerr << "Failed to launch ingen process." << endl; - } - - } else if (_mode == INTERNAL) { - assert(_new_engine); - SharedPtr engine(_new_engine()); - engine->start_jack_driver(); - - assert(_new_queued_engine_interface); - SharedPtr engine_interface(_new_queued_engine_interface(*engine.get())); - - ThreadedSigClientInterface* tsci = new ThreadedSigClientInterface(Ingen::event_queue_size); - SharedPtr client(tsci); - - App::instance().attach(engine_interface, client); - - engine_interface->set_responder(SharedPtr(new Ingen::DirectResponder(client, 1))); - - engine->set_event_source(engine_interface); - - engine->activate(); - - Glib::signal_timeout().connect( - sigc::mem_fun(engine.get(), &Ingen::Engine::main_iteration), 1000); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &ConnectWindow::gtk_callback), 100); - - Glib::signal_timeout().connect( - sigc::mem_fun(tsci, &ThreadedSigClientInterface::emit_signals), 2, G_PRIORITY_HIGH_IDLE); - } -} - - -void -ConnectWindow::disconnect() -{ - _connect_stage = -1; - _attached = false; - - _progress_bar->set_fraction(0.0); - _connect_button->set_sensitive(false); - _disconnect_button->set_sensitive(false); - - App::instance().detach(); - - init(); - - _connect_button->set_sensitive(true); - _disconnect_button->set_sensitive(false); -} - - -void -ConnectWindow::quit() -{ - if (_attached) { - Gtk::MessageDialog d(*this, "This will exit Ingenuity, but the engine will " - "remain running (if it is remote).\n\nAre you sure you want to quit?", - true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); - int ret = d.run(); - if (ret == Gtk::RESPONSE_CLOSE) - Gtk::Main::quit(); - } else { - Gtk::Main::quit(); - } -} - - -void -ConnectWindow::server_toggled() -{ - _url_entry->set_sensitive(true); - _port_spinbutton->set_sensitive(false); - _mode = CONNECT_REMOTE; -} - - -void -ConnectWindow::launch_toggled() -{ - _url_entry->set_sensitive(false); - _port_spinbutton->set_sensitive(true); - _mode = LAUNCH_REMOTE; -} - - -void -ConnectWindow::internal_toggled() -{ - _url_entry->set_sensitive(false); - _port_spinbutton->set_sensitive(false); - _mode = INTERNAL; -} - - -bool -ConnectWindow::gtk_callback() -{ - /* This isn't very nice (isn't threaded), but better than no dialog at - * all like before :) - */ - - // Timing stuff for repeated attach attempts - timeval now; - gettimeofday(&now, NULL); - static timeval last = now; - - /* Connecting to engine */ - if (_connect_stage == 0) { - - assert(!_attached); - assert(App::instance().engine()); - assert(App::instance().client()); - - // FIXME - //assert(!App::instance().engine()->is_attached()); - _progress_label->set_text("Connecting to engine..."); - present(); - - App::instance().client()->response_sig.connect(sigc::mem_fun(this, &ConnectWindow::response_received)); - - _ping_id = rand(); - while (_ping_id == -1) - _ping_id = rand(); - - App::instance().engine()->set_next_response_id(_ping_id); - App::instance().engine()->ping(); - ++_connect_stage; - - - } else if (_connect_stage == 1) { - if (_attached) { - App::instance().engine()->activate(); - ++_connect_stage; - } else { - const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + - (now.tv_usec - last.tv_usec) * 0.001f; - if (ms_since_last > 1000) { - App::instance().engine()->set_next_response_id(_ping_id); - App::instance().engine()->ping(); - last = now; - } - } - } else if (_connect_stage == 2) { - _progress_label->set_text(string("Registering as client...")); - //App::instance().engine()->register_client(App::instance().engine()->client_hooks()); - // FIXME - //auto_ptr client(new ThreadedSigClientInterface(); - App::instance().engine()->register_client(ClientKey(), App::instance().client()); - App::instance().engine()->load_plugins(); - ++_connect_stage; - } else if (_connect_stage == 3) { - // Register idle callback to process events and whatnot - // (Gtk refreshes at priority G_PRIORITY_HIGH_IDLE+20) - /*Glib::signal_timeout().connect( - sigc::mem_fun(this, &App::idle_callback), 100, G_PRIORITY_HIGH_IDLE);*/ - //Glib::signal_idle().connect(sigc::mem_fun(this, &App::idle_callback)); - /* Glib::signal_timeout().connect( - sigc::mem_fun((ThreadedSigClientInterface*)_client, &ThreadedSigClientInterface::emit_signals), - 5, G_PRIORITY_DEFAULT_IDLE);*/ - - _progress_label->set_text(string("Requesting plugins...")); - App::instance().engine()->request_plugins(); - ++_connect_stage; - } else if (_connect_stage == 4) { - // Wait for first plugins message - if (App::instance().store()->plugins().size() > 0) { - _progress_label->set_text(string("Receiving plugins...")); - ++_connect_stage; - } - } else if (_connect_stage == 5) { - // FIXME - /*if (App::instance().store().plugins().size() < _client->num_plugins()) { - static char buf[32]; - snprintf(buf, 32, "%zu/%zu", App::instance().store().plugins().size(), - ThreadedSigClientInterface::instance()->num_plugins()); - _progress_bar->set_text(Glib::ustring(buf)); - _progress_bar->set_fraction( - App::instance().store().plugins().size() / (double)_client->num_plugins()); - } else {*/ - _progress_bar->set_text(""); - ++_connect_stage; - //} - } else if (_connect_stage == 6) { - _progress_label->set_text(string("Waiting for root patch...")); - App::instance().engine()->request_all_objects(); - ++_connect_stage; - } else if (_connect_stage == 7) { - if (App::instance().store()->objects().size() > 0) { - SharedPtr root = PtrCast(App::instance().store()->object("/")); - assert(root); - App::instance().window_factory()->present_patch(root); - ++_connect_stage; - } - } else if (_connect_stage == 8) { - _progress_label->set_text("Connected to engine"); - ++_connect_stage; - } else if (_connect_stage == 9) { - ++_connect_stage; - hide(); - } else if (_connect_stage == 10) { - _icon->set(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); - _progress_bar->set_fraction(1.0); - _url_entry->set_sensitive(false); - _connect_button->set_sensitive(false); - _disconnect_button->set_label("gtk-disconnect"); - _disconnect_button->set_sensitive(true); - _port_spinbutton->set_sensitive(false); - _launch_radio->set_sensitive(false); - _internal_radio->set_sensitive(false); - _connect_stage = 0; // set ourselves up for next time (if there is one) - return false; // deregister this callback - } - - if (_connect_stage != 5) // yeah, ew - _progress_bar->pulse(); - - if (_connect_stage == -1) { // we were cancelled - _icon->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); - _progress_bar->set_fraction(0.0); - _connect_button->set_sensitive(true); - _disconnect_button->set_sensitive(false); - _disconnect_button->set_label("gtk-disconnect"); - _progress_label->set_text(string("Disconnected")); - return false; - } else { - return true; - } -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/ConnectWindow.h b/src/progs/ingenuity/ConnectWindow.h deleted file mode 100644 index fb1a012f..00000000 --- a/src/progs/ingenuity/ConnectWindow.h +++ /dev/null @@ -1,91 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONNECT_WINDOW_H -#define CONNECT_WINDOW_H - -#include -#include -#include -#include -#include "client/ThreadedSigClientInterface.h" -using Ingen::Client::SigClientInterface; - -namespace Ingen { class Engine; class QueuedEngineInterface; } - -namespace Ingenuity { - -class App; -class Controller; - - -/** The initially visible "Connect to engine" window. - * - * This handles actually connecting to the engine and making sure everything - * is ready before really launching the app (eg wait for the root patch). - * - * \ingroup Ingenuity - */ -class ConnectWindow : public Gtk::Dialog -{ -public: - ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void start(); - void response_received(int32_t id, bool, string) { if ((id) == _ping_id) _attached = true; } - -private: - enum Mode { CONNECT_REMOTE, LAUNCH_REMOTE, INTERNAL }; - - void server_toggled(); - void launch_toggled(); - void internal_toggled(); - - void init(); - void disconnect(); - void connect(); - void quit(); - - bool gtk_callback(); - - Mode _mode; - int32_t _ping_id; - bool _attached; - - int _connect_stage; - - SharedPtr _engine_module; - Ingen::Engine* (*_new_engine)(); - Ingen::QueuedEngineInterface* (*_new_queued_engine_interface)(Ingen::Engine&); - - Gtk::Image* _icon; - Gtk::ProgressBar* _progress_bar; - Gtk::Label* _progress_label; - Gtk::Entry* _url_entry; - Gtk::RadioButton* _server_radio; - Gtk::SpinButton* _port_spinbutton; - Gtk::RadioButton* _launch_radio; - Gtk::RadioButton* _internal_radio; - Gtk::Button* _disconnect_button; - Gtk::Button* _connect_button; - Gtk::Button* _quit_button; -}; - - -} // namespace Ingenuity - -#endif // CONNECT_WINDOW_H diff --git a/src/progs/ingenuity/Connection.h b/src/progs/ingenuity/Connection.h deleted file mode 100644 index d7b3a9cc..00000000 --- a/src/progs/ingenuity/Connection.h +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONNECTION_H -#define CONNECTION_H - -#include -#include -#include -#include -#include "client/ConnectionModel.h" -using Ingen::Client::ConnectionModel; - -namespace Ingenuity { - - -/** A Connection in a Patch. - * - * \ingroup Ingenuity - */ -class Connection : public LibFlowCanvas::Connection -{ -public: - Connection(boost::shared_ptr canvas, - boost::shared_ptr model, - boost::shared_ptr src, - boost::shared_ptr dst, - uint32_t color) - : LibFlowCanvas::Connection(canvas, src, dst, color) - , _connection_model(model) - {} - - virtual ~Connection() {} - - SharedPtr model() const { return _connection_model; } - -private: - SharedPtr _connection_model; -}; - - -} // namespace Ingenuity - -#endif // CONNECTION_H diff --git a/src/progs/ingenuity/ControlGroups.cpp b/src/progs/ingenuity/ControlGroups.cpp deleted file mode 100644 index 2cdbf0a3..00000000 --- a/src/progs/ingenuity/ControlGroups.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/PluginModel.h" -#include "client/NodeModel.h" -#include "client/PortModel.h" -#include "ControlGroups.h" -#include "ControlPanel.h" -#include "PortPropertiesWindow.h" -#include "GladeFactory.h" -#include "App.h" - -using std::cerr; using std::cout; using std::endl; - -using namespace Ingen::Client; - -namespace Ingenuity { - - -// ////////////////////// ControlGroup ///////////////////////////////// // - -ControlGroup::ControlGroup(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) -: Gtk::VBox(cobject), - _control_panel(NULL), - _enable_signal(false) -{ -} - - -void -ControlGroup::init(ControlPanel* panel, SharedPtr pm) -{ - _control_panel = panel; - _port_model = pm, - - assert(_port_model); - assert(panel); - - pm->control_change_sig.connect(sigc::mem_fun(this, &ControlGroup::set_value)); -} - - -// ////////////////// SliderControlGroup ////////////////////// // - - -SliderControlGroup::SliderControlGroup(BaseObjectType* cobject, const Glib::RefPtr& xml) -: ControlGroup(cobject, xml), - _enabled(true) -{ - xml->get_widget("control_strip_name_label", _name_label); - xml->get_widget("control_strip_slider", _slider); - xml->get_widget("control_strip_spinner", _value_spinner); - - Glib::RefPtr menu_xml = GladeFactory::new_glade_reference("port_control_menu"); - menu_xml->get_widget("port_control_menu", _menu); - menu_xml->get_widget("port_control_menu_properties", _menu_properties); - - _menu_properties->signal_activate().connect( - sigc::mem_fun(this, &SliderControlGroup::menu_properties)); -} - - -void -SliderControlGroup::init(ControlPanel* panel, SharedPtr pm) -{ - _enable_signal = false; - _enabled = true; - - ControlGroup::init(panel, pm); - - assert(_name_label); - assert(_slider); - - set_name(pm->path().name()); - - _slider->set_draw_value(false); - - _name_label->signal_button_press_event().connect(sigc::mem_fun(*this, &SliderControlGroup::clicked)); - _slider->signal_button_press_event().connect(sigc::mem_fun(*this, &SliderControlGroup::clicked)); - - _slider->signal_event().connect( - sigc::mem_fun(*this, &SliderControlGroup::slider_pressed)); - - _slider->signal_value_changed().connect( - sigc::mem_fun(*this, &SliderControlGroup::update_value_from_slider)); - - _value_spinner->signal_value_changed().connect( - sigc::mem_fun(*this, &SliderControlGroup::update_value_from_spinner)); - - // FIXME: code duplication w/ PortPropertiesWindow.cpp - float min = 0.0f; - float max = 1.0f; - - const Atom& min_atom = pm->get_metadata("ingen:minimum"); - const Atom& max_atom = pm->get_metadata("ingen:maximum"); - if (min_atom.type() == Atom::FLOAT && max_atom.type() == Atom::FLOAT) { - min = min_atom.get_float(); - max = max_atom.get_float(); - } - - const SharedPtr parent = PtrCast(pm->parent()); - - if (parent && parent->plugin() && parent->plugin()->type() == PluginModel::LV2) { - min = slv2_port_get_minimum_value( - parent->plugin()->slv2_plugin(), - slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), - pm->path().name().c_str())); - max = slv2_port_get_maximum_value( - parent->plugin()->slv2_plugin(), - slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), - pm->path().name().c_str())); - } - - if (max <= min) - max = min + 1.0f; - - _slider->set_increments(0, 0); - _slider->set_range(min, max); - _value_spinner->set_range(min, max); - - set_value(pm->value()); - - _enable_signal = true; - - show_all(); -} - - -bool -SliderControlGroup::clicked(GdkEventButton* ev) -{ - if (ev->button == 3) { - _menu->popup(ev->button, ev->time); - return true; - } else { - return false; - } -} - - -void -SliderControlGroup::menu_properties() -{ - Glib::RefPtr xml = GladeFactory::new_glade_reference(); - - PortPropertiesWindow* dialog; - xml->get_widget_derived("port_properties_win", dialog); - dialog->init(this, _port_model); - dialog->run(); -} - - -void -SliderControlGroup::set_value(float val) -{ - _enable_signal = false; - if (_enabled) { - if (_slider->get_value() != val) - _slider->set_value(val); - if (_value_spinner->get_value() != val) - _value_spinner->set_value(val); - } - _enable_signal = true; -} - - -void -SliderControlGroup::set_range(float min, float max) -{ - _slider->set_range(min, max); - _value_spinner->set_range(min, max); -} - - -void -SliderControlGroup::set_name(const string& name) -{ - string name_label = ""; - name_label += name + ""; - _name_label->set_markup(name_label); -} - - -void -SliderControlGroup::enable() -{ - _slider->property_sensitive() = true; - //_min_spinner->property_sensitive() = true; - //_max_spinner->property_sensitive() = true; - _value_spinner->property_sensitive() = true; - _name_label->property_sensitive() = true; -} - - -void -SliderControlGroup::disable() -{ - _slider->property_sensitive() = false; - //_min_spinner->property_sensitive() = false; - //_max_spinner->property_sensitive() = false; - _value_spinner->property_sensitive() = false; - _name_label->property_sensitive() = false; -} - - -void -SliderControlGroup::update_value_from_slider() -{ - if (_enable_signal) { - const float value = _slider->get_value(); - _enable_signal = false; - - _value_spinner->set_value(value); - _control_panel->value_changed(_port_model, value); - - _enable_signal = true; - } -} - - -void -SliderControlGroup::update_value_from_spinner() -{ - if (_enable_signal) { - _enable_signal = false; - const float value = _value_spinner->get_value(); - - /*if (value < _min_spinner->get_value()) { - _min_spinner->set_value(value); - _slider->set_range(_min_spinner->get_value(), _max_spinner->get_value()); - } - if (value > _max_spinner->get_value()) { - _max_spinner->set_value(value); - _slider->set_range(_min_spinner->get_value(), _max_spinner->get_value()); - }*/ - - _slider->set_value(value); - - _control_panel->value_changed(_port_model, value); - - //m_port_model->value(value); - _enable_signal = true; - } -} - - -/** Callback for when slider is grabbed so we can ignore set_control - * events for this port (and avoid nasty feedback issues). - */ -bool -SliderControlGroup::slider_pressed(GdkEvent* ev) -{ - //cerr << "Pressed: " << ev->type << endl; - if (ev->type == GDK_BUTTON_PRESS) { - _enabled = false; - //GtkClientInterface::instance()->set_ignore_port(_port_model->path()); - } else if (ev->type == GDK_BUTTON_RELEASE) { - _enabled = true; - //GtkClientInterface::instance()->clear_ignore_port(); - } - - return false; -} - - -// ///////////// IntegerControlGroup ////////////// // - -#if 0 -IntegerControlGroup::IntegerControlGroup(ControlPanel* panel, SharedPtr pm) -: ControlGroup(panel, pm), - _enable_signal(false), - _alignment(0.5, 0.5, 0.0, 0.0), - _name_label(pm->path().name()), - _spinner(1.0, 0) -{ - set_name(pm->path().name()); - - _spinner.set_range(-99999, 99999); - _spinner.set_value(_port_model->value()); - _spinner.signal_value_changed().connect( - sigc::mem_fun(*this, &IntegerControlGroup::update_value)); - _spinner.set_increments(1, 10); - - _alignment.add(_spinner); - pack_start(_name_label); - pack_start(_alignment); - - _enable_signal = true; - - show_all(); -} - - -void -IntegerControlGroup::set_name(const string& name) -{ - string name_label = ""; - name_label += name + ""; - _name_label->set_markup(name_label); -} - - -void -IntegerControlGroup::set_value(float val) -{ - //cerr << "[IntegerControlGroup] Setting value to " << val << endl; - _enable_signal = false; - _spinner.set_value(val); - _enable_signal = true; -} - - -void -IntegerControlGroup::enable() -{ - _spinner.property_sensitive() = true; - _name_label->property_sensitive() = true; -} - - -void -IntegerControlGroup::disable() -{ - _spinner.property_sensitive() = false; - _name_label->property_sensitive() = false; -} - - -void -IntegerControlGroup::update_value() -{ - if (_enable_signal) { - float value = _spinner.get_value(); - _control_panel->value_changed(_port_model, value); - //m_port_model->value(value); - } -} - - -// ///////////// ToggleControlGroup ////////////// // - - -ToggleControlGroup::ToggleControlGroup(ControlPanel* panel, SharedPtr pm) -: ControlGroup(panel, pm), - _enable_signal(false), - _alignment(0.5, 0.5, 0.0, 0.0), - _name_label(pm->path().name()) -{ - set_name(pm->path().name()); - - set_value(_port_model->value()); - _checkbutton.signal_toggled().connect( - sigc::mem_fun(*this, &ToggleControlGroup::update_value)); - - _alignment.add(_checkbutton); - pack_start(_name_label); - pack_start(_alignment); - - _enable_signal = true; - - show_all(); -} - - -void -ToggleControlGroup::set_name(const string& name) -{ - string name_label = ""; - name_label += name + ""; - _name_label->set_markup(name_label); -} - - -void -ToggleControlGroup::set_value(float val) -{ - //cerr << "[ToggleControlGroup] Setting value to " << val << endl; - _enable_signal = false; - _checkbutton.set_active( (val > 0.0f) ); - _enable_signal = true; -} - - -void -ToggleControlGroup::enable() -{ - _checkbutton.property_sensitive() = true; - _name_label->property_sensitive() = true; -} - - -void -ToggleControlGroup::disable() -{ - _checkbutton.property_sensitive() = false; - _name_label->property_sensitive() = false; -} - - -void -ToggleControlGroup::update_value() -{ - if (_enable_signal) { - float value = _checkbutton.get_active() ? 1.0f : 0.0f; - _control_panel->value_changed(_port_model, value); - //m_port_model->value(value); - } -} -#endif - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/ControlGroups.h b/src/progs/ingenuity/ControlGroups.h deleted file mode 100644 index 70b8bb72..00000000 --- a/src/progs/ingenuity/ControlGroups.h +++ /dev/null @@ -1,160 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONTROLGROUPS_H -#define CONTROLGROUPS_H - -#include -#include -#include -#include -#include "client/PortModel.h" -#include - -namespace Ingen { namespace Client { class PortModel; } } -using namespace Ingen::Client; - -namespace Ingenuity { - -class ControlPanel; -class PortPropertiesWindow; - - -/** A group of controls (for a single Port) in a NodeControlWindow. - * - * \ingroup Ingenuity - */ -class ControlGroup : public Gtk::VBox -{ -public: - ControlGroup(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); - virtual ~ControlGroup() { } - - void init(ControlPanel* panel, SharedPtr pm); - - inline const SharedPtr port_model() const { return _port_model; } - -protected: - friend class PortPropertiesWindow; - - virtual void set_value(float value) = 0; - virtual void set_range(float min, float max) {} - - ControlPanel* _control_panel; - SharedPtr _port_model; - bool _enable_signal; -}; - - -/** A slider for a continuous control. - * - * \ingroup Ingenuity - */ -class SliderControlGroup : public ControlGroup -{ -public: - SliderControlGroup(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); - void init(ControlPanel* panel, SharedPtr pm); - - void enable(); - void disable(); - - void set_min(float val); - void set_max(float val); - -private: - void set_name(const string& name); - - bool clicked(GdkEventButton* ev); - - void set_value(float value); - void set_range(float min, float max); - - void update_range(); - void update_value_from_slider(); - void update_value_from_spinner(); - - void menu_properties(); - - bool slider_pressed(GdkEvent* ev); - - bool _enabled; - - Gtk::Label* _name_label; - Gtk::SpinButton* _value_spinner; - Gtk::HScale* _slider; - - Gtk::Menu* _menu; - Gtk::MenuItem* _menu_properties; -}; - - -#if 0 - -/** A spinbutton for integer controls. - * - * \ingroup Ingenuity - */ -class IntegerControlGroup : public ControlGroup -{ -public: - IntegerControlGroup(ControlPanel* panel, SharedPtr pm); - - void enable(); - void disable(); - -private: - void set_name(const string& name); - void set_value(float val); - - void update_value(); - - bool _enable_signal; - Gtk::Alignment _alignment; - Gtk::Label _name_label; - Gtk::SpinButton _spinner; -}; - - -/** A radio button for toggle controls. - * - * \ingroup Ingenuity - */ -class ToggleControlGroup : public ControlGroup -{ -public: - ToggleControlGroup(ControlPanel* panel, SharedPtr pm); - - void enable(); - void disable(); - -private: - void set_name(const string& name); - void set_value(float val); - - void update_value(); - - bool _enable_signal; - Gtk::Alignment _alignment; - Gtk::Label _name_label; - Gtk::CheckButton _checkbutton; -}; -#endif - -} // namespace Ingenuity - -#endif // CONTROLGROUPS_H diff --git a/src/progs/ingenuity/ControlPanel.cpp b/src/progs/ingenuity/ControlPanel.cpp deleted file mode 100644 index 7e153ba5..00000000 --- a/src/progs/ingenuity/ControlPanel.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License alongCont - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "client/NodeModel.h" -#include "client/PortModel.h" -#include "client/PluginModel.h" -#include "App.h" -#include "ControlPanel.h" -#include "ControlGroups.h" -#include "GladeFactory.h" - -namespace Ingenuity { - - -ControlPanel::ControlPanel(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::HBox(cobject), - _callback_enabled(true) -{ - xml->get_widget("control_panel_controls_box", _control_box); - xml->get_widget("control_panel_voice_controls_box", _voice_control_box); - xml->get_widget("control_panel_all_voices_radio", _all_voices_radio); - xml->get_widget("control_panel_specific_voice_radio", _specific_voice_radio); - xml->get_widget("control_panel_voice_spinbutton", _voice_spinbutton); - - _all_voices_radio->signal_toggled().connect(sigc::mem_fun(this, &ControlPanel::all_voices_selected)); - _specific_voice_radio->signal_toggled().connect(sigc::mem_fun(this, &ControlPanel::specific_voice_selected)); - _voice_spinbutton->signal_value_changed().connect(sigc::mem_fun(this, &ControlPanel::voice_selected)); - - show_all(); -} - - -ControlPanel::~ControlPanel() -{ - for (vector::iterator i = _controls.begin(); i != _controls.end(); ++i) - delete (*i); -} - - -void -ControlPanel::init(SharedPtr node, size_t poly) -{ - assert(node != NULL); - assert(poly > 0); - - if (poly > 1) { - _voice_spinbutton->set_range(0, poly - 1); - } else { - remove(*_voice_control_box); - } - - for (PortModelList::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) { - add_port(*i); - } - - _callback_enabled = true; -} - - -ControlGroup* -ControlPanel::find_port(const Path& path) const -{ - for (vector::const_iterator cg = _controls.begin(); cg != _controls.end(); ++cg) - if ((*cg)->port_model()->path() == path) - return (*cg); - - return NULL; -} - - -/** Add a control to the panel for the given port. - */ -void -ControlPanel::add_port(SharedPtr pm) -{ - assert(pm); - - // Already have port, don't add another - if (find_port(pm->path()) != NULL) - return; - - // Add port - if (pm->is_control() && pm->is_input()) { - SliderControlGroup* cg = NULL; - if (pm->is_integer()) - cerr << "FIXME: integer\n"; - //cg = new IntegerControlGroup(this, pm); - else if (pm->is_toggle()) - cerr << "FIXME: toggle\n"; - //cg = new ToggleControlGroup(this, pm); - else { - Glib::RefPtr xml = GladeFactory::new_glade_reference("control_strip"); - xml->get_widget_derived("control_strip", cg); - cg->init(this, pm); - } - - if (_controls.size() > 0) - _control_box->pack_start(*Gtk::manage(new Gtk::HSeparator()), false, false, 4); - - _controls.push_back(cg); - _control_box->pack_start(*cg, false, false, 0); - - cg->enable(); - /*if (pm->connected()) - cg->disable(); - else - cg->enable();*/ - - cg->show(); - - cerr << "FIXME: control panel connected port tracking\n"; - // pm->connection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::connection), pm)) - // pm->disconnection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::disconnection), pm)) - } - - Gtk::Requisition controls_size; - _control_box->size_request(controls_size); - _ideal_size.first = controls_size.width; - _ideal_size.second = controls_size.height; - - Gtk::Requisition voice_size; - _voice_control_box->size_request(voice_size); - _ideal_size.first += voice_size.width; - _ideal_size.second += voice_size.height; - - //cerr << "Setting ideal size to " << _ideal_size.first - // << " x " << _ideal_size.second << endl; -} - - -/** Remove the control for the given port. - */ -void -ControlPanel::remove_port(const Path& path) -{ - bool was_first = false; - for (vector::iterator cg = _controls.begin(); cg != _controls.end(); ++cg) { - if ((*cg)->port_model()->path() == path) { - _control_box->remove(**cg); - if (cg == _controls.begin()) - was_first = true; - _controls.erase(cg); - break; - } - } -} - - -/** Rename the control for the given port. - */ -/* -void -ControlPanel::rename_port(const Path& old_path, const Path& new_path) -{ - for (vector::iterator cg = _controls.begin(); cg != _controls.end(); ++cg) { - if ((*cg)->port_model()->path() == old_path) { - (*cg)->set_name(new_path.name()); - return; - } - } -} -*/ - -#if 0 -/** Enable the control for the given port. - * - * Used when all connections to port are un-made. - */ -void -ControlPanel::enable_port(const Path& path) -{ - for (vector::iterator i = _controls.begin(); i != _controls.end(); ++i) { - if ((*i)->port_model()->path() == path) { - (*i)->enable(); - return; - } - } -} - - -/** Disable the control for the given port. - * - * Used when port is connected. - */ -void -ControlPanel::disable_port(const Path& path) -{ - for (vector::iterator i = _controls.begin(); i != _controls.end(); ++i) { - if ((*i)->port_model()->path() == path) { - (*i)->disable(); - return; - } - } -} -#endif - -/** Callback for ControlGroups to notify this of a change. - */ -void -ControlPanel::value_changed(SharedPtr port, float val) -{ - if (_callback_enabled) { - App::instance().engine()->disable_responses(); - - /* Send the message, but set the client-side model's value to the new - * setting right away (so the value doesn't need to be echoed back) */ - - if (_all_voices_radio->get_active()) { - App::instance().engine()->set_port_value(port->path(), val); - port->value(val); - } else { - int voice = _voice_spinbutton->get_value_as_int(); - App::instance().engine()->set_port_value(port->path(), voice, val); - port->value(val); - } - - App::instance().engine()->set_next_response_id(rand()); // FIXME: inefficient, probably not good - } -} - -void -ControlPanel::all_voices_selected() -{ - _voice_spinbutton->property_sensitive() = false; -} - - -void -ControlPanel::specific_voice_selected() -{ - _voice_spinbutton->property_sensitive() = true; -} - - -void -ControlPanel::voice_selected() -{ -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/ControlPanel.h b/src/progs/ingenuity/ControlPanel.h deleted file mode 100644 index f7da37ad..00000000 --- a/src/progs/ingenuity/ControlPanel.h +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONTROLPANEL_H -#define CONTROLPANEL_H - -#include -#include -#include -#include // for pair<> -#include -#include -#include -#include -#include -#include "ControlGroups.h" - - -using std::vector; using std::string; using std::pair; -using std::cerr; using std::cout; using std::endl; - -namespace Ingen { namespace Client { - class PortModel; - class NodeModel; -} } -using namespace Ingen::Client; - -namespace Ingenuity { - - -/** A group of controls for a node (or patch). - * - * Used by both NodeControlWindow and the main window (for patch controls). - * - * \ingroup Ingenuity - */ -class ControlPanel : public Gtk::HBox { -public: - ControlPanel(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); - virtual ~ControlPanel(); - - void init(SharedPtr node, size_t poly); - - ControlGroup* find_port(const Path& path) const; - - void add_port(SharedPtr port); - void remove_port(const Path& path); - - void enable_port(const Path& path); - void disable_port(const Path& path); - - size_t num_controls() const { return _controls.size(); } - pair ideal_size() const { return _ideal_size; } - - // Callback for ControlGroup - void value_changed(SharedPtr port_path, float val); - -private: - void all_voices_selected(); - void specific_voice_selected(); - void voice_selected(); - - bool _callback_enabled; - - pair _ideal_size; - - vector _controls; - Gtk::VBox* _control_box; - Gtk::Box* _voice_control_box; - Gtk::RadioButton* _all_voices_radio; - Gtk::RadioButton* _specific_voice_radio; - Gtk::SpinButton* _voice_spinbutton; -}; - - -} // namespace Ingenuity - -#endif // CONTROLPANEL_H diff --git a/src/progs/ingenuity/DSSIController.cpp b/src/progs/ingenuity/DSSIController.cpp deleted file mode 100644 index 01ef96c4..00000000 --- a/src/progs/ingenuity/DSSIController.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "DSSIController.h" -#include -#include -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/NodeModel.h" -#include "App.h" -#include "DSSIModule.h" - -namespace Ingenuity { - - -DSSIController::DSSIController(SharedPtr model) -: _banks_dirty(true) -{ -#if 0 - assert(model->plugin()->type() == PluginModel::DSSI); - Gtk::Menu::MenuList& items = _menu.items(); - items[0].property_sensitive() = true; // "Show Control Window" item - - Gtk::Menu_Helpers::MenuElem program_elem("Select Program", _program_menu); - items.push_front(program_elem); - _program_menu_item = program_elem.get_child(); - _program_menu_item->set_sensitive(false); - - items.push_front(Gtk::Menu_Helpers::MenuElem("Show Plugin GUI", - sigc::mem_fun(this, &DSSIController::show_gui))); -#endif -} - -void -DSSIController::program_add(int bank, int program, const string& name) -{ - cerr << "FIXME: DSSI add program\n"; - //node_model()->add_program(bank, program, name); - //m_banks_dirty = true; -} - - -void -DSSIController::program_remove(int bank, int program) -{ - cerr << "FIXME: DSSI add program\n"; - //node_model()->remove_program(bank, program); - //m_banks_dirty = true; -} - -/** Trivial wrapper of attempt_to_show_gui for libsigc - */ -void -DSSIController::show_gui() -{ - attempt_to_show_gui(); -} - - -void -DSSIController::update_program_menu() -{ - cerr << "FIXME: Program menu\n"; -#if 0 - _program_menu.items().clear(); - - const map >& banks = node_model()->get_programs(); - std::ostringstream oss; - - map >::const_iterator i; - for (i = banks.begin(); i != banks.end(); ++i) { - Gtk::Menu* bank_menu; - if (banks.size() > 1) - bank_menu = manage(new Gtk::Menu()); - else - bank_menu = &_program_menu; - map::const_iterator j; - for (j = i->second.begin(); j != i->second.end(); ++j) { - oss.str(""); - oss << std::setw(3) << std::setfill('0') - << j->first << ' ' << j->second; - sigc::slot slt = bind( - bind(sigc::mem_fun(*this, &DSSIController::send_program_change), - j->first), i->first); - bank_menu->items().push_back( - Gtk::Menu_Helpers::MenuElem(oss.str(), slt)); - } - if (banks.size() > 1) { - oss.str(""); - oss << "Bank " << i->first; - _program_menu.items().push_back( - Gtk::Menu_Helpers::MenuElem(oss.str(), *bank_menu)); - } - } - - // Disable the program menu if there are no programs - if (banks.size() == 0) - _program_menu_item->set_sensitive(false); - else - _program_menu_item->set_sensitive(true); - - _banks_dirty = false; -#endif -} - - -void -DSSIController::send_program_change(int bank, int program) -{ - //App::instance().engine()->set_program(node_model()->path(), bank, program); -} - - -/** Attempt to show the DSSI GUI for this plugin. - * - * Returns whether or not GUI was successfully loaded/shown. - */ -bool -DSSIController::attempt_to_show_gui() -{ - cerr << "FIXME: DSSI GUI" << endl; -#if 0 - // Shamelessley "inspired by" jack-dssi-host - // Copyright 2004 Chris Cannam, Steve Harris and Sean Bolton. - - const bool verbose = false; - - string engine_url = App::instance().engine()->engine_url(); - // Hack off last character if it's a / - if (engine_url[engine_url.length()-1] == '/') - engine_url = engine_url.substr(0, engine_url.length()-1); - - const char* dllName = node_model()->plugin()->lib_name().c_str(); - const char* label = node_model()->plugin()->plug_label().c_str(); - const char* myName = "ingenuity"; - const string& oscUrl = engine_url + "/dssi" + node_model()->path(); - - struct dirent* entry = NULL; - char* dllBase = strdup(dllName); - char* subpath = NULL; - DIR* subdir = NULL; - char* filename = NULL; - struct stat buf; - int fuzzy = 0; - - char* env_dssi_path = getenv("DSSI_PATH"); - string dssi_path; - if (!env_dssi_path) { - cerr << "DSSI_PATH is empty. Assuming /usr/lib/dssi:/usr/local/lib/dssi." << endl; - dssi_path = "/usr/lib/dssi:/usr/local/lib/dssi"; - } else { - dssi_path = env_dssi_path; - } - - if (strlen(dllBase) > 3 && !strcasecmp(dllBase + strlen(dllBase) - 3, ".so")) { - dllBase[strlen(dllBase) - 3] = '\0'; - } - - - // This is pretty nasty, it loops through the path, even if the dllBase is absolute - while (dssi_path != "") { - string directory = dssi_path.substr(0, dssi_path.find(':')); - if (dssi_path.find(':') != string::npos) - dssi_path = dssi_path.substr(dssi_path.find(':')+1); - else - dssi_path = ""; - - if (*dllBase == '/') { - subpath = strdup(dllBase); - } else { - subpath = (char*)malloc(strlen(directory.c_str()) + strlen(dllBase) + 2); - sprintf(subpath, "%s/%s", directory.c_str(), dllBase); - } - - for (fuzzy = 0; fuzzy <= 1; ++fuzzy) { - - if (!(subdir = opendir(subpath))) { - if (verbose) { - fprintf(stderr, "%s: can't open plugin GUI directory \"%s\"\n", myName, subpath); - } - break; - } - - while ((entry = readdir(subdir))) { - - if (entry->d_name[0] == '.') - continue; - if (!strchr(entry->d_name, '_')) - continue; - - if (fuzzy) { - if (verbose) { - fprintf(stderr, "checking %s against %s\n", entry->d_name, dllBase); - } - if (strncmp(entry->d_name, dllBase, strlen(dllBase))) - continue; - } else { - if (verbose) { - fprintf(stderr, "checking %s against %s\n", entry->d_name, label); - } - if (strncmp(entry->d_name, label, strlen(label))) - continue; - } - - filename = (char*)malloc(strlen(subpath) + strlen(entry->d_name) + 2); - sprintf(filename, "%s/%s", subpath, entry->d_name); - - if (stat(filename, &buf)) { - perror("stat failed"); - free(filename); - continue; - } - - if ((S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) && - (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) { - - if (verbose) { - fprintf(stderr, "%s: trying to execute GUI at \"%s\"\n", - myName, filename); - } - - if (fork() == 0) { - execlp(filename, filename, oscUrl.c_str(), dllName, label, - node_model()->name().c_str(), 0); - perror("exec failed"); - exit(1); - } - - free(filename); - free(subpath); - free(dllBase); - return true; - } - - free(filename); - } - } - } - - cerr << "Unable to launch DSSI GUI for " << node_model()->path() << endl; - - free(subpath); - free(dllBase); -#endif - return false; -} - - -void -DSSIController::show_menu(GdkEventButton* event) -{ -#if 0 - if (_banks_dirty) - update_program_menu(); - NodeController::show_menu(event); -#endif -} - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/DSSIController.h b/src/progs/ingenuity/DSSIController.h deleted file mode 100644 index 3d5922c9..00000000 --- a/src/progs/ingenuity/DSSIController.h +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DSSICONTROLLER_H -#define DSSICONTROLLER_H - -#include -#include -#include -#include "client/NodeModel.h" - -using std::string; -using namespace Ingen::Client; - -namespace Ingen { namespace Client { - class MetadataModel; - class NodeModel; - class PortModel; -} } - -namespace Ingenuity { - -class NodeControlWindow; -class NodePropertiesWindow; - -/* Controller for a DSSI node. - * - * FIXME: legacy cruft. move this code to the appropriate places and nuke - * this class. - * - * \ingroup Ingenuity - */ -class DSSIController -{ -public: - DSSIController(SharedPtr model); - - virtual ~DSSIController() {} - - void show_gui(); - bool attempt_to_show_gui(); - void program_add(int bank, int program, const string& name); - void program_remove(int bank, int program); - - void send_program_change(int bank, int program); - - void show_menu(GdkEventButton* event); - -private: - void update_program_menu(); - - Gtk::Menu _program_menu; - Glib::RefPtr _program_menu_item; - - bool _banks_dirty; -}; - - -} // namespace Ingenuity - -#endif // DSSICONTROLLER_H diff --git a/src/progs/ingenuity/DSSIModule.cpp b/src/progs/ingenuity/DSSIModule.cpp deleted file mode 100644 index 38706de6..00000000 --- a/src/progs/ingenuity/DSSIModule.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "DSSIModule.h" -#include "DSSIController.h" - -namespace Ingenuity { - - -DSSIModule::DSSIModule(boost::shared_ptr canvas, SharedPtr node) -: NodeModule(canvas, node) -{ -} - - -void -DSSIModule::on_double_click(GdkEventButton* ev) -{ - /* - DSSIController* dc = dynamic_cast(_node); - if (!dc || ! dc->attempt_to_show_gui()) - show_control_window(); - */ -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/DSSIModule.h b/src/progs/ingenuity/DSSIModule.h deleted file mode 100644 index f41ce889..00000000 --- a/src/progs/ingenuity/DSSIModule.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DSSIMODULE_H -#define DSSIMODULE_H - -#include "NodeModule.h" - -namespace Ingenuity { - -class DSSIController; - -/* Module for a DSSI node. - * - * \ingroup Ingenuity - */ -class DSSIModule : public Ingenuity::NodeModule -{ -public: - DSSIModule(boost::shared_ptr canvas, SharedPtr node); - virtual ~DSSIModule() {} - - void on_double_click(GdkEventButton* ev); -}; - - -} // namespace Ingenuity - -#endif // DSSIMODULE_H - diff --git a/src/progs/ingenuity/GladeFactory.cpp b/src/progs/ingenuity/GladeFactory.cpp deleted file mode 100644 index dcb3e941..00000000 --- a/src/progs/ingenuity/GladeFactory.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "GladeFactory.h" -#include -#include -using std::cout; using std::cerr; using std::endl; -using std::ifstream; - -namespace Ingenuity { - - -Glib::ustring GladeFactory::glade_filename = ""; - - -void -GladeFactory::find_glade_file() -{ - // Check for the .glade file in current directory - glade_filename = "./ingenuity.glade"; - ifstream fs(glade_filename.c_str()); - if (fs.fail()) { // didn't find it, check PKGDATADIR - fs.clear(); - glade_filename = PKGDATADIR; - glade_filename += "/ingenuity.glade"; - - fs.open(glade_filename.c_str()); - if (fs.fail()) { - cerr << "[GladeFactory] Unable to find ingenuity.glade in current directory or " << PKGDATADIR << "." << endl; - throw; - } - fs.close(); - } - cerr << "[GladeFactory] Loading widgets from " << glade_filename.c_str() << endl; -} - - -Glib::RefPtr -GladeFactory::new_glade_reference(const string& toplevel_widget) -{ - if (glade_filename == "") - find_glade_file(); - - try { - if (toplevel_widget == "") - return Gnome::Glade::Xml::create(glade_filename); - else - return Gnome::Glade::Xml::create(glade_filename, toplevel_widget.c_str()); - } catch (const Gnome::Glade::XmlError& ex) { - cerr << ex.what() << endl; - throw ex; - } -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/GladeFactory.h b/src/progs/ingenuity/GladeFactory.h deleted file mode 100644 index 0b7e8198..00000000 --- a/src/progs/ingenuity/GladeFactory.h +++ /dev/null @@ -1,49 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef GLADEFACTORY_H -#define GLADEFACTORY_H - -#include -#include - -using std::string; - -namespace Ingenuity { - - -/** Creates glade references, so various objects can create widgets. - * Purely static. - * - * \ingroup Ingenuity - */ -class GladeFactory { -public: - static Glib::RefPtr - new_glade_reference(const string& toplevel_widget = ""); - -private: - GladeFactory() {} - - static void find_glade_file(); - static Glib::ustring glade_filename; -}; - - -} // namespace Ingenuity - -#endif // GLADEFACTORY_H diff --git a/src/progs/ingenuity/LashController.cpp b/src/progs/ingenuity/LashController.cpp deleted file mode 100644 index 6ede8335..00000000 --- a/src/progs/ingenuity/LashController.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "LashController.h" -#include "config.h" -#include -#include -#include -#include -#include -#include "App.h" -#include "PatchModel.h" - -using std::cerr; using std::cout; using std::endl; -using std::string; - -namespace Ingenuity { - - -LashController::LashController(lash_args_t* args) -: _client(NULL) -{ - _client = lash_init(args, PACKAGE_NAME, - /*LASH_Config_Data_Set|*/LASH_Config_File, LASH_PROTOCOL(2, 0)); - if (_client == NULL) { - cerr << "[LashController] Failed to connect to LASH. Session management will not function." << endl; - } else { - cout << "[LashController] Lash initialised" << endl; - } - - lash_event_t* event = lash_event_new_with_type(LASH_Client_Name); - lash_event_set_string(event, "Ingenuity"); - lash_send_event(_client, event); -} - - -LashController::~LashController() -{ - if (_client != NULL) { - lash_event_t* quit_event = lash_event_new_with_type(LASH_Quit); - lash_send_event(_client, quit_event); - } -} - - -void -LashController::process_events() -{ - assert(_client != NULL); - - lash_event_t* ev = NULL; - lash_config_t* conf = NULL; - - // Process events - while ((ev = lash_get_event(_client)) != NULL) { - handle_event(ev); - lash_event_destroy(ev); - } - - // Process configs - while ((conf = lash_get_config(_client)) != NULL) { - handle_config(conf); - lash_config_destroy(conf); - } -} - - -void -LashController::handle_event(lash_event_t* ev) -{ - assert(ev != NULL); - - LASH_Event_Type type = lash_event_get_type(ev); - const char* c_str = lash_event_get_string(ev); - string str = (c_str == NULL) ? "" : c_str; - - if (type == LASH_Save_File) { - cout << "[LashController] LASH Save File - " << str << endl; - save(str); - lash_send_event(_client, lash_event_new_with_type(LASH_Save_File)); - } else if (type == LASH_Restore_File) { - cout << "[LashController] LASH Restore File - " << str << endl; - cerr << "LASH RESTORE NOT YET (RE)IMPLEMENTED." << endl; - /*_controller->load_session_blocking(str + "/session"); - _controller->lash_restore_finished(); - lash_send_event(_client, lash_event_new_with_type(LASH_Restore_File)); - */ - /*} else if (type == LASH_Save_Data_Set) { - //cout << "[LashController] LASH Save Data Set - " << endl; - - // Tell LASH we're done - lash_send_event(_client, lash_event_new_with_type(LASH_Save_Data_Set)); - */ - } else if (type == LASH_Quit) { - cout << "[LashController] LASH Quit" << endl; - _client = NULL; - App::instance().quit(); - } else { - cerr << "[LashController] Unhandled LASH event, type: " << static_cast(type) << endl; - } -} - - -void -LashController::handle_config(lash_config_t* conf) -{ - assert(conf != NULL); - - const char* key = NULL; - const void* val = NULL; - size_t val_size = 0; - - cout << "[LashController] LASH Config. Key = " << key << endl; - - key = lash_config_get_key(conf); - val = lash_config_get_value(conf); - val_size = lash_config_get_value_size(conf); -} - -void -LashController::save(const string& dir) -{ - cerr << "LASH SAVING NOT YET (RE)IMPLEMENTED\n"; - /* - PatchController* pc = NULL; - - // Save every patch under dir with it's path as a filename - // (so the dir structure will resemble the patch heirarchy) - for (map::iterator i = _app->patches().begin(); - i != _app->patches().end(); ++i) { - pc = (*i).second; - pc->model()->filename(dir + pc->model()->path() + ".om"); - } - - // Create directories - for (map::iterator i = _app->patches().begin(); - i != _app->patches().end(); ++i) { - pc = (*i).second; - if (pc->model()->parent() != NULL) { - string path = Path::parent(pc->model()->path()).substr(1) + "/"; - while (path.find("/") != string::npos) { - mkdir(string(dir +"/"+ path.substr(0, path.find("/"))).c_str(), 0744); - path = path.substr(path.find("/")+1); - } - } - _controller->save_patch_blocking(pc->model(), pc->model()->filename(), false); - } - - //m_app->state_manager()->save(str + "/omgtkrc"); - _controller->save_session_blocking(dir + "/session"); - */ -} - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/LashController.h b/src/progs/ingenuity/LashController.h deleted file mode 100644 index 7721e5b2..00000000 --- a/src/progs/ingenuity/LashController.h +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of IngenGtk. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LASHCONTROLLER_H -#define LASHCONTROLLER_H - -#include -#include -using std::string; - -namespace Ingenuity { - -class App; - -/* Old and unused LASH controller. - * - * \ingroup Ingenuity - */ -class LashController -{ -public: - LashController(lash_args_t* args); - ~LashController(); - - bool enabled() { return lash_enabled(_client); } - void process_events(); - -private: - void save(const string& dir); - - lash_client_t* _client; - - void handle_event(lash_event_t* conf); - void handle_config(lash_config_t* conf); -}; - - -} // namespace Ingenuity - -#endif // LASHCONTROLLER_H diff --git a/src/progs/ingenuity/LoadPatchWindow.cpp b/src/progs/ingenuity/LoadPatchWindow.cpp deleted file mode 100644 index 70d5c409..00000000 --- a/src/progs/ingenuity/LoadPatchWindow.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "LoadPatchWindow.h" -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "App.h" -#include "Configuration.h" -#include "ThreadedLoader.h" - -using namespace Ingen::Serialisation; -using boost::optional; - -namespace Ingenuity { - - -LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::FileChooserDialog(cobject), - _replace(true) -{ - xml->get_widget("load_patch_poly_from_current_radio", _poly_from_current_radio); - xml->get_widget("load_patch_poly_from_file_radio", _poly_from_file_radio); - xml->get_widget("load_patch_poly_from_user_radio", _poly_from_user_radio); - xml->get_widget("load_patch_poly_spinbutton", _poly_spinbutton); - xml->get_widget("load_patch_ok_button", _ok_button); - xml->get_widget("load_patch_cancel_button", _cancel_button); - - _poly_from_current_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); - _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); - _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_user_selected)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::ok_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::cancel_clicked)); - - _poly_from_current_radio->set_active(true); - - Gtk::FileFilter filt; - filt.add_pattern("*.om"); - filt.set_name("Om patch files (XML, DEPRECATED) (*.om)"); - filt.add_pattern("*.ingen.ttl"); - filt.set_name("Ingen patch files (RDF, *.ingen.ttl)"); - set_filter(filt); - - // Add global examples directory to "shortcut folders" (bookmarks) - string examples_dir = PKGDATADIR; - examples_dir.append("/patches"); - DIR* d = opendir(examples_dir.c_str()); - if (d != NULL) - add_shortcut_folder(examples_dir); -} - - -void -LoadPatchWindow::present(SharedPtr patch, MetadataMap data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadPatchWindow::set_patch(SharedPtr patch) -{ - _patch = patch; -} - - -void -LoadPatchWindow::on_show() -{ - if (App::instance().configuration()->patch_folder().length() > 0) - set_current_folder(App::instance().configuration()->patch_folder()); - Gtk::FileChooserDialog::on_show(); -} - - -///// Event Handlers ////// - - -void -LoadPatchWindow::poly_from_file_selected() -{ - _poly_spinbutton->property_sensitive() = false; -} - - -void -LoadPatchWindow::poly_from_user_selected() -{ - _poly_spinbutton->property_sensitive() = true; -} - - -void -LoadPatchWindow::ok_clicked() -{ - // If unset load_patch will load values - optional name; - optional poly; - - optional parent; - - if (_poly_from_user_radio->get_active()) - poly = _poly_spinbutton->get_value_as_int(); - - if (_replace) - App::instance().engine()->clear_patch(_patch->path()); - - if (_patch->path() != "/") - parent = _patch->path().parent(); - - App::instance().loader()->load_patch(true, get_uri(), "/", - _initial_data, parent, name, poly); - - hide(); -} - - -void -LoadPatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/LoadPatchWindow.h b/src/progs/ingenuity/LoadPatchWindow.h deleted file mode 100644 index 7f17cef7..00000000 --- a/src/progs/ingenuity/LoadPatchWindow.h +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADPATCHWINDOW_H -#define LOADPATCHWINDOW_H - -#include -#include -#include -#include "client/PluginModel.h" -#include "client/PatchModel.h" -using Ingen::Client::PatchModel; -using Ingen::Client::MetadataMap; - -namespace Ingenuity { - - -/** 'Load Patch' window. - * - * Loaded by glade as a derived object. Used for both "Import" and "Load" - * (e.g. Replace, clear-then-import) operations (the radio button state - * should be changed with the provided methods before presenting). - * - * This is not for loading subpatches. See @a LoadSubpatchWindow for that. - * - * \ingroup Ingenuity - */ -class LoadPatchWindow : public Gtk::FileChooserDialog -{ -public: - LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void set_patch(SharedPtr patch); - - void set_replace() { _replace = true; } - void set_merge() { _replace = false; } - - void present(SharedPtr patch, MetadataMap data); - -protected: - void on_show(); - -private: - void poly_from_file_selected(); - void poly_from_user_selected(); - void ok_clicked(); - void cancel_clicked(); - - MetadataMap _initial_data; - - SharedPtr _patch; - bool _replace; - - Gtk::RadioButton* _poly_from_current_radio; - Gtk::RadioButton* _poly_from_file_radio; - Gtk::RadioButton* _poly_from_user_radio; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace Ingenuity - -#endif // LOADPATCHWINDOW_H diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp deleted file mode 100644 index 5d314db2..00000000 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/NodeModel.h" -#include "client/PatchModel.h" -#include "client/Store.h" -#include "App.h" -#include "LoadPluginWindow.h" -#include "PatchWindow.h" -#include "PatchView.h" -#include "PatchCanvas.h" -using std::cout; using std::cerr; using std::endl; - - -namespace Ingenuity { - -LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::Window(cobject), - _has_shown(false), - _plugin_name_offset(0) -{ - xml->get_widget("load_plugin_plugins_treeview", _plugins_treeview); - xml->get_widget("load_plugin_polyphonic_checkbutton", _polyphonic_checkbutton); - xml->get_widget("load_plugin_name_entry", _node_name_entry); - xml->get_widget("load_plugin_clear_button", _clear_button); - xml->get_widget("load_plugin_add_button", _add_button); - //xml->get_widget("load_plugin_close_button", _close_button); - //xml->get_widget("load_plugin_ok_button", _add_button); - - xml->get_widget("load_plugin_filter_combo", _filter_combo); - xml->get_widget("load_plugin_search_entry", _search_entry); - - // Set up the plugins list - _plugins_liststore = Gtk::ListStore::create(_plugins_columns); - _plugins_treeview->set_model(_plugins_liststore); - _plugins_treeview->append_column("Name", _plugins_columns._col_name); - _plugins_treeview->append_column("Type", _plugins_columns._col_type); - _plugins_treeview->append_column("URI", _plugins_columns._col_uri); - //m_plugins_treeview->append_column("Library", _plugins_columns._col_library); - //m_plugins_treeview->append_column("Label", _plugins_columns._col_label); - - // This could be nicer.. store the TreeViewColumns locally maybe? - _plugins_treeview->get_column(0)->set_sort_column(_plugins_columns._col_name); - _plugins_treeview->get_column(1)->set_sort_column(_plugins_columns._col_type); - _plugins_treeview->get_column(2)->set_sort_column(_plugins_columns._col_uri); - //m_plugins_treeview->get_column(3)->set_sort_column(_plugins_columns._col_library); - //m_plugins_treeview->get_column(4)->set_sort_column(_plugins_columns._col_label); - for (int i=0; i < 3; ++i) - _plugins_treeview->get_column(i)->set_resizable(true); - - _plugins_liststore->set_default_sort_func(sigc::mem_fun(this, &LoadPluginWindow::plugin_compare)); - - // Set up the search criteria combobox - _criteria_liststore = Gtk::ListStore::create(_criteria_columns); - _filter_combo->set_model(_criteria_liststore); - Gtk::TreeModel::iterator iter = _criteria_liststore->append(); - Gtk::TreeModel::Row row = *iter; - row[_criteria_columns._col_label] = "Name contains"; - row[_criteria_columns._col_criteria] = CriteriaColumns::NAME; - _filter_combo->set_active(iter); - iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "Type contains"; - row[_criteria_columns._col_criteria] = CriteriaColumns::TYPE; - iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "URI contains"; - row[_criteria_columns._col_criteria] = CriteriaColumns::URI; - /*iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "Library contains: "; - row[_criteria_columns._col_criteria] = CriteriaColumns::LIBRARY; - iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "Label contains: "; - row[_criteria_columns._col_criteria] = CriteriaColumns::LABEL;*/ - - _clear_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::clear_clicked)); - _add_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::add_clicked)); - //m_close_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::close_clicked)); - //m_add_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::ok_clicked)); - _plugins_treeview->signal_row_activated().connect(sigc::mem_fun(this, &LoadPluginWindow::plugin_activated)); - _search_entry->signal_activate().connect( sigc::mem_fun(this, &LoadPluginWindow::add_clicked)); - _search_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::filter_changed)); - _node_name_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::name_changed)); - - _selection = _plugins_treeview->get_selection(); - _selection->signal_changed().connect(sigc::mem_fun(this, &LoadPluginWindow::plugin_selection_changed)); - - //m_add_button->grab_default(); -} - - -void -LoadPluginWindow::present(SharedPtr patch, MetadataMap data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - - -/** Called every time the user types into the name input box. - * Used to display warning messages, and enable/disable the OK button. - */ -void -LoadPluginWindow::name_changed() -{ - string name = _node_name_entry->get_text(); - if (!Path::is_valid_name(name)) { - //m_message_label->set_text("Name contains invalid characters."); - _add_button->property_sensitive() = false; - } else if (_patch->get_node(name)) { - //m_message_label->set_text("An object already exists with that name."); - _add_button->property_sensitive() = false; - } else if (name.length() == 0) { - //m_message_label->set_text(""); - _add_button->property_sensitive() = false; - } else { - //m_message_label->set_text(""); - _add_button->property_sensitive() = true; - } -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadPluginWindow::set_patch(SharedPtr patch) -{ - _patch = patch; - - if (patch->poly() <= 1) - _polyphonic_checkbutton->property_sensitive() = false; - else - _polyphonic_checkbutton->property_sensitive() = true; - -} - - -/** Populates the plugin list on the first show. - * - * This is done here instead of construction time as the list population is - * really expensive and bogs down creation of a patch. This is especially - * important when many patch notifications are sent at one time from the - * engine. - */ -void -LoadPluginWindow::on_show() -{ - if (!_has_shown) { - set_plugin_list(App::instance().store()->plugins()); - - // Center on patch window - /*int _w, _h; - get_size(_w, _h); - - int parent_x, parent_y, parent_w, parent_h; - _patch_controller->window()->get_position(parent_x, parent_y); - _patch_controller->window()->get_size(parent_w, parent_h); - - move(parent_x + parent_w/2 - _w/2, parent_y + parent_h/2 - _h/2); - */ - _has_shown = true; - } - Gtk::Window::on_show(); -} - - -int -LoadPluginWindow::plugin_compare(const Gtk::TreeModel::iterator& a_i, - const Gtk::TreeModel::iterator& b_i) -{ - SharedPtr a = a_i->get_value(_plugins_columns._col_plugin_model); - SharedPtr b = b_i->get_value(_plugins_columns._col_plugin_model); - - // FIXME: haaack - if (!a && !b) - return 0; - else if (!a) - return 1; - else if (!b) - return -1; - - if (a->type() == b->type()) - return strcmp(a->name().c_str(), b->name().c_str()); - else - return ((int)a->type() < (int)b->type()) ? -1 : 1; -} - - -void -LoadPluginWindow::set_plugin_list(const std::map >& m) -{ - _plugins_liststore->clear(); - - for (std::map >::const_iterator i = m.begin(); i != m.end(); ++i) { - SharedPtr plugin = (*i).second; - - Gtk::TreeModel::iterator iter = _plugins_liststore->append(); - Gtk::TreeModel::Row row = *iter; - - row[_plugins_columns._col_name] = plugin->name(); - //row[_plugins_columns._col_label] = plugin->plug_label(); - if (plugin->type_uri() == "ingen:Internal") - row[_plugins_columns._col_type] = "Internal"; - else if (plugin->type_uri() == "ingen:LV2") - row[_plugins_columns._col_type] = "LV2"; - else if (plugin->type_uri() == "ingen:DSSI") - row[_plugins_columns._col_type] = "DSSI"; - else if (plugin->type_uri() == "ingen:LADSPA") - row[_plugins_columns._col_type] = "LADSPA"; - else - row[_plugins_columns._col_type] = plugin->type_uri(); - row[_plugins_columns._col_uri] = plugin->uri(); - row[_plugins_columns._col_label] = plugin->name(); - //row[_plugins_columns._col_library] = plugin->lib_name(); - row[_plugins_columns._col_plugin_model] = plugin; - } - - _plugins_liststore->set_sort_column(Gtk::TreeSortable::DEFAULT_SORT_COLUMN_ID, Gtk::SORT_ASCENDING); - - _plugins_treeview->columns_autosize(); -} - - -void -LoadPluginWindow::add_plugin(SharedPtr plugin) -{ - Gtk::TreeModel::iterator iter = _plugins_liststore->append(); - Gtk::TreeModel::Row row = *iter; - - row[_plugins_columns._col_name] = plugin->name(); - //row[_plugins_columns._col_label] = plugin->plug_label(); - row[_plugins_columns._col_type] = plugin->type_uri(); - row[_plugins_columns._col_uri] = plugin->uri(); - row[_plugins_columns._col_label] = plugin->name(); - //row[_plugins_columns._col_library] = plugin->lib_name(); - row[_plugins_columns._col_plugin_model] = plugin; -} - - - -///// Event Handlers ////// - - -void -LoadPluginWindow::plugin_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col) -{ - add_clicked(); -} - - -void -LoadPluginWindow::plugin_selection_changed() -{ - _plugin_name_offset = 0; - - _node_name_entry->set_text(generate_module_name()); - - //Gtk::TreeModel::iterator iter = _selection->get_selected(); - //Gtk::TreeModel::Row row = *iter; - //const PluginModel* plugin = row.get_value(_plugins_columns._col_plugin_model); -} - - -/** Generate an automatic name for this Node. - * - * Offset is an offset of the number that will be appended to the plugin's - * label, needed if the user adds multiple plugins faster than the engine - * sends the notification back. - */ -string -LoadPluginWindow::generate_module_name(int offset) -{ - string name = ""; - - Gtk::TreeModel::iterator iter = _selection->get_selected(); - - if (iter) { - Gtk::TreeModel::Row row = *iter; - SharedPtr plugin = row.get_value(_plugins_columns._col_plugin_model); - return plugin->default_node_name(_patch); - } - /*char num_buf[3]; - for (uint i=0; i < 99; ++i) { - name = plugin->default_node_name(); - if (name == "") - name = plugin->name().substr(0, plugin->name().find(' ')); - if (i+offset != 0) { - snprintf(num_buf, 3, "%d", i+offset+1); - name += "_"; - name += num_buf; - } - if (!_patch->get_node(name)) - break; - else - name = ""; - } - }*/ - - return name; -} - - -void -LoadPluginWindow::add_clicked() -{ - Gtk::TreeModel::iterator iter = _selection->get_selected(); - bool polyphonic = _polyphonic_checkbutton->get_active(); - - if (iter) { // If anything is selected - Gtk::TreeModel::Row row = *iter; - SharedPtr plugin = row.get_value(_plugins_columns._col_plugin_model); - string name = _node_name_entry->get_text(); - if (name == "") { - name = generate_module_name(); - } - if (name == "") { - Gtk::MessageDialog dialog(*this, - "Unable to chose a default name for this node. Please enter a name.", - false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - - dialog.run(); - } else { - Path path = _patch->path().base() + Path::nameify(name); - App::instance().engine()->create_node(plugin->uri(), path, polyphonic); - for (MetadataMap::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) - App::instance().engine()->set_metadata(path, i->first, i->second); - ++_plugin_name_offset; - _node_name_entry->set_text(generate_module_name(_plugin_name_offset)); - - // Set the next module location 20 over, for a cascade effect - cerr << "FIXME: cascade\n"; - //m_new_module_x += 20; - //m_new_module_y += 20; - } - } -} - - -/* -void -LoadPluginWindow::close_clicked() -{ - hide(); -} - - -void -LoadPluginWindow::ok_clicked() -{ - add_clicked(); - close_clicked(); -} -*/ - -void -LoadPluginWindow::filter_changed() -{ - _plugins_liststore->clear(); - - string search = _search_entry->get_text(); - transform(search.begin(), search.end(), search.begin(), toupper); - - // Get selected criteria - const Gtk::TreeModel::Row row = *(_filter_combo->get_active()); - CriteriaColumns::Criteria criteria = row[_criteria_columns._col_criteria]; - - string field; - - Gtk::TreeModel::Row model_row; - Gtk::TreeModel::iterator model_iter; - size_t num_visible = 0; - - - for (std::map >::const_iterator i = App::instance().store()->plugins().begin(); - i != App::instance().store()->plugins().end(); ++i) { - - const SharedPtr plugin = (*i).second; - - switch (criteria) { - case CriteriaColumns::NAME: - field = plugin->name(); break; - case CriteriaColumns::TYPE: - field = plugin->type_uri(); break; - case CriteriaColumns::URI: - field = plugin->uri(); break; - /*case CriteriaColumns::LIBRARY: - field = plugin->lib_name(); break; - case CriteriaColumns::LABEL: - field = plugin->plug_label(); break;*/ - default: - throw; - } - - transform(field.begin(), field.end(), field.begin(), toupper); - - if (field.find(search) != string::npos) { - model_iter = _plugins_liststore->append(); - model_row = *model_iter; - - model_row[_plugins_columns._col_name] = plugin->name(); - //model_row[_plugins_columns._col_label] = plugin->plug_label(); - model_row[_plugins_columns._col_type] = plugin->type_uri(); - model_row[_plugins_columns._col_uri] = plugin->uri(); - model_row[_plugins_columns._col_plugin_model] = plugin; - - ++num_visible; - } - } - - if (num_visible == 1) { - _selection->unselect_all(); - _selection->select(model_iter); - } -} - - -void -LoadPluginWindow::clear_clicked() -{ - _search_entry->set_text(""); - set_plugin_list(App::instance().store()->plugins()); -} - -bool -LoadPluginWindow::on_key_press_event(GdkEventKey* event) -{ - if (event->keyval == GDK_w && event->state & GDK_CONTROL_MASK) { - hide(); - return true; - } else { - return Gtk::Window::on_key_press_event(event); - } -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/LoadPluginWindow.h b/src/progs/ingenuity/LoadPluginWindow.h deleted file mode 100644 index 7bfb63e1..00000000 --- a/src/progs/ingenuity/LoadPluginWindow.h +++ /dev/null @@ -1,149 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef LOADPLUGINWINDOW_H -#define LOADPLUGINWINDOW_H - -#include -#include -#include -#include -#include -#include "client/PatchModel.h" -#include "client/PluginModel.h" -using Ingen::Client::PluginModel; -using Ingen::Client::PatchModel; -using Ingen::Client::MetadataMap; - -namespace Ingenuity { - - -// Gtkmm _really_ needs to add some helper to abstract away this stupid nonsense - -/** Columns for the plugin list in the load plugin window. - * - * \ingroup Ingenuity - */ -class ModelColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - ModelColumns() { - add(_col_name); - add(_col_type); - add(_col_uri); - add(_col_label); - //add(_col_library); - //add(_col_label); - add(_col_plugin_model); - } - - Gtk::TreeModelColumn _col_name; - Gtk::TreeModelColumn _col_type; - Gtk::TreeModelColumn _col_uri; - - // Not displayed: - Gtk::TreeModelColumn _col_label; - Gtk::TreeModelColumn > _col_plugin_model; -}; - - -/** Column for the criteria combo box in the load plugin window. - * - * \ingroup Ingenuity - */ -class CriteriaColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - enum Criteria { NAME, TYPE, URI, }; - - CriteriaColumns() { add(_col_label); add(_col_criteria); } - - Gtk::TreeModelColumn _col_label; - Gtk::TreeModelColumn _col_criteria; -}; - - -/** 'Load Plugin' window. - * - * Loaded by glade as a derived object. - * - * \ingroup Ingenuity - */ -class LoadPluginWindow : public Gtk::Window -{ -public: - LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void set_patch(SharedPtr patch); - void set_plugin_list(const std::map >& m); - - void add_plugin(SharedPtr plugin); - bool has_shown() const { return _has_shown; } - - void present(SharedPtr patch, MetadataMap data); - -protected: - void on_show(); - bool on_key_press_event(GdkEventKey* event); - -private: - void add_clicked(); - //void close_clicked(); - //void ok_clicked(); - void filter_changed(); - void clear_clicked(); - void name_changed(); - - int plugin_compare(const Gtk::TreeModel::iterator& a, - const Gtk::TreeModel::iterator& b); - - void plugin_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col); - void plugin_selection_changed(); - string generate_module_name(int offset = 0); - - MetadataMap _initial_data; - - SharedPtr _patch; - - bool _has_shown; // plugin list only populated on show to speed patch window creation - - Glib::RefPtr _plugins_liststore; - ModelColumns _plugins_columns; - - Glib::RefPtr _criteria_liststore; - CriteriaColumns _criteria_columns; - - Glib::RefPtr _selection; - - int _plugin_name_offset; // see comments for generate_plugin_name - - Gtk::TreeView* _plugins_treeview; - Gtk::CheckButton* _polyphonic_checkbutton; - Gtk::Entry* _node_name_entry; - Gtk::Button* _clear_button; - Gtk::Button* _add_button; - //Gtk::Button* _close_button; - //Gtk::Button* _ok_button; - Gtk::ComboBox* _filter_combo; - Gtk::Entry* _search_entry; -}; - - -} // namespace Ingenuity - -#endif // LOADPLUGINWINDOW_H diff --git a/src/progs/ingenuity/LoadRemotePatchWindow.cpp b/src/progs/ingenuity/LoadRemotePatchWindow.cpp deleted file mode 100644 index f42c0849..00000000 --- a/src/progs/ingenuity/LoadRemotePatchWindow.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "LoadRemotePatchWindow.h" -#include -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "App.h" -#include "Configuration.h" -#include "ThreadedLoader.h" - -using boost::optional; -using namespace Raul; - -namespace Ingenuity { - - -LoadRemotePatchWindow::LoadRemotePatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::Dialog(cobject), - _replace(true) -{ - xml->get_widget("load_remote_patch_treeview", _treeview); - xml->get_widget("load_remote_patch_uri_entry", _uri_entry); - xml->get_widget("load_remote_patch_cancel_button", _cancel_button); - xml->get_widget("load_remote_patch_open_button", _open_button); - - _liststore = Gtk::ListStore::create(_columns); - _treeview->set_model(_liststore); - _treeview->append_column("Name", _columns._col_name); - _treeview->append_column("URI", _columns._col_uri); - - _selection = _treeview->get_selection(); - _selection->signal_changed().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::patch_selected)); - _treeview->signal_row_activated().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::patch_activated)); - - _open_button->signal_clicked().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::open_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::cancel_clicked)); - _uri_entry->signal_changed().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::uri_changed)); -} - - -void -LoadRemotePatchWindow::present(SharedPtr patch, MetadataMap data) -{ - _liststore->clear(); - - set_patch(patch); - _initial_data = data; - - RDF::Model model(*App::instance().rdf_world(), - "http://rdf.drobilla.net/ingen_patches/index.ttl", - "http://rdf.drobilla.net/ingen_patches/"); - - RDF::Query query(*App::instance().rdf_world(), Glib::ustring( - "SELECT DISTINCT ?name ?uri WHERE {" - " ?uri a ingen:Patch ;" - " doap:name ?name ." - "}")); - - RDF::Query::Results results = query.run(*App::instance().rdf_world(), model); - - for (RDF::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - Gtk::TreeModel::iterator iter = _liststore->append(); - (*iter)[_columns._col_name] = (*i)["name"].to_string(); - (*iter)[_columns._col_uri] = (*i)["uri"].to_string(); - } - - _treeview->columns_autosize(); - - Gtk::Window::present(); -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadRemotePatchWindow::set_patch(SharedPtr patch) -{ - _patch = patch; -} - - -void -LoadRemotePatchWindow::uri_changed() -{ - _open_button->property_sensitive() = (_uri_entry->get_text().length() > 0); -} - - -void -LoadRemotePatchWindow::patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col) -{ - open_clicked(); -} - - -void -LoadRemotePatchWindow::patch_selected() -{ - Gtk::TreeModel::iterator selected_i = _selection->get_selected(); - - if (selected_i) { // If anything is selected - const Glib::ustring uri = selected_i->get_value(_columns._col_uri); - _uri_entry->set_text(uri); - } -} - - -void -LoadRemotePatchWindow::open_clicked() -{ - Glib::ustring uri = _uri_entry->get_text(); - - cerr << "OPEN URI: " << uri << endl; - - // If unset load_patch will load values - optional name; - optional poly; - - optional parent; - - if (_replace) - App::instance().engine()->clear_patch(_patch->path()); - - if (_patch->path() != "/") - parent = _patch->path().parent(); - - App::instance().loader()->load_patch(true, uri, "/", - _initial_data, parent, name, poly); - - hide(); -} - - -void -LoadRemotePatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/LoadRemotePatchWindow.h b/src/progs/ingenuity/LoadRemotePatchWindow.h deleted file mode 100644 index 5a9de63a..00000000 --- a/src/progs/ingenuity/LoadRemotePatchWindow.h +++ /dev/null @@ -1,91 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADREMOTEPATCHWINDOW_H -#define LOADREMOTEPATCHWINDOW_H - -#include -#include -#include -#include "client/PatchModel.h" -#include "client/PluginModel.h" -using Ingen::Client::PatchModel; -using Ingen::Client::MetadataMap; - -namespace Ingenuity { - - -/** Columns for the remote patch list. - * - * \ingroup Ingenuity - */ -class PatchColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - PatchColumns() { - add(_col_name); - add(_col_uri); - } - - Gtk::TreeModelColumn _col_name; - Gtk::TreeModelColumn _col_uri; -}; - - - -/* Load remote patch ("import location") dialog. - * - * \ingroup Ingenuity - */ -class LoadRemotePatchWindow : public Gtk::Dialog -{ -public: - LoadRemotePatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void set_patch(SharedPtr patch); - - void set_replace() { _replace = true; } - void set_merge() { _replace = false; } - - void present(SharedPtr patch, MetadataMap data); - -private: - void patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col); - void patch_selected(); - void uri_changed(); - void open_clicked(); - void cancel_clicked(); - - MetadataMap _initial_data; - - SharedPtr _patch; - bool _replace; - - Glib::RefPtr _selection; - Glib::RefPtr _liststore; - PatchColumns _columns; - - Gtk::TreeView* _treeview; - Gtk::Entry* _uri_entry; - Gtk::Button* _open_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace Ingenuity - -#endif // LOADREMOTEPATCHWINDOW_H diff --git a/src/progs/ingenuity/LoadSubpatchWindow.cpp b/src/progs/ingenuity/LoadSubpatchWindow.cpp deleted file mode 100644 index d1f4b953..00000000 --- a/src/progs/ingenuity/LoadSubpatchWindow.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/NodeModel.h" -#include "client/PatchModel.h" -#include "App.h" -#include "LoadSubpatchWindow.h" -#include "PatchView.h" -#include "Configuration.h" -#include "ThreadedLoader.h" -using boost::optional; - -namespace Ingenuity { - - -LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::FileChooserDialog(cobject) -{ - xml->get_widget("load_subpatch_name_from_file_radio", _name_from_file_radio); - xml->get_widget("load_subpatch_name_from_user_radio", _name_from_user_radio); - xml->get_widget("load_subpatch_name_entry", _name_entry); - xml->get_widget("load_subpatch_poly_from_file_radio", _poly_from_file_radio); - xml->get_widget("load_subpatch_poly_from_parent_radio", _poly_from_parent_radio); - xml->get_widget("load_subpatch_poly_from_user_radio", _poly_from_user_radio); - xml->get_widget("load_subpatch_poly_spinbutton", _poly_spinbutton); - xml->get_widget("load_subpatch_ok_button", _ok_button); - xml->get_widget("load_subpatch_cancel_button", _cancel_button); - - _name_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_name_entry)); - _name_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_name_entry)); - _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); - _poly_from_parent_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); - _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_poly_spinner)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::ok_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::cancel_clicked)); - - Gtk::FileFilter filt; - filt.add_pattern("*.om"); - filt.set_name("Om patch files (XML, DEPRECATED) (*.om)"); - filt.add_pattern("*.ingen.ttl"); - filt.set_name("Ingen patch files (RDF, *.ingen.ttl)"); - set_filter(filt); - - // Add global examples directory to "shortcut folders" (bookmarks) - string examples_dir = PKGDATADIR; - examples_dir.append("/patches"); - DIR* d = opendir(examples_dir.c_str()); - if (d != NULL) - add_shortcut_folder(examples_dir); -} - - -void -LoadSubpatchWindow::present(SharedPtr patch, MetadataMap data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadSubpatchWindow::set_patch(SharedPtr patch) -{ - _patch = patch; - - char temp_buf[4]; - snprintf(temp_buf, 4, "%zd", patch->poly()); - Glib::ustring txt = "Same as parent ("; - txt.append(temp_buf).append(")"); - _poly_from_parent_radio->set_label(txt); -} - - -void -LoadSubpatchWindow::on_show() -{ - if (App::instance().configuration()->patch_folder().length() > 0) - set_current_folder(App::instance().configuration()->patch_folder()); - Gtk::FileChooserDialog::on_show(); -} - - -///// Event Handlers ////// - - - -void -LoadSubpatchWindow::disable_name_entry() -{ - _name_entry->property_sensitive() = false; -} - - -void -LoadSubpatchWindow::enable_name_entry() -{ - _name_entry->property_sensitive() = true; -} - - -void -LoadSubpatchWindow::disable_poly_spinner() -{ - _poly_spinbutton->property_sensitive() = false; -} - - -void -LoadSubpatchWindow::enable_poly_spinner() -{ - _poly_spinbutton->property_sensitive() = true; -} - - -void -LoadSubpatchWindow::ok_clicked() -{ - assert(_patch); - - // If unset load_patch will load values - optional name; - optional poly; - string name_str = ""; - - if (_name_from_user_radio->get_active()) { - name_str = _name_entry->get_text(); - name = name_str; - } - - if (_poly_from_user_radio->get_active()) - poly = _poly_spinbutton->get_value_as_int(); - else if (_poly_from_parent_radio->get_active()) - poly = _patch->poly(); - - App::instance().loader()->load_patch(false, get_uri(), "/", - _initial_data, _patch->path(), name, poly); - - hide(); -} - - -void -LoadSubpatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/LoadSubpatchWindow.h b/src/progs/ingenuity/LoadSubpatchWindow.h deleted file mode 100644 index 54693504..00000000 --- a/src/progs/ingenuity/LoadSubpatchWindow.h +++ /dev/null @@ -1,77 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADSUBPATCHWINDOW_H -#define LOADSUBPATCHWINDOW_H - -#include -#include -#include -#include "client/PatchModel.h" -#include "client/PluginModel.h" -using Ingen::Client::PatchModel; -using Ingen::Client::MetadataMap; - -namespace Ingenuity { - - -/** 'Add Subpatch' window. - * - * Loaded by glade as a derived object. - * - * \ingroup Ingenuity - */ -class LoadSubpatchWindow : public Gtk::FileChooserDialog -{ -public: - LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void set_patch(SharedPtr patch); - - void present(SharedPtr patch, MetadataMap data); - -protected: - void on_show(); - -private: - void disable_name_entry(); - void enable_name_entry(); - void disable_poly_spinner(); - void enable_poly_spinner(); - - void ok_clicked(); - void cancel_clicked(); - - MetadataMap _initial_data; - - SharedPtr _patch; - - Gtk::RadioButton* _name_from_file_radio; - Gtk::RadioButton* _name_from_user_radio; - Gtk::Entry* _name_entry; - Gtk::RadioButton* _poly_from_file_radio; - Gtk::RadioButton* _poly_from_parent_radio; - Gtk::RadioButton* _poly_from_user_radio; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace Ingenuity - -#endif // LOADSUBPATCHWINDOW_H diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am deleted file mode 100644 index 82d96b15..00000000 --- a/src/progs/ingenuity/Makefile.am +++ /dev/null @@ -1,98 +0,0 @@ -if BUILD_GTK_CLIENT - -EXTRA_DIST = ingenuity.gladep ingenuity_dev -MAINTAINERCLEANFILES = Makefile.in - -sharefilesdir = $(pkgdatadir) -dist_sharefiles_DATA = ingenuity.glade ingen.svg - -desktopfilesdir = $(datadir)/applications -dist_desktopfiles_DATA = ingenuity.desktop - -globalpixmapsdir = $(datadir)/pixmaps -dist_globalpixmaps_DATA = ingen.svg - -ingenuity_CXXFLAGS = -DGTK_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs -DPKGDATADIR=\"$(pkgdatadir)\" @RAUL_CFLAGS@ @GTKMM_CFLAGS@ @LIBGLADEMM_CFLAGS@ @GNOMECANVASMM_CFLAGS@ @LOSC_CFLAGS@ @LASH_CFLAGS@ @FLOWCANVAS_CFLAGS@ @SLV2_CFLAGS@ @CURL_CFLAGS@ -DINGEN_MODULE_DIR=\"$(libdir)/ingen\" -ingenuity_LDADD = @RAUL_LIBS@ @GTKMM_LIBS@ @LIBGLADEMM_LIBS@ @GNOMECANVASMM_LIBS@ @LOSC_LIBS@ @LASH_LIBS@ @FLOWCANVAS_LIBS@ @SLV2_LIBS@ @CURL_LIBS@ ../../libs/client/libingen_client.la ../../libs/module/libingen_module.la -ingenuity_DEPENDENCIES = ../../libs/client/libingen_client.la ../../libs/module/libingen_module.la - -bin_PROGRAMS = ingenuity -ingenuity_SOURCES = \ - cmdline.h \ - cmdline.c \ - main.cpp \ - NodeMenu.h \ - NodeMenu.cpp \ - PatchCanvas.h \ - PatchCanvas.cpp \ - BreadCrumb.h \ - BreadCrumbBox.h \ - BreadCrumbBox.cpp \ - ConnectWindow.h \ - ConnectWindow.cpp \ - App.h \ - App.cpp \ - Configuration.h \ - Configuration.cpp \ - GladeFactory.h \ - GladeFactory.cpp \ - LoadPluginWindow.h \ - LoadPluginWindow.cpp \ - LoadPatchWindow.h \ - LoadPatchWindow.cpp \ - LoadRemotePatchWindow.h \ - LoadRemotePatchWindow.cpp \ - UploadPatchWindow.h \ - UploadPatchWindow.cpp \ - MessagesWindow.h \ - MessagesWindow.cpp \ - LoadSubpatchWindow.h \ - LoadSubpatchWindow.cpp \ - NodeControlWindow.h \ - NodeControlWindow.cpp \ - ControlPanel.h \ - ControlPanel.cpp \ - ControlGroups.h \ - ControlGroups.cpp \ - PatchView.h \ - PatchView.cpp \ - PatchWindow.h \ - PatchWindow.cpp \ - WindowFactory.h \ - WindowFactory.cpp \ - NodeModule.h \ - NodeModule.cpp \ - PatchPortModule.h \ - PatchPortModule.cpp \ - DSSIModule.h \ - DSSIModule.cpp \ - DSSIController.h \ - DSSIController.cpp \ - SubpatchModule.h \ - SubpatchModule.cpp \ - Port.h \ - Port.cpp \ - Connection.h \ - NewSubpatchWindow.h \ - NewSubpatchWindow.cpp \ - ConfigWindow.h \ - ConfigWindow.cpp \ - PatchPropertiesWindow.h \ - PatchPropertiesWindow.cpp \ - ThreadedLoader.h \ - ThreadedLoader.cpp \ - RenameWindow.h \ - RenameWindow.cpp \ - NodePropertiesWindow.h \ - NodePropertiesWindow.cpp \ - PortPropertiesWindow.h \ - PortPropertiesWindow.cpp \ - PatchTreeWindow.h \ - PatchTreeWindow.cpp - -if WITH_LASH -ingenuity_SOURCES += LashController.h LashController.cpp -endif - - -endif # WITH_GTK_CLIENT diff --git a/src/progs/ingenuity/MessagesWindow.cpp b/src/progs/ingenuity/MessagesWindow.cpp deleted file mode 100644 index 6f54ac57..00000000 --- a/src/progs/ingenuity/MessagesWindow.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "MessagesWindow.h" -#include - -namespace Ingenuity { -using std::string; - - -MessagesWindow::MessagesWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("messages_textview", _textview); - glade_xml->get_widget("messages_clear_button", _clear_button); - glade_xml->get_widget("messages_close_button", _close_button); - - _clear_button->signal_clicked().connect(sigc::mem_fun(this, &MessagesWindow::clear_clicked)); - _close_button->signal_clicked().connect(sigc::mem_fun(this, &MessagesWindow::close_clicked)); -} - - -void -MessagesWindow::post(const string& msg) -{ - Glib::RefPtr text_buf = _textview->get_buffer(); - text_buf->insert(text_buf->end(), msg); - text_buf->insert(text_buf->end(), "\n"); - - if (!_clear_button->is_sensitive()) - _clear_button->set_sensitive(true); -} - - -void -MessagesWindow::close_clicked() -{ - hide(); -} - - -void -MessagesWindow::clear_clicked() -{ - Glib::RefPtr text_buf = _textview->get_buffer(); - text_buf->erase(text_buf->begin(), text_buf->end()); - _clear_button->set_sensitive(false); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/MessagesWindow.h b/src/progs/ingenuity/MessagesWindow.h deleted file mode 100644 index 642b63c6..00000000 --- a/src/progs/ingenuity/MessagesWindow.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MESSAGESWINDOW_H -#define MESSAGESWINDOW_H - -#include -#include -#include -using std::string; - - -namespace Ingenuity { - - -/** Messages Window. - * - * Loaded by libglade as a derived object. - * This is shown when errors occur (ie during patch loading). - * - * \ingroup Ingenuity - */ -class MessagesWindow : public Gtk::Window -{ -public: - MessagesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - - void post(const string& str); - -private: - void clear_clicked(); - void close_clicked(); - - Gtk::TextView* _textview; - Gtk::Button* _clear_button; - Gtk::Button* _close_button; -}; - - -} // namespace Ingenuity - -#endif // MESSAGESWINDOW_H diff --git a/src/progs/ingenuity/NewSubpatchWindow.cpp b/src/progs/ingenuity/NewSubpatchWindow.cpp deleted file mode 100644 index e49340b8..00000000 --- a/src/progs/ingenuity/NewSubpatchWindow.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "App.h" -#include "interface/EngineInterface.h" -#include "client/NodeModel.h" -#include "client/PatchModel.h" -#include "NewSubpatchWindow.h" -#include "PatchView.h" - -namespace Ingenuity { - - -NewSubpatchWindow::NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::Window(cobject) -{ - xml->get_widget("new_subpatch_name_entry", _name_entry); - xml->get_widget("new_subpatch_message_label", _message_label); - xml->get_widget("new_subpatch_polyphony_spinbutton", _poly_spinbutton); - xml->get_widget("new_subpatch_ok_button", _ok_button); - xml->get_widget("new_subpatch_cancel_button", _cancel_button); - - _name_entry->signal_changed().connect(sigc::mem_fun(this, &NewSubpatchWindow::name_changed)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &NewSubpatchWindow::ok_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &NewSubpatchWindow::cancel_clicked)); - - _ok_button->property_sensitive() = false; -} - -void -NewSubpatchWindow::present(SharedPtr patch, MetadataMap data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -NewSubpatchWindow::set_patch(SharedPtr patch) -{ - _patch = patch; -} - - -/** Called every time the user types into the name input box. - * Used to display warning messages, and enable/disable the OK button. - */ -void -NewSubpatchWindow::name_changed() -{ - string name = _name_entry->get_text(); - if (!Path::is_valid_name(name)) { - _message_label->set_text("Name contains invalid characters."); - _ok_button->property_sensitive() = false; - } else if (_patch->get_node(name)) { - _message_label->set_text("An object already exists with that name."); - _ok_button->property_sensitive() = false; - } else if (name.length() == 0) { - _message_label->set_text(""); - _ok_button->property_sensitive() = false; - } else { - _message_label->set_text(""); - _ok_button->property_sensitive() = true; - } -} - - -void -NewSubpatchWindow::ok_clicked() -{ - const Path path = _patch->path().base() + Path::nameify(_name_entry->get_text()); - const size_t poly = _poly_spinbutton->get_value_as_int(); - - App::instance().engine()->create_patch(path, poly); - for (MetadataMap::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) - App::instance().engine()->set_metadata(path, i->first, i->second); - - App::instance().engine()->enable_patch(path); - - hide(); -} - - -void -NewSubpatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/NewSubpatchWindow.h b/src/progs/ingenuity/NewSubpatchWindow.h deleted file mode 100644 index 28730137..00000000 --- a/src/progs/ingenuity/NewSubpatchWindow.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NEWSUBPATCHWINDOW_H -#define NEWSUBPATCHWINDOW_H - -#include -#include -#include -#include "client/PatchModel.h" -#include "client/PluginModel.h" -using Ingen::Client::PatchModel; -using Ingen::Client::MetadataMap; - -namespace Ingenuity { - - -/** 'New Subpatch' window. - * - * Loaded by glade as a derived object. - * - * \ingroup Ingenuity - */ -class NewSubpatchWindow : public Gtk::Window -{ -public: - NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void set_patch(SharedPtr patch); - - void present(SharedPtr patch, MetadataMap data); - -private: - void name_changed(); - void ok_clicked(); - void cancel_clicked(); - - MetadataMap _initial_data; - SharedPtr _patch; - - Gtk::Entry* _name_entry; - Gtk::Label* _message_label; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace Ingenuity - -#endif // NEWSUBPATCHWINDOW_H diff --git a/src/progs/ingenuity/NodeControlWindow.cpp b/src/progs/ingenuity/NodeControlWindow.cpp deleted file mode 100644 index 8d324a65..00000000 --- a/src/progs/ingenuity/NodeControlWindow.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License alongCont - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/NodeModel.h" -#include "App.h" -#include "NodeControlWindow.h" -#include "GladeFactory.h" -#include "ControlGroups.h" -#include "ControlPanel.h" -#include "PatchWindow.h" - -using namespace std; - -namespace Ingenuity { - - -/** Create a node control window and load a new ControlPanel for it. - */ -NodeControlWindow::NodeControlWindow(SharedPtr node, size_t poly) -: _node(node), - _position_stored(false), - _x(0), _y(0) -{ - assert(_node != NULL); - - property_resizable() = true; - set_border_width(5); - - set_title(_node->path() + " Controls"); - - Glib::RefPtr xml = GladeFactory::new_glade_reference("warehouse_win"); - xml->get_widget_derived("control_panel_vbox", _control_panel); - _control_panel->reparent(*this); - - _control_panel->init(_node, poly); - - show_all_children(); - resize(); - - _callback_enabled = true; -} - - -/** Create a node control window and with an existing ControlPanel. - */ -NodeControlWindow::NodeControlWindow(SharedPtr node, ControlPanel* panel) -: _node(node), - _control_panel(panel) -{ - assert(_node); - - property_resizable() = true; - set_border_width(5); - - set_title(_node->path() + " Controls"); - - _control_panel->reparent(*this); - - show_all_children(); - resize(); - - _callback_enabled = true; -} - - -NodeControlWindow::~NodeControlWindow() -{ - delete _control_panel; -} - - -void -NodeControlWindow::resize() -{ - pair controls_size = _control_panel->ideal_size(); - /*int width = 400; - int height = controls_size.second - + ((_node->polyphonic()) ? 4 : 40);*/ - int width = controls_size.first; - int height = controls_size.second; - - if (height > property_screen().get_value()->get_height() - 64) - height = property_screen().get_value()->get_height() - 64; - if (width > property_screen().get_value()->get_width() - 64) - width = property_screen().get_value()->get_width() - 64; - - //cerr << "Resizing to: " << width << " x " << height << endl; - - Gtk::Window::resize(width, height); -} - - -void -NodeControlWindow::on_show() -{ - for (PortModelList::const_iterator i = _node->ports().begin(); - i != _node->ports().end(); ++i) - if ((*i)->is_control() && (*i)->is_input()) - App::instance().engine()->request_port_value((*i)->path()); - - if (_position_stored) - move(_x, _y); - - Gtk::Window::on_show(); -} - - -void -NodeControlWindow::on_hide() -{ - _position_stored = true; - get_position(_x, _y); - Gtk::Window::on_hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/NodeControlWindow.h b/src/progs/ingenuity/NodeControlWindow.h deleted file mode 100644 index 62ab497d..00000000 --- a/src/progs/ingenuity/NodeControlWindow.h +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODECONTROLWINDOW_H -#define NODECONTROLWINDOW_H - -#include -#include -#include -#include -#include -#include -using std::string; using std::vector; - -namespace Ingen { namespace Client { - class NodeModel; -} } -using Ingen::Client::NodeModel; - -namespace Ingenuity { - -class ControlGroup; -class ControlPanel; - - -/** Window with controls (sliders) for all control-rate ports on a Node. - * - * \ingroup Ingenuity - */ -class NodeControlWindow : public Gtk::Window -{ -public: - NodeControlWindow(SharedPtr node, size_t poly); - NodeControlWindow(SharedPtr node, ControlPanel* panel); - virtual ~NodeControlWindow(); - - SharedPtr node() { return _node; } - - ControlPanel* control_panel() const { return _control_panel; } - - void resize(); - -protected: - void on_show(); - void on_hide(); - -private: - SharedPtr _node; - ControlPanel* _control_panel; - bool _callback_enabled; - - bool _position_stored; - int _x; - int _y; -}; - - -} // namespace Ingenuity - -#endif // NODECONTROLWINDOW_H diff --git a/src/progs/ingenuity/NodeMenu.cpp b/src/progs/ingenuity/NodeMenu.cpp deleted file mode 100644 index a0efe441..00000000 --- a/src/progs/ingenuity/NodeMenu.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/NodeModel.h" -#include "App.h" -#include "NodeMenu.h" -#include "WindowFactory.h" - -using std::cerr; using std::endl; - -namespace Ingenuity { - - -NodeMenu::NodeMenu(SharedPtr node) -: _node(node) -, _controls_menuitem(NULL) -{ - App& app = App::instance(); - - Gtk::Menu_Helpers::MenuElem controls_elem = Gtk::Menu_Helpers::MenuElem("Controls", - sigc::bind( - sigc::mem_fun(app.window_factory(), &WindowFactory::present_controls), - node)); - _controls_menuitem = controls_elem.get_child(); - items().push_back(controls_elem); - - items().push_back(Gtk::Menu_Helpers::SeparatorElem()); - - /*items().push_back(Gtk::Menu_Helpers::MenuElem("Rename...", - sigc::bind( - sigc::mem_fun(app.window_factory(), &WindowFactory::present_rename), - node)));*/ - /*items().push_back(Gtk::Menu_Helpers::MenuElem("Clone", - sigc::bind( - sigc::mem_fun(app.engine(), &EngineInterface::clone), - node))); - sigc::mem_fun(this, &NodeMenu::on_menu_clone)));*/ - - items().push_back(Gtk::Menu_Helpers::MenuElem("Disconnect All", - sigc::mem_fun(this, &NodeMenu::on_menu_disconnect_all))); - - items().push_back(Gtk::Menu_Helpers::MenuElem("Destroy", - sigc::mem_fun(this, &NodeMenu::on_menu_destroy))); - - //m_controls_menuitem->property_sensitive() = false; - - cerr << "FIXME: MIDI learn menu\n"; - /* - if (_node->plugin() && _node->plugin()->type() == PluginModel::Internal - && _node->plugin()->plug_label() == "midi_control_in") { - items().push_back(Gtk::Menu_Helpers::MenuElem("Learn", - sigc::mem_fun(this, &NodeMenu::on_menu_learn))); - } - */ - - items().push_back(Gtk::Menu_Helpers::SeparatorElem()); - - items().push_back(Gtk::Menu_Helpers::MenuElem("Properties", - sigc::bind( - sigc::mem_fun(app.window_factory(), &WindowFactory::present_properties), - node))); - - //model->new_port_sig.connect(sigc::mem_fun(this, &NodeMenu::add_port)); - //model->destroyed_sig.connect(sigc::mem_fun(this, &NodeMenu::destroy)); -} - -#if 0 -NodeMenu::~NodeMenu() -{ - cerr << "~NodeMenu()\n"; -} - -void -NodeMenu::destroy() -{ - cerr << "FIXME: NODE DESTROYED\n"; - //SharedPtr model = _model; - //m_model.reset(); -} -#endif - -void -NodeMenu::set_path(const Path& new_path) -{ - cerr << "FIXME: rename\n"; - /* - remove_from_store(); - - // Rename ports - for (list::const_iterator i = _node->ports().begin(); - i != _node->ports().end(); ++i) { - ObjectController* const pc = (*i)->controller(); - assert(pc != NULL); - pc->set_path(_model->path().base() + pc->model()->name()); - } - - // Handle bridge port, if this node represents one - if (_bridge_port != NULL) - _bridge_port->set_path(new_path); - - if (_module != NULL) - _module->canvas()->rename_module(_node->path().name(), new_path.name()); - - ObjectController::set_path(new_path); - - add_to_store(); - */ -} - -#if 0 -void -NodeMenu::destroy() -{ - PatchController* pc = ((PatchController*)_model->parent()->controller()); - assert(pc != NULL); - - //remove_from_store(); - //pc->remove_node(_model->path().name()); - cerr << "FIXME: remove node\n"; - - if (_bridge_port != NULL) - _bridge_port->destroy(); - _bridge_port = NULL; - - //if (_module != NULL) - // delete _module; -} -#endif - -#if 0 -void -NodeMenu::add_port(SharedPtr pm) -{ - assert(pm->parent().get() == _node.get()); - assert(pm->parent() == _node); - assert(_node->get_port(pm->path().name()) == pm); - - //cout << "[NodeMenu] Adding port " << pm->path() << endl; - - /* - if (_module != NULL) { - // (formerly PortController) - pc->create_port(_module); - _module->resize(); - - // Enable "Controls" menu item on module - if (has_control_inputs()) - enable_controls_menuitem(); - }*/ -} -#endif - -void -NodeMenu::on_menu_destroy() -{ - App::instance().engine()->destroy(_node->path()); -} - - -void -NodeMenu::on_menu_clone() -{ - cerr << "FIXME: clone broken\n"; - /* - assert(_node); - //assert(_parent != NULL); - //assert(_parent->model() != NULL); - - string clone_name = _node->name(); - int i = 2; // postfix number (ie oldname_2) - - // Check if name already has a number postfix - if (clone_name.find_last_of("_") != string::npos) { - string name_postfix = clone_name.substr(clone_name.find_last_of("_")+1); - clone_name = clone_name.substr(0, clone_name.find_last_of("_")); - if (sscanf(name_postfix.c_str(), "%d", &i)) - ++i; - } - - char clone_postfix[4]; - for ( ; i < 100; ++i) { - snprintf(clone_postfix, 4, "_%d", i); - if (_node->parent_patch()->get_node(clone_name + clone_postfix) == NULL) - break; - } - - clone_name = clone_name + clone_postfix; - - const string path = _node->parent_patch()->base() + clone_name; - NodeModel* nm = new NodeModel(_node->plugin(), path); - nm->polyphonic(_node->polyphonic()); - nm->x(_node->x() + 20); - nm->y(_node->y() + 20); - App::instance().engine()->create_node_from_model(nm); - */ -} - - -void -NodeMenu::on_menu_learn() -{ - App::instance().engine()->midi_learn(_node->path()); -} - -void -NodeMenu::on_menu_disconnect_all() -{ - App::instance().engine()->disconnect_all(_node->path()); -} - - -bool -NodeMenu::has_control_inputs() -{ - for (PortModelList::const_iterator i = _node->ports().begin(); - i != _node->ports().end(); ++i) - if ((*i)->is_input() && (*i)->is_control()) - return true; - - return false; -} - - -void -NodeMenu::enable_controls_menuitem() -{ - _controls_menuitem->property_sensitive() = true; -} - - -void -NodeMenu::disable_controls_menuitem() -{ - _controls_menuitem->property_sensitive() = false; - - //if (_control_window != NULL) - // _control_window->hide(); -} - - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/NodeMenu.h b/src/progs/ingenuity/NodeMenu.h deleted file mode 100644 index d6f598ad..00000000 --- a/src/progs/ingenuity/NodeMenu.h +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEMENU_H -#define NODEMENU_H - -#include -#include -#include -#include -#include "client/NodeModel.h" -using Ingen::Client::NodeModel; - -using std::string; - -namespace Ingenuity { - -class Controller; -class NodeControlWindow; -class NodePropertiesWindow; -class PatchCanvas; - -/** Controller for a Node. - * - * \ingroup Ingenuity - */ -class NodeMenu : public Gtk::Menu -{ -public: - NodeMenu(SharedPtr node); - - void set_path(const Path& new_path); - - virtual void program_add(int bank, int program, const string& name) {} - virtual void program_remove(int bank, int program) {} - - bool has_control_inputs(); - - //virtual void show_menu(GdkEventButton* event) - //{ _menu.popup(event->button, event->time); } - -protected: - - virtual void enable_controls_menuitem(); - virtual void disable_controls_menuitem(); - - //virtual void add_port(SharedPtr pm); - - void on_menu_destroy(); - void on_menu_clone(); - void on_menu_learn(); - void on_menu_disconnect_all(); - - //Gtk::Menu _menu; - SharedPtr _node; - Glib::RefPtr _controls_menuitem; -}; - - -} // namespace Ingenuity - -#endif // NODEMENU_H diff --git a/src/progs/ingenuity/NodeModule.cpp b/src/progs/ingenuity/NodeModule.cpp deleted file mode 100644 index dd03fde8..00000000 --- a/src/progs/ingenuity/NodeModule.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "client/NodeModel.h" -#include "App.h" -#include "NodeModule.h" -#include "PatchCanvas.h" -#include "Port.h" -#include "GladeFactory.h" -#include "RenameWindow.h" -#include "PatchWindow.h" -#include "WindowFactory.h" -#include "SubpatchModule.h" -#include "NodeControlWindow.h" - -namespace Ingenuity { - - -NodeModule::NodeModule(boost::shared_ptr canvas, SharedPtr node) -: LibFlowCanvas::Module(canvas, node->path().name()), - _node(node), - _menu(node) -{ - assert(_node); - - if (node->polyphonic()) { - set_border_width(2.0); - } - - node->new_port_sig.connect(sigc::bind(sigc::mem_fun(this, &NodeModule::add_port), true)); - node->removed_port_sig.connect(sigc::mem_fun(this, &NodeModule::remove_port)); - node->metadata_update_sig.connect(sigc::mem_fun(this, &NodeModule::metadata_update)); - - signal_clicked.connect(sigc::mem_fun(this, &NodeModule::on_click)); -} - - -NodeModule::~NodeModule() -{ - NodeControlWindow* win = App::instance().window_factory()->control_window(_node); - - if (win) { - // Should remove from window factory via signal - delete win; - } -} - - -boost::shared_ptr -NodeModule::create(boost::shared_ptr canvas, SharedPtr node) -{ - boost::shared_ptr ret; - - SharedPtr patch = PtrCast(node); - if (patch) - ret = boost::shared_ptr(new SubpatchModule(canvas, patch)); - else - ret = boost::shared_ptr(new NodeModule(canvas, node)); - - for (MetadataMap::const_iterator m = node->metadata().begin(); m != node->metadata().end(); ++m) - ret->metadata_update(m->first, m->second); - - for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) - ret->add_port(*p, false); - - ret->resize(); - - return ret; -} - - -void -NodeModule::add_port(SharedPtr port, bool resize_to_fit) -{ - Module::add_port(boost::shared_ptr(new Port( - PtrCast(shared_from_this()), port))); - - if (resize_to_fit) - resize(); -} - - -void -NodeModule::remove_port(SharedPtr port) -{ - SharedPtr p = Module::remove_port(port->path().name()); - p.reset(); -} - - -void -NodeModule::show_control_window() -{ - App::instance().window_factory()->present_controls(_node); -} - - -void -NodeModule::store_location() -{ - const float x = static_cast(property_x()); - const float y = static_cast(property_y()); - - const Atom& existing_x = _node->get_metadata("ingenuity:canvas-x"); - const Atom& existing_y = _node->get_metadata("ingenuity:canvas-y"); - - if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT - || existing_x.get_float() != x || existing_y.get_float() != y) { - App::instance().engine()->set_metadata(_node->path(), "ingenuity:canvas-x", Atom(x)); - App::instance().engine()->set_metadata(_node->path(), "ingenuity:canvas-y", Atom(y)); - } -} - - -void -NodeModule::on_click(GdkEventButton* event) -{ - if (event->button == 3) - _menu.popup(event->button, event->time); -} - - -void -NodeModule::metadata_update(const string& key, const Atom& value) -{ - if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT) - move_to(value.get_float(), property_y()); - else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT) - move_to(property_x(), value.get_float()); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/NodeModule.h b/src/progs/ingenuity/NodeModule.h deleted file mode 100644 index d87bcfcc..00000000 --- a/src/progs/ingenuity/NodeModule.h +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of In* Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEMODULE_H -#define NODEMODULE_H - -#include -#include -#include -#include -#include "Port.h" -#include "NodeMenu.h" -using std::string; - -class Atom; - -namespace Ingen { namespace Client { - class PortModel; - class NodeModel; - class ControlModel; -} } -using namespace Ingen::Client; - -namespace Ingenuity { - -class PatchCanvas; -class Port; - - -/** A module in a patch. - * - * This base class is extended for various types of modules - SubpatchModule, - * DSSIModule, etc. - * - * \ingroup Ingenuity - */ -class NodeModule : public LibFlowCanvas::Module -{ -public: - static boost::shared_ptr create (boost::shared_ptr canvas, SharedPtr node); - - virtual ~NodeModule(); - - boost::shared_ptr port(const string& port_name) { - return boost::dynamic_pointer_cast( - Module::get_port(port_name)); - } - - virtual void store_location(); - - void on_click(GdkEventButton* event); - - void show_control_window(); - - SharedPtr node() const { return _node; } - -protected: - NodeModule(boost::shared_ptr canvas, SharedPtr node); - - virtual void on_double_click(GdkEventButton* ev) { show_control_window(); } - virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); } - - void metadata_update(const string& key, const Atom& value); - - void add_port(SharedPtr port, bool resize=true); - void remove_port(SharedPtr port); - - SharedPtr _node; - NodeMenu _menu; -}; - - -} // namespace Ingenuity - -#endif // NODEMODULE_H diff --git a/src/progs/ingenuity/NodePropertiesWindow.cpp b/src/progs/ingenuity/NodePropertiesWindow.cpp deleted file mode 100644 index 428119a3..00000000 --- a/src/progs/ingenuity/NodePropertiesWindow.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "client/NodeModel.h" -#include "client/PluginModel.h" -#include "NodePropertiesWindow.h" - -namespace Ingenuity { -using std::string; - - -NodePropertiesWindow::NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("node_properties_path_label", _node_path_label); - glade_xml->get_widget("node_properties_polyphonic_checkbutton", _node_polyphonic_toggle); - glade_xml->get_widget("node_properties_plugin_type_label", _plugin_type_label); - glade_xml->get_widget("node_properties_plugin_uri_label", _plugin_uri_label); - glade_xml->get_widget("node_properties_plugin_name_label", _plugin_name_label); -} - - -/** Set the node this window is associated with. - * This function MUST be called before using this object in any way. - */ -void -NodePropertiesWindow::set_node(SharedPtr node_model) -{ - assert(node_model); - - _node_model = node_model; - - set_title(node_model->path() + " Properties"); - - _node_path_label->set_text(node_model->path()); - _node_polyphonic_toggle->set_active(node_model->polyphonic()); - - SharedPtr pm = node_model->plugin(); - - if (pm) { - _plugin_type_label->set_text(pm->type_uri()); - _plugin_uri_label->set_text(pm->uri()); - _plugin_name_label->set_text(pm->name()); - } -} - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/NodePropertiesWindow.h b/src/progs/ingenuity/NodePropertiesWindow.h deleted file mode 100644 index eae9bfdc..00000000 --- a/src/progs/ingenuity/NodePropertiesWindow.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEPROPERTIESWINDOW_H -#define NODEPROPERTIESWINDOW_H - -#include -#include -#include -#include "client/NodeModel.h" -using namespace Ingen::Client; - -namespace Ingenuity { - - -/** Node properties window. - * - * Loaded by libglade as a derived object. - * - * \ingroup Ingenuity - */ -class NodePropertiesWindow : public Gtk::Window -{ -public: - NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - - void present(SharedPtr node_model) { set_node(node_model); Gtk::Window::present(); } - void set_node(SharedPtr node_model); - -private: - - SharedPtr _node_model; - Gtk::Label* _node_path_label; - Gtk::CheckButton* _node_polyphonic_toggle; - Gtk::Label* _plugin_type_label; - Gtk::Label* _plugin_uri_label; - Gtk::Label* _plugin_name_label; -}; - -} // namespace Ingenuity - -#endif // NODEPROPERTIESWINDOW_H diff --git a/src/progs/ingenuity/PatchCanvas.cpp b/src/progs/ingenuity/PatchCanvas.cpp deleted file mode 100644 index e6397a3d..00000000 --- a/src/progs/ingenuity/PatchCanvas.cpp +++ /dev/null @@ -1,523 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/PluginModel.h" -#include "client/PatchModel.h" -#include "client/NodeModel.h" -#include "client/Store.h" -#include "client/Serializer.h" -#include "App.h" -#include "PatchCanvas.h" -#include "PatchWindow.h" -#include "PatchPortModule.h" -#include "LoadPluginWindow.h" -#include "LoadSubpatchWindow.h" -#include "NewSubpatchWindow.h" -#include "Port.h" -#include "Connection.h" -#include "NodeModule.h" -#include "SubpatchModule.h" -#include "GladeFactory.h" -#include "WindowFactory.h" -#include "config.h" -using Ingen::Client::Store; -using Ingen::Client::Serializer; -using Ingen::Client::PluginModel; - -namespace Ingenuity { - - -PatchCanvas::PatchCanvas(SharedPtr patch, int width, int height) -: FlowCanvas(width, height), - _patch(patch), - _last_click_x(0), - _last_click_y(0) -{ - Glib::RefPtr xml = GladeFactory::new_glade_reference(); - xml->get_widget("canvas_menu", _menu); - - xml->get_widget("canvas_menu_add_audio_input", _menu_add_audio_input); - xml->get_widget("canvas_menu_add_audio_output", _menu_add_audio_output); - xml->get_widget("canvas_menu_add_control_input", _menu_add_control_input); - xml->get_widget("canvas_menu_add_control_output", _menu_add_control_output); - xml->get_widget("canvas_menu_add_midi_input", _menu_add_midi_input); - xml->get_widget("canvas_menu_add_midi_output", _menu_add_midi_output); - xml->get_widget("canvas_menu_load_plugin", _menu_load_plugin); - xml->get_widget("canvas_menu_load_patch", _menu_load_patch); - xml->get_widget("canvas_menu_new_patch", _menu_new_patch); - - // Add port menu items - _menu_add_audio_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "audio_input", "ingen:audio", false)); - _menu_add_audio_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "audio_output", "ingen:audio", true)); - _menu_add_control_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "control_input", "ingen:control", false)); - _menu_add_control_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "control_output", "ingen:control", true)); - _menu_add_midi_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "midi_input", "ingen:midi", false)); - _menu_add_midi_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "midi_output", "ingen:midi", true)); - - build_plugin_menu(); - - // Connect to model signals to track state - _patch->new_node_sig.connect(sigc::mem_fun(this, &PatchCanvas::add_node)); - _patch->removed_node_sig.connect(sigc::mem_fun(this, &PatchCanvas::remove_node)); - _patch->new_port_sig.connect(sigc::mem_fun(this, &PatchCanvas::add_port)); - _patch->removed_port_sig.connect(sigc::mem_fun(this, &PatchCanvas::remove_port)); - _patch->new_connection_sig.connect(sigc::mem_fun(this, &PatchCanvas::connection)); - _patch->removed_connection_sig.connect(sigc::mem_fun(this, &PatchCanvas::disconnection)); - - // Connect widget signals to do things - _menu_load_plugin->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_load_plugin)); - _menu_load_patch->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_load_patch)); - _menu_new_patch->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_new_patch)); -} - - -void -PatchCanvas::build_plugin_class_menu(Gtk::Menu* menu, - SLV2PluginClass plugin_class, SLV2PluginClasses classes) -{ -#ifdef HAVE_SLV2 - // Add submenus - for (unsigned i=0; i < slv2_plugin_classes_size(classes); ++i) { - SLV2PluginClass c = slv2_plugin_classes_get_at(classes, i); - const char* parent = slv2_plugin_class_get_parent_uri(c); - - if (parent && !strcmp(parent, slv2_plugin_class_get_uri(plugin_class))) { - menu->items().push_back(Gtk::Menu_Helpers::MenuElem( - slv2_plugin_class_get_label(c))); - Gtk::MenuItem* menu_item = &(menu->items().back()); - Gtk::Menu* submenu = Gtk::manage(new Gtk::Menu()); - menu_item->set_submenu(*submenu); - build_plugin_class_menu(submenu, c, classes); - } - } - - - const Store::Plugins& plugins = App::instance().store()->plugins(); - - // Add plugins - for (Store::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) { - SLV2Plugin p = i->second->slv2_plugin(); - if (p && slv2_plugin_get_class(p) == plugin_class) - menu->items().push_back(Gtk::Menu_Helpers::MenuElem(i->second->name(), - sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), - i->second))); - } - - -#endif -} - - -void -PatchCanvas::build_plugin_menu() -{ -#ifdef HAVE_SLV2 - _menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem("Plugin", - *(manage(new Gtk::Image(Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU))))); - Gtk::MenuItem* plugin_menu_item = &(_menu->items().back()); - Gtk::Menu* plugin_menu = Gtk::manage(new Gtk::Menu()); - plugin_menu_item->set_submenu(*plugin_menu); - _menu->reorder_child(*plugin_menu_item, 2); - - SLV2PluginClass lv2_plugin = slv2_world_get_plugin_class(PluginModel::slv2_world()); - SLV2PluginClasses classes = slv2_world_get_plugin_classes(PluginModel::slv2_world()); - - build_plugin_class_menu(plugin_menu, lv2_plugin, classes); -#endif -} - - -void -PatchCanvas::build() -{ - boost::shared_ptr shared_this = - boost::dynamic_pointer_cast(shared_from_this()); - - // Create modules for nodes - for (NodeModelMap::const_iterator i = _patch->nodes().begin(); - i != _patch->nodes().end(); ++i) { - add_node((*i).second); - } - - // Create pseudo modules for ports (ports on this canvas, not on our module) - for (PortModelList::const_iterator i = _patch->ports().begin(); - i != _patch->ports().end(); ++i) { - add_port(*i); - } - - // Create connections - for (list >::const_iterator i = _patch->connections().begin(); - i != _patch->connections().end(); ++i) { - connection(*i); - } -} - - -void -PatchCanvas::arrange() -{ - LibFlowCanvas::FlowCanvas::arrange(); - - for (list >::iterator i = _items.begin(); i != _items.end(); ++i) - (*i)->store_location(); -} - - -void -PatchCanvas::add_node(SharedPtr nm) -{ - boost::shared_ptr shared_this = - boost::dynamic_pointer_cast(shared_from_this()); - - SharedPtr pm = PtrCast(nm); - SharedPtr module; - if (pm) - module = SubpatchModule::create(shared_this, pm); - else - module = NodeModule::create(shared_this, nm); - - add_item(module); - module->show(); - _views.insert(std::make_pair(nm, module)); -} - - -void -PatchCanvas::remove_node(SharedPtr nm) -{ - Views::iterator i = _views.find(nm); - - if (i != _views.end()) { - remove_item(i->second); - _views.erase(i); - } -} - - -void -PatchCanvas::add_port(SharedPtr pm) -{ - boost::shared_ptr shared_this = - boost::dynamic_pointer_cast(shared_from_this()); - - SharedPtr view = PatchPortModule::create(shared_this, pm); - _views.insert(std::make_pair(pm, view)); - add_item(view); - view->show(); -} - - -void -PatchCanvas::remove_port(SharedPtr pm) -{ - Views::iterator i = _views.find(pm); - - if (i != _views.end()) { - remove_item(i->second); - _views.erase(i); - } -} - - -SharedPtr -PatchCanvas::get_port_view(SharedPtr port) -{ - SharedPtr ret; - SharedPtr module = _views[port]; - - // Port on this patch - if (module) { - ret = (PtrCast(module)) - ? *(PtrCast(module)->ports().begin()) - : PtrCast(module); - } else { - module = PtrCast(_views[port->parent()]); - if (module) - ret = module->get_port(port->path().name()); - } - - return ret; -} - - -void -PatchCanvas::connection(SharedPtr cm) -{ - const SharedPtr src = get_port_view(cm->src_port()); - const SharedPtr dst = get_port_view(cm->dst_port()); - - if (src && dst) - add_connection(boost::shared_ptr(new Connection(shared_from_this(), - cm, src, dst, src->color() + 0x22222200))); - else - cerr << "[PatchCanvas] ERROR: Unable to find ports to connect " - << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; -} - - -void -PatchCanvas::disconnection(SharedPtr cm) -{ - const SharedPtr src = get_port_view(cm->src_port()); - const SharedPtr dst = get_port_view(cm->dst_port()); - - if (src && dst) - remove_connection(src, dst); - else - cerr << "[PatchCanvas] ERROR: Unable to find ports to disconnect " - << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; -} - - -void -PatchCanvas::connect(boost::shared_ptr src_port, - boost::shared_ptr dst_port) -{ - const boost::shared_ptr src - = boost::dynamic_pointer_cast(src_port); - - const boost::shared_ptr dst - = boost::dynamic_pointer_cast(dst_port); - - if (!src || !dst) - return; - - // Midi binding/learn shortcut - if (src->model()->is_midi() && dst->model()->is_control()) - { - cerr << "FIXME: MIDI binding" << endl; -#if 0 - SharedPtr pm(new PluginModel(PluginModel::Internal, "", "midi_control_in", "")); - SharedPtr nm(new NodeModel(pm, _patch->path().base() - + src->name() + "-" + dst->name(), false)); - nm->set_metadata("canvas-x", Atom((float) - (dst->module()->property_x() - dst->module()->width() - 20))); - nm->set_metadata("canvas-y", Atom((float) - (dst->module()->property_y()))); - App::instance().engine()->create_node_from_model(nm.get()); - App::instance().engine()->connect(src->model()->path(), nm->path() + "/MIDI_In"); - App::instance().engine()->connect(nm->path() + "/Out_(CR)", dst->model()->path()); - App::instance().engine()->midi_learn(nm->path()); - - // Set control node range to port's user range - - App::instance().engine()->set_port_value_queued(nm->path().base() + "Min", - dst->model()->get_metadata("user-min").get_float()); - App::instance().engine()->set_port_value_queued(nm->path().base() + "Max", - dst->model()->get_metadata("user-max").get_float()); -#endif - } else { - App::instance().engine()->connect(src->model()->path(), dst->model()->path()); - } -} - - -void -PatchCanvas::disconnect(boost::shared_ptr src_port, - boost::shared_ptr dst_port) -{ - const boost::shared_ptr src - = boost::dynamic_pointer_cast(src_port); - - const boost::shared_ptr dst - = boost::dynamic_pointer_cast(dst_port); - - App::instance().engine()->disconnect(src->model()->path(), - dst->model()->path()); -} - - -bool -PatchCanvas::canvas_event(GdkEvent* event) -{ - assert(event); - - switch (event->type) { - - case GDK_BUTTON_PRESS: - if (event->button.button == 3) { - _last_click_x = (int)event->button.x; - _last_click_y = (int)event->button.y; - show_menu(event); - } - break; - - /*case GDK_KEY_PRESS: - if (event->key.keyval == GDK_Delete) - destroy_selected(); - break; - */ - - default: - break; - } - - return FlowCanvas::canvas_event(event); -} - - -void -PatchCanvas::destroy_selection() -{ - for (list >::iterator m = _selected_items.begin(); m != _selected_items.end(); ++m) { - boost::shared_ptr module = boost::dynamic_pointer_cast(*m); - if (module) { - App::instance().engine()->destroy(module->node()->path()); - } else { - boost::shared_ptr port_module = boost::dynamic_pointer_cast(*m); - if (port_module) - App::instance().engine()->destroy(port_module->port()->path()); - } - } - -} - - -void -PatchCanvas::copy_selection() -{ - Serializer serializer(*App::instance().rdf_world()); - serializer.start_to_string(); - - for (list >::iterator m = _selected_items.begin(); m != _selected_items.end(); ++m) { - boost::shared_ptr module = boost::dynamic_pointer_cast(*m); - if (module) { - serializer.serialize(module->node()); - } else { - boost::shared_ptr port_module = boost::dynamic_pointer_cast(*m); - if (port_module) - serializer.serialize(port_module->port()); - } - } - - for (list >::iterator c = _selected_connections.begin(); - c != _selected_connections.end(); ++c) { - boost::shared_ptr connection = boost::dynamic_pointer_cast(*c); - if (connection) - serializer.serialize_connection(connection->model()); - } - - string result = serializer.finish(); - - Glib::RefPtr clipboard = Gtk::Clipboard::get(); - clipboard->set_text(result); -} - - -string -PatchCanvas::generate_port_name(const string& base) { - string name = base; - - char num_buf[5]; - for (uint i=1; i < 9999; ++i) { - snprintf(num_buf, 5, "%u", i); - name = base + "_"; - name += num_buf; - if (!_patch->get_port(name)) - break; - } - - assert(Path::is_valid(string("/") + name)); - - return name; -} - - -void -PatchCanvas::menu_add_port(const string& name, const string& type, bool is_output) -{ - const Path& path = _patch->path().base() + generate_port_name(name); - App::instance().engine()->create_port(path, type, is_output); - MetadataMap data = get_initial_data(); - for (MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i) - App::instance().engine()->set_metadata(path, i->first, i->second); -} - - -void -PatchCanvas::load_plugin(SharedPtr plugin) -{ - const Path& path = _patch->path().base() + plugin->default_node_name(_patch); - // FIXME: polyphony? - App::instance().engine()->create_node(plugin->uri(), path, false); - MetadataMap data = get_initial_data(); - for (MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i) - App::instance().engine()->set_metadata(path, i->first, i->second); -} - - -/** Try to guess a suitable location for a new module. - */ -void -PatchCanvas::get_new_module_location(double& x, double& y) -{ - int scroll_x; - int scroll_y; - get_scroll_offsets(scroll_x, scroll_y); - x = scroll_x + 20; - y = scroll_y + 20; -} - - -MetadataMap -PatchCanvas::get_initial_data() -{ - MetadataMap result; - - result["ingenuity:canvas-x"] = Atom((float)_last_click_x); - result["ingenuity:canvas-y"] = Atom((float)_last_click_y); - - return result; -} - -void -PatchCanvas::menu_load_plugin() -{ - App::instance().window_factory()->present_load_plugin(_patch, get_initial_data()); -} - - -void -PatchCanvas::menu_load_patch() -{ - App::instance().window_factory()->present_load_subpatch(_patch, get_initial_data()); -} - - -void -PatchCanvas::menu_new_patch() -{ - App::instance().window_factory()->present_new_subpatch(_patch, get_initial_data()); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchCanvas.h b/src/progs/ingenuity/PatchCanvas.h deleted file mode 100644 index 297e9874..00000000 --- a/src/progs/ingenuity/PatchCanvas.h +++ /dev/null @@ -1,127 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHCANVAS_H -#define PATCHCANVAS_H - -#include -#include -#include -#include -#include -#include -#include -#include "client/ConnectionModel.h" -#include "client/PatchModel.h" -#include "NodeModule.h" - -using std::string; -using namespace LibFlowCanvas; - -using LibFlowCanvas::Port; -using Ingen::Client::ConnectionModel; -using Ingen::Client::PatchModel; -using Ingen::Client::NodeModel; -using Ingen::Client::PortModel; -using Ingen::Client::MetadataMap; - -namespace Ingenuity { - -class NodeModule; - - -/** Patch canvas widget. - * - * \ingroup Ingenuity - */ -class PatchCanvas : public LibFlowCanvas::FlowCanvas -{ -public: - PatchCanvas(SharedPtr patch, int width, int height); - - virtual ~PatchCanvas() {} - - /*boost::shared_ptr find_module(const string& name) { - return boost::dynamic_pointer_cast( - FlowCanvas::get_item(name)); - }*/ - - void build(); - void arrange(); - - void add_node(SharedPtr nm); - void remove_node(SharedPtr nm); - void add_port(SharedPtr pm); - void remove_port(SharedPtr pm); - void connection(SharedPtr cm); - void disconnection(SharedPtr cm); - - void get_new_module_location(double& x, double& y); - - void destroy_selection(); - void copy_selection(); - - void show_menu(GdkEvent* event) - { _menu->popup(event->button.button, event->button.time); } - -private: - string generate_port_name(const string& base); - void menu_add_port(const string& name, const string& type, bool is_output); - void menu_load_plugin(); - void menu_new_patch(); - void menu_load_patch(); - void load_plugin(SharedPtr plugin); - void build_plugin_menu(); - void build_plugin_class_menu(Gtk::Menu* menu, - SLV2PluginClass plugin_class, SLV2PluginClasses classes); - - MetadataMap get_initial_data(); - - bool canvas_event(GdkEvent* event); - - SharedPtr get_port_view(SharedPtr port); - - void connect(boost::shared_ptr src, - boost::shared_ptr dst); - - void disconnect(boost::shared_ptr src, - boost::shared_ptr dst); - - SharedPtr _patch; - - typedef std::map, SharedPtr > Views; - Views _views; - - int _last_click_x; - int _last_click_y; - - Gtk::Menu* _menu; - Gtk::MenuItem* _menu_add_audio_input; - Gtk::MenuItem* _menu_add_audio_output; - Gtk::MenuItem* _menu_add_control_input; - Gtk::MenuItem* _menu_add_control_output; - Gtk::MenuItem* _menu_add_midi_input; - Gtk::MenuItem* _menu_add_midi_output; - Gtk::MenuItem* _menu_load_plugin; - Gtk::MenuItem* _menu_load_patch; - Gtk::MenuItem* _menu_new_patch; -}; - - -} // namespace Ingenuity - -#endif // PATCHCANVAS_H diff --git a/src/progs/ingenuity/PatchPortModule.cpp b/src/progs/ingenuity/PatchPortModule.cpp deleted file mode 100644 index 08e7dbbd..00000000 --- a/src/progs/ingenuity/PatchPortModule.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "PatchPortModule.h" -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "client/NodeModel.h" -#include "App.h" -#include "PatchCanvas.h" -#include "Port.h" -#include "GladeFactory.h" -#include "RenameWindow.h" -#include "PatchWindow.h" - -namespace Ingenuity { - - -PatchPortModule::PatchPortModule(boost::shared_ptr canvas, SharedPtr port) -: LibFlowCanvas::Module(canvas, port->path().name(), 0, 0, false), // FIXME: coords? - _port(port) -{ - /*if (port_model()->polyphonic() && port_model()->parent() != NULL - && port_model()->parent_patch()->poly() > 1) { - border_width(2.0); - }*/ - - assert(canvas); - assert(port); - - assert(PtrCast(port->parent())); - - /*resize(); - - const Atom& x_atom = port->get_metadata("ingenuity:canvas-x"); - const Atom& y_atom = port->get_metadata("ingenuity:canvas-y"); - - if (x_atom && y_atom && x_atom.type() == Atom::FLOAT && y_atom.type() == Atom::FLOAT) { - move_to(x_atom.get_float(), y_atom.get_float()); - } else { - double default_x; - double default_y; - canvas->get_new_module_location(default_x, default_y); - move_to(default_x, default_y); - }*/ - - port->metadata_update_sig.connect(sigc::mem_fun(this, &PatchPortModule::metadata_update)); -} - - -boost::shared_ptr -PatchPortModule::create(boost::shared_ptr canvas, SharedPtr port) -{ - boost::shared_ptr ret = boost::shared_ptr( - new PatchPortModule(canvas, port)); - assert(ret); - - ret->_patch_port = boost::shared_ptr(new Port(ret, port, true, true)); - ret->add_port(ret->_patch_port); - - for (MetadataMap::const_iterator m = port->metadata().begin(); m != port->metadata().end(); ++m) - ret->metadata_update(m->first, m->second); - - ret->resize(); - - return ret; -} - - -void -PatchPortModule::store_location() -{ - const float x = static_cast(property_x()); - const float y = static_cast(property_y()); - - const Atom& existing_x = _port->get_metadata("ingenuity:canvas-x"); - const Atom& existing_y = _port->get_metadata("ingenuity:canvas-y"); - - if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT - || existing_x.get_float() != x || existing_y.get_float() != y) { - App::instance().engine()->set_metadata(_port->path(), "ingenuity:canvas-x", Atom(x)); - App::instance().engine()->set_metadata(_port->path(), "ingenuity:canvas-y", Atom(y)); - } -} - - -void -PatchPortModule::metadata_update(const string& key, const Atom& value) -{ - if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT) - move_to(value.get_float(), property_y()); - else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT) - move_to(property_x(), value.get_float()); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchPortModule.h b/src/progs/ingenuity/PatchPortModule.h deleted file mode 100644 index f42b7592..00000000 --- a/src/progs/ingenuity/PatchPortModule.h +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHPORTMODULE_H -#define PATCHPORTMODULE_H - -#include -#include -#include -#include -#include -#include "Port.h" -using std::string; - -namespace Ingen { namespace Client { - class PortModel; - class NodeModel; - class ControlModel; -} } -using namespace Ingen::Client; - -namespace Ingenuity { - -class PatchCanvas; -class Port; - - -/** A "module" to represent a patch's port on it's own canvas. - * - * Translation: This is the nameless single port pseudo module thingy. - * - * \ingroup Ingenuity - */ -class PatchPortModule : public boost::enable_shared_from_this, - public LibFlowCanvas::Module -{ -public: - static boost::shared_ptr create(boost::shared_ptr canvas, - SharedPtr port); - - virtual ~PatchPortModule() {} - - virtual void store_location(); - - //void on_right_click(GdkEventButton* event) { _port->show_menu(event); } - - SharedPtr port() const { return _port; } - -protected: - PatchPortModule(boost::shared_ptr canvas, SharedPtr port); - - //virtual void on_double_click(GdkEventButton* ev) { show_control_window(); } - //virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); } - - void metadata_update(const string& key, const Raul::Atom& value); - - SharedPtr _port; - boost::shared_ptr _patch_port; ///< Port on this 'anonymous' module -}; - - -} // namespace Ingenuity - -#endif // PATCHPORTMODULE_H diff --git a/src/progs/ingenuity/PatchPropertiesWindow.cpp b/src/progs/ingenuity/PatchPropertiesWindow.cpp deleted file mode 100644 index 17b28d34..00000000 --- a/src/progs/ingenuity/PatchPropertiesWindow.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "client/PatchModel.h" -#include "PatchPropertiesWindow.h" - -namespace Ingenuity { -using std::string; - - -PatchPropertiesWindow::PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("properties_author_entry", _author_entry); - glade_xml->get_widget("properties_description_textview", _textview); - glade_xml->get_widget("properties_cancel_button", _cancel_button); - glade_xml->get_widget("properties_ok_button", _ok_button); - - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &PatchPropertiesWindow::cancel_clicked)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &PatchPropertiesWindow::ok_clicked)); -} - - -/** Set the patch model this description is for. - * - * This function is a "post-constructor" - it MUST be called before using - * the window in any way. - */ -void -PatchPropertiesWindow::set_patch(SharedPtr patch_model) -{ - property_title() = patch_model->path() + " Properties"; - _patch_model = patch_model; - - const Atom& author_atom = _patch_model->get_metadata("author"); - _author_entry->set_text( - (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); - - const Atom& desc_atom = _patch_model->get_metadata("description"); - _textview->get_buffer()->set_text( - (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); -} - - -void -PatchPropertiesWindow::cancel_clicked() -{ - const Atom& author_atom = _patch_model->get_metadata("author"); - _author_entry->set_text( - (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); - - const Atom& desc_atom = _patch_model->get_metadata("description"); - _textview->get_buffer()->set_text( - (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); - - hide(); -} - - -void -PatchPropertiesWindow::ok_clicked() -{ - cerr << "FIXME: properties\n"; - - //m_patch_model->set_metadata("author", Atom(_author_entry->get_text().c_str())); - //m_patch_model->set_metadata("description", Atom(_textview->get_buffer()->get_text().c_str())); - hide(); -} - - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchPropertiesWindow.h b/src/progs/ingenuity/PatchPropertiesWindow.h deleted file mode 100644 index 8e461381..00000000 --- a/src/progs/ingenuity/PatchPropertiesWindow.h +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHPROPERTIESWINDOW_H -#define PATCHPROPERTIESWINDOW_H - -#include -#include -#include -#include -using std::string; - -namespace Ingen { namespace Client { class PatchModel; } } -using Ingen::Client::PatchModel; - -namespace Ingenuity { - - -/** Patch Properties Window. - * - * Loaded by libglade as a derived object. - * - * \ingroup Ingenuity - */ -class PatchPropertiesWindow : public Gtk::Window -{ -public: - PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - - void present(SharedPtr patch_model) { set_patch(patch_model); Gtk::Window::present(); } - void set_patch(SharedPtr patch_model); - - void cancel_clicked(); - void ok_clicked(); - -private: - SharedPtr _patch_model; - - Gtk::Entry* _author_entry; - Gtk::TextView* _textview; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; -}; - - -} // namespace Ingenuity - -#endif // PATCHPROPERTIESWINDOW_H diff --git a/src/progs/ingenuity/PatchTreeWindow.cpp b/src/progs/ingenuity/PatchTreeWindow.cpp deleted file mode 100644 index 77caf6dd..00000000 --- a/src/progs/ingenuity/PatchTreeWindow.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "interface/EngineInterface.h" -#include "client/OSCEngineSender.h" -#include "client/Store.h" -#include "client/PatchModel.h" -#include "App.h" -#include "PatchTreeWindow.h" -#include "SubpatchModule.h" -#include "WindowFactory.h" - -namespace Ingenuity { - - -PatchTreeWindow::PatchTreeWindow(BaseObjectType* cobject, - const Glib::RefPtr& xml) -: Gtk::Window(cobject), - _enable_signal(true) -{ - xml->get_widget_derived("patches_treeview", _patches_treeview); - - _patch_treestore = Gtk::TreeStore::create(_patch_tree_columns); - _patches_treeview->set_window(this); - _patches_treeview->set_model(_patch_treestore); - Gtk::TreeViewColumn* name_col = Gtk::manage(new Gtk::TreeViewColumn( - "Patch", _patch_tree_columns.name_col)); - Gtk::TreeViewColumn* enabled_col = Gtk::manage(new Gtk::TreeViewColumn( - "Run", _patch_tree_columns.enabled_col)); - name_col->set_resizable(true); - name_col->set_expand(true); - - _patches_treeview->append_column(*name_col); - _patches_treeview->append_column(*enabled_col); - Gtk::CellRendererToggle* enabled_renderer = dynamic_cast( - _patches_treeview->get_column_cell_renderer(1)); - enabled_renderer->property_activatable() = true; - - _patch_tree_selection = _patches_treeview->get_selection(); - - //m_patch_tree_selection->signal_changed().connect( - // sigc::mem_fun(this, &PatchTreeWindow::event_patch_selected)); - _patches_treeview->signal_row_activated().connect( - sigc::mem_fun(this, &PatchTreeWindow::event_patch_activated)); - enabled_renderer->signal_toggled().connect( - sigc::mem_fun(this, &PatchTreeWindow::event_patch_enabled_toggled)); - - _patches_treeview->columns_autosize(); -} - - -void -PatchTreeWindow::init(Store& store) -{ - store.new_object_sig.connect(sigc::mem_fun(this, &PatchTreeWindow::new_object)); -} - - -void -PatchTreeWindow::new_object(SharedPtr object) -{ - SharedPtr patch = PtrCast(object); - if (patch) - add_patch(patch); -} - - -void -PatchTreeWindow::add_patch(SharedPtr pm) -{ - if (!pm->parent()) { - Gtk::TreeModel::iterator iter = _patch_treestore->append(); - Gtk::TreeModel::Row row = *iter; - if (pm->path() == "/") { - SharedPtr osc_sender = PtrCast(App::instance().engine()); - string root_name = osc_sender ? osc_sender->engine_url() : "Internal"; - // Hack off trailing '/' if it's there (ugly) - //if (root_name.substr(root_name.length()-1,1) == "/") - // root_name = root_name.substr(0, root_name.length()-1); - //root_name.append(":/"); - row[_patch_tree_columns.name_col] = root_name; - } else { - row[_patch_tree_columns.name_col] = pm->path().name(); - } - row[_patch_tree_columns.enabled_col] = false; - row[_patch_tree_columns.patch_model_col] = pm; - _patches_treeview->expand_row(_patch_treestore->get_path(iter), true); - } else { - Gtk::TreeModel::Children children = _patch_treestore->children(); - Gtk::TreeModel::iterator c = find_patch(children, pm->parent()->path()); - - if (c != children.end()) { - Gtk::TreeModel::iterator iter = _patch_treestore->append(c->children()); - Gtk::TreeModel::Row row = *iter; - row[_patch_tree_columns.name_col] = pm->path().name(); - row[_patch_tree_columns.enabled_col] = false; - row[_patch_tree_columns.patch_model_col] = pm; - _patches_treeview->expand_row(_patch_treestore->get_path(iter), true); - } - } - - pm->enabled_sig.connect(sigc::bind(sigc::mem_fun(this, &PatchTreeWindow::patch_enabled), pm->path())); - pm->disabled_sig.connect(sigc::bind(sigc::mem_fun(this, &PatchTreeWindow::patch_disabled), pm->path())); -} - - -void -PatchTreeWindow::remove_patch(const Path& path) -{ - Gtk::TreeModel::iterator i = find_patch(_patch_treestore->children(), path); - if (i != _patch_treestore->children().end()) - _patch_treestore->erase(i); -} - - -Gtk::TreeModel::iterator -PatchTreeWindow::find_patch(Gtk::TreeModel::Children root, const Path& path) -{ - for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { - SharedPtr pm = (*c)[_patch_tree_columns.patch_model_col]; - if (pm->path() == path) { - return c; - } else if ((*c)->children().size() > 0) { - Gtk::TreeModel::iterator ret = find_patch(c->children(), path); - if (ret != c->children().end()) - return ret; - } - } - return root.end(); -} - -/* -void -PatchTreeWindow::event_patch_selected() -{ - Gtk::TreeModel::iterator active = _patch_tree_selection->get_selected(); - if (active) { - Gtk::TreeModel::Row row = *active; - SharedPtr pm = row[_patch_tree_columns.patch_model_col]; - } -} -*/ - - -/** Show the context menu for the selected patch in the patches treeview. - */ -void -PatchTreeWindow::show_patch_menu(GdkEventButton* ev) -{ - Gtk::TreeModel::iterator active = _patch_tree_selection->get_selected(); - if (active) { - Gtk::TreeModel::Row row = *active; - SharedPtr pm = row[_patch_tree_columns.patch_model_col]; - if (pm) - cerr << "FIXME: patch menu\n"; - //pm->show_menu(ev); - } -} - - -void -PatchTreeWindow::event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col) -{ - Gtk::TreeModel::iterator active = _patch_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; - SharedPtr pm = row[_patch_tree_columns.patch_model_col]; - - App::instance().window_factory()->present_patch(pm); -} - - -void -PatchTreeWindow::event_patch_enabled_toggled(const Glib::ustring& path_str) -{ - Gtk::TreeModel::Path path(path_str); - Gtk::TreeModel::iterator active = _patch_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; - - SharedPtr pm = row[_patch_tree_columns.patch_model_col]; - Glib::ustring patch_path = pm->path(); - - assert(pm); - - if ( ! pm->enabled()) { - if (_enable_signal) - App::instance().engine()->enable_patch(patch_path); - //row[_patch_tree_columns.enabled_col] = true; - } else { - if (_enable_signal) - App::instance().engine()->disable_patch(patch_path); - //row[_patch_tree_columns.enabled_col] = false; - } -} - - -void -PatchTreeWindow::patch_enabled(const Path& path) -{ - _enable_signal = false; - - Gtk::TreeModel::iterator i - = find_patch(_patch_treestore->children(), path); - - if (i != _patch_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; - row[_patch_tree_columns.enabled_col] = true; - } else { - cerr << "[PatchTreeWindow] Unable to find patch " << path << endl; - } - - _enable_signal = true; -} - - -void -PatchTreeWindow::patch_disabled(const Path& path) -{ - _enable_signal = false; - - Gtk::TreeModel::iterator i - = find_patch(_patch_treestore->children(), path); - - if (i != _patch_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; - row[_patch_tree_columns.enabled_col] = false; - } else { - cerr << "[PatchTreeWindow] Unable to find patch " << path << endl; - } - - _enable_signal = true; -} - - -void -PatchTreeWindow::patch_renamed(const Path& old_path, const Path& new_path) -{ - _enable_signal = false; - - Gtk::TreeModel::iterator i - = find_patch(_patch_treestore->children(), old_path); - - if (i != _patch_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; - row[_patch_tree_columns.name_col] = new_path.name(); - } else { - cerr << "[PatchTreeWindow] Unable to find patch " << old_path << endl; - } - - _enable_signal = true; -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchTreeWindow.h b/src/progs/ingenuity/PatchTreeWindow.h deleted file mode 100644 index c7fc3c10..00000000 --- a/src/progs/ingenuity/PatchTreeWindow.h +++ /dev/null @@ -1,110 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHTREEWINDOW_H -#define PATCHTREEWINDOW_H - -#include -#include -#include - -namespace Ingen { namespace Client { - class Store; -} } -using Ingen::Client::Store; - -namespace Ingenuity { - -class PatchWindow; -class PatchTreeView; - - -/** Window with a TreeView of all loaded patches. - * - * \ingroup Ingenuity - */ -class PatchTreeWindow : public Gtk::Window -{ -public: - PatchTreeWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - - void init(Store& store); - - void new_object(SharedPtr object); - - void patch_enabled(const Path& path); - void patch_disabled(const Path& path); - void patch_renamed(const Path& old_path, const Path& new_path); - - void add_patch(SharedPtr pm); - void remove_patch(const Path& path); - void show_patch_menu(GdkEventButton* ev); - -protected: - //void event_patch_selected(); - void event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col); - void event_patch_enabled_toggled(const Glib::ustring& path_str); - - Gtk::TreeModel::iterator find_patch(Gtk::TreeModel::Children root, const Path& path); - - PatchTreeView* _patches_treeview; - - struct PatchTreeModelColumns : public Gtk::TreeModel::ColumnRecord - { - PatchTreeModelColumns() - { add(name_col); add(enabled_col); add(patch_model_col); } - - Gtk::TreeModelColumn name_col; - Gtk::TreeModelColumn enabled_col; - Gtk::TreeModelColumn > patch_model_col; - }; - - bool _enable_signal; - PatchTreeModelColumns _patch_tree_columns; - Glib::RefPtr _patch_treestore; - Glib::RefPtr _patch_tree_selection; -}; - - -/** Derived TreeView class to support context menus for patches */ -class PatchTreeView : public Gtk::TreeView -{ -public: - PatchTreeView(BaseObjectType* cobject, const Glib::RefPtr& xml) - : Gtk::TreeView(cobject) - {} - - void set_window(PatchTreeWindow* win) { _window = win; } - - bool on_button_press_event(GdkEventButton* ev) { - bool ret = Gtk::TreeView::on_button_press_event(ev); - - if ((ev->type == GDK_BUTTON_PRESS) && (ev->button == 3)) - _window->show_patch_menu(ev); - - return ret; - } - -private: - PatchTreeWindow* _window; - -}; // struct PatchTreeView - - -} // namespace Ingenuity - -#endif // PATCHTREEWINDOW_H diff --git a/src/progs/ingenuity/PatchView.cpp b/src/progs/ingenuity/PatchView.cpp deleted file mode 100644 index 076eaa40..00000000 --- a/src/progs/ingenuity/PatchView.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "App.h" -#include "PatchView.h" -#include "PatchCanvas.h" -#include "LoadPluginWindow.h" -#include "NewSubpatchWindow.h" -#include "LoadSubpatchWindow.h" -#include "NodeControlWindow.h" -#include "PatchPropertiesWindow.h" -#include "PatchTreeWindow.h" -#include "GladeFactory.h" - -namespace Ingenuity { - - -PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::Box(cobject), - _breadcrumb_container(NULL), - _enable_signal(true) -{ - property_visible() = false; - - xml->get_widget("patch_view_breadcrumb_container", _breadcrumb_container); - xml->get_widget("patch_view_process_but", _process_but); - xml->get_widget("patch_view_poly_spin", _poly_spin); - xml->get_widget("patch_view_clear_but", _clear_but); - xml->get_widget("patch_view_destroy_but", _destroy_but); - xml->get_widget("patch_view_refresh_but", _refresh_but); - xml->get_widget("patch_view_save_but", _save_but); - xml->get_widget("patch_view_zoom_full_but", _zoom_full_but); - xml->get_widget("patch_view_zoom_normal_but", _zoom_normal_but); - xml->get_widget("patch_view_scrolledwindow", _canvas_scrolledwindow); -} - - -void -PatchView::set_patch(SharedPtr patch) -{ - assert(!_canvas); // FIXME: remove - - cerr << "Creating view for " << patch->path() << endl; - - assert(_breadcrumb_container); // ensure created - - _patch = patch; - _canvas = SharedPtr(new PatchCanvas(patch, 1600*2, 1200*2)); - _canvas->build(); - - _canvas_scrolledwindow->add(*_canvas); - - _poly_spin->set_value(patch->poly()); - _destroy_but->set_sensitive(patch->path() != "/"); - patch->enabled() ? enable() : disable(); - - // Connect model signals to track state - patch->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable)); - patch->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable)); - - // Connect widget signals to do things - _process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled)); - _clear_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::clear_clicked)); - _refresh_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::refresh_clicked)); - - _zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun( - _canvas.get(), &FlowCanvas::set_zoom), 1.0)); - - _zoom_full_but->signal_clicked().connect( - sigc::mem_fun(_canvas.get(), &FlowCanvas::zoom_full)); -} - - -PatchView::~PatchView() -{ - cerr << "Destroying view for " << _patch->path() << endl; -} - - -SharedPtr -PatchView::create(SharedPtr patch) - -{ - const Glib::RefPtr& xml = GladeFactory::new_glade_reference("patch_view_box"); - PatchView* result = NULL; - xml->get_widget_derived("patch_view_box", result); - assert(result); - result->set_patch(patch); - return SharedPtr(result); -} - - -void -PatchView::process_toggled() -{ - if (!_enable_signal) - return; - - if (_process_but->get_active()) { - App::instance().engine()->enable_patch(_patch->path()); - App::instance().patch_tree()->patch_enabled(_patch->path()); - } else { - App::instance().engine()->disable_patch(_patch->path()); - App::instance().patch_tree()->patch_disabled(_patch->path()); - } -} - - -void -PatchView::clear_clicked() -{ - App::instance().engine()->clear_patch(_patch->path()); -} - - -void -PatchView::refresh_clicked() -{ - App::instance().engine()->request_object(_patch->path()); -} - - -void -PatchView::enable() -{ - _enable_signal = false; - _process_but->set_active(true); - _enable_signal = true; -} - - -void -PatchView::disable() -{ - _enable_signal = false; - _process_but->set_active(false); - _enable_signal = true; -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchView.h b/src/progs/ingenuity/PatchView.h deleted file mode 100644 index 95683251..00000000 --- a/src/progs/ingenuity/PatchView.h +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHVIEW_H -#define PATCHVIEW_H - -#include -#include -#include -#include -#include -#include "client/PatchModel.h" - -using std::string; - -namespace Ingen { namespace Client { - class PortModel; - class ControlModel; - class MetadataModel; -} } -using namespace Ingen::Client; - - -namespace Ingenuity { - -class PatchCanvas; -class LoadPluginWindow; -class NewSubpatchWindow; -class LoadSubpatchWindow; -class NewSubpatchWindow; -class NodeControlWindow; -class PatchDescriptionWindow; -class SubpatchModule; -class OmPort; - - -/** The patch specific contents of a PatchWindow (ie the canvas and whatever else). - * - * \ingroup Ingenuity - */ -class PatchView : public Gtk::Box -{ -public: - PatchView(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); - ~PatchView(); - - SharedPtr canvas() const { return _canvas; } - SharedPtr patch() const { return _patch; } - Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; } - - static SharedPtr create(SharedPtr patch); - -private: - void set_patch(SharedPtr patch); - - void process_toggled(); - void clear_clicked(); - void refresh_clicked(); - - void enable(); - void disable(); - - void zoom_full(); - - SharedPtr _patch; - SharedPtr _canvas; - - Gtk::ScrolledWindow* _canvas_scrolledwindow; - - Gtk::ToggleToolButton* _process_but; - Gtk::SpinButton* _poly_spin; - Gtk::ToolButton* _clear_but; - Gtk::ToolButton* _destroy_but; - Gtk::ToolButton* _refresh_but; - Gtk::ToolButton* _save_but; - Gtk::ToolButton* _zoom_normal_but; - Gtk::ToolButton* _zoom_full_but; - Gtk::Viewport* _breadcrumb_container; - - bool _enable_signal; -}; - - -} // namespace Ingenuity - -#endif // PATCHVIEW_H diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp deleted file mode 100644 index 2e764ff0..00000000 --- a/src/progs/ingenuity/PatchWindow.cpp +++ /dev/null @@ -1,465 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "PatchWindow.h" -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "client/Store.h" -#include "App.h" -#include "PatchCanvas.h" -#include "LoadPluginWindow.h" -#include "NewSubpatchWindow.h" -#include "LoadPatchWindow.h" -#include "LoadSubpatchWindow.h" -#include "NodeControlWindow.h" -#include "PatchPropertiesWindow.h" -#include "ConfigWindow.h" -#include "MessagesWindow.h" -#include "PatchTreeWindow.h" -#include "BreadCrumbBox.h" -#include "ConnectWindow.h" -#include "ThreadedLoader.h" -#include "WindowFactory.h" -#include "PatchView.h" - -namespace Ingenuity { - - -PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) -: Gtk::Window(cobject), - _enable_signal(true), - _position_stored(false), - _x(0), - _y(0), - _breadcrumb_box(NULL) -{ - property_visible() = false; - - xml->get_widget("patch_win_vbox", _vbox); - xml->get_widget("patch_win_viewport", _viewport); - //xml->get_widget("patch_win_status_bar", _status_bar); - //xml->get_widget("patch_open_menuitem", _menu_open); - xml->get_widget("patch_import_menuitem", _menu_import); - xml->get_widget("patch_import_location_menuitem", _menu_import_location); - //xml->get_widget("patch_open_into_menuitem", _menu_open_into); - xml->get_widget("patch_save_menuitem", _menu_save); - xml->get_widget("patch_save_as_menuitem", _menu_save_as); - xml->get_widget("patch_upload_menuitem", _menu_upload); - xml->get_widget("patch_cut_menuitem", _menu_cut); - xml->get_widget("patch_copy_menuitem", _menu_copy); - xml->get_widget("patch_paste_menuitem", _menu_paste); - xml->get_widget("patch_delete_menuitem", _menu_delete); - xml->get_widget("patch_close_menuitem", _menu_close); - xml->get_widget("patch_configuration_menuitem", _menu_configuration); - xml->get_widget("patch_quit_menuitem", _menu_quit); - xml->get_widget("patch_view_control_window_menuitem", _menu_view_control_window); - xml->get_widget("patch_view_engine_window_menuitem", _menu_view_engine_window); - xml->get_widget("patch_properties_menuitem", _menu_view_patch_properties); - xml->get_widget("patch_fullscreen_menuitem", _menu_fullscreen); - xml->get_widget("patch_arrange_menuitem", _menu_arrange); - xml->get_widget("patch_clear_menuitem", _menu_clear); - xml->get_widget("patch_destroy_menuitem", _menu_destroy_patch); - xml->get_widget("patch_view_messages_window_menuitem", _menu_view_messages_window); - xml->get_widget("patch_view_patch_tree_window_menuitem", _menu_view_patch_tree_window); - xml->get_widget("patch_help_about_menuitem", _menu_help_about); - - _menu_view_control_window->property_sensitive() = false; - //m_status_bar->push(App::instance().engine()->engine_url()); - //m_status_bar->pack_start(*Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_MENU)), false, false); - - /*_menu_open->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_open));*/ - _menu_import->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_import)); - _menu_import_location->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_import_location)); - _menu_save->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_save)); - _menu_save_as->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_save_as)); - _menu_upload->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_upload)); - _menu_copy->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_copy)); - _menu_delete->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_delete)); - _menu_quit->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_quit)); - _menu_configuration->signal_activate().connect( - sigc::mem_fun(App::instance().configuration_dialog(), &ConfigWindow::show)); - _menu_fullscreen->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_fullscreen_toggled)); - _menu_arrange->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_arrange)); - _menu_view_engine_window->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_show_engine)); - _menu_view_control_window->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_show_controls)); - _menu_view_patch_properties->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_show_properties)); - _menu_destroy_patch->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_destroy)); - _menu_clear->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_clear)); - _menu_view_messages_window->signal_activate().connect( - sigc::mem_fun(App::instance().messages_dialog(), &MessagesWindow::present)); - _menu_view_patch_tree_window->signal_activate().connect( - sigc::mem_fun(App::instance().patch_tree(), &PatchTreeWindow::present)); - - _menu_help_about->signal_activate().connect( - sigc::mem_fun(App::instance().about_dialog(), &Gtk::Dialog::present)); - - _breadcrumb_box = new BreadCrumbBox(); - _breadcrumb_box->signal_patch_selected.connect(sigc::mem_fun(this, &PatchWindow::set_patch_from_path)); -} - - -PatchWindow::~PatchWindow() -{ - // Prevents deletion - //m_patch->claim_patch_view(); - - delete _breadcrumb_box; -} - - -/** Set the patch controller from a Path (for use by eg. BreadCrumbBox) - */ -void -PatchWindow::set_patch_from_path(const Path& path, SharedPtr view) -{ - if (view) { - assert(view->patch()->path() == path); - App::instance().window_factory()->present_patch(view->patch(), this, view); - } else { - SharedPtr model = PtrCast(App::instance().store()->object(path)); - if (model) - App::instance().window_factory()->present_patch(model, this); - } -} - - -/** Sets the patch controller for this window and initializes everything. - * - * If @a view is NULL, a new view will be created. - */ -void -PatchWindow::set_patch(SharedPtr patch, SharedPtr view) -{ - if (!patch || patch == _patch) - return; - - _enable_signal = false; - - _patch = patch; - - _view = view; - - if (!_view) - _view = _breadcrumb_box->view(patch->path()); - - if (!_view) - _view = PatchView::create(patch); - - assert(_view); - - // Add view to our viewport - if (_view->get_parent()) - _view->get_parent()->remove(*_view.get()); - - _viewport->remove(); - _viewport->add(*_view.get()); - - - if (_breadcrumb_box->get_parent()) - _breadcrumb_box->get_parent()->remove(*_breadcrumb_box); - - _view->breadcrumb_container()->remove(); - _view->breadcrumb_container()->add(*_breadcrumb_box); - _view->breadcrumb_container()->show(); - - _breadcrumb_box->build(patch->path(), _view); - _breadcrumb_box->show(); - - _menu_view_control_window->property_sensitive() = false; - - for (PortModelList::const_iterator p = patch->ports().begin(); - p != patch->ports().end(); ++p) { - if ((*p)->is_control()) { - _menu_view_control_window->property_sensitive() = true; - break; - } - } - - int width, height; - get_size(width, height); - _view->canvas()->scroll_to( - ((int)_view->canvas()->width() - width)/2, - ((int)_view->canvas()->height() - height)/2); - - set_title(_patch->path() + " - Ingenuity"); - - //m_properties_window->patch_model(pc->patch_model()); - - if (patch->path() == "/") - _menu_destroy_patch->set_sensitive(false); - else - _menu_destroy_patch->set_sensitive(true); - - show_all(); - - _enable_signal = true; -} - - -void -PatchWindow::event_show_engine() -{ - if (_patch) - App::instance().connect_window()->show(); -} - - -void -PatchWindow::event_show_controls() -{ - App::instance().window_factory()->present_controls(_patch); -} - - -void -PatchWindow::event_show_properties() -{ - App::instance().window_factory()->present_properties(_patch); -} - - -void -PatchWindow::event_import() -{ - App::instance().window_factory()->present_load_patch(_patch); -} - - -void -PatchWindow::event_import_location() -{ - App::instance().window_factory()->present_load_remote_patch(_patch); -} - - -void -PatchWindow::event_save() -{ - if (_patch->filename() == "") - event_save_as(); - else - App::instance().loader()->save_patch(_patch, _patch->filename(), false); -} - - -void -PatchWindow::event_save_as() -{ - Gtk::FileChooserDialog dialog(*this, "Save Patch", Gtk::FILE_CHOOSER_ACTION_SAVE); - - /*Gtk::VBox* box = dialog.get_vbox(); - Gtk::Label warning("Warning: Recursively saving will overwrite any subpatch files \ - without confirmation."); - box->pack_start(warning, false, false, 2); - Gtk::CheckButton recursive_checkbutton("Recursively save all subpatches"); - box->pack_start(recursive_checkbutton, false, false, 0); - recursive_checkbutton.show(); - */ - - dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - Gtk::Button* save_button = dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); - save_button->property_has_default() = true; - - // Set current folder to most sensible default - const string& current_filename = _patch->filename(); - if (current_filename.length() > 0) - dialog.set_filename(current_filename); - else if (App::instance().configuration()->patch_folder().length() > 0) - dialog.set_current_folder(App::instance().configuration()->patch_folder()); - - int result = dialog.run(); - //bool recursive = recursive_checkbutton.get_active(); - - assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); - - if (result == Gtk::RESPONSE_OK) { - string filename = dialog.get_filename(); - if (filename.length() < 11 || filename.substr(filename.length()-10) != ".ingen.ttl") - filename += ".ingen.ttl"; - - bool confirm = false; - std::fstream fin; - fin.open(filename.c_str(), std::ios::in); - if (fin.is_open()) { // File exists - string msg = "File already exists! Are you sure you want to overwrite "; - msg += filename + "?"; - Gtk::MessageDialog confirm_dialog(*this, - msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); - if (confirm_dialog.run() == Gtk::RESPONSE_YES) - confirm = true; - else - confirm = false; - } else { // File doesn't exist - confirm = true; - } - fin.close(); - - if (confirm) { - App::instance().loader()->save_patch(_patch, filename, true); - _patch->set_filename(filename); - //_patch->set_metadata("filename", Atom(filename.c_str())); - } - } - App::instance().configuration()->set_patch_folder(dialog.get_current_folder()); -} - - -void -PatchWindow::event_upload() -{ - App::instance().window_factory()->present_upload_patch(_patch); -} - - -void -PatchWindow::event_copy() -{ - if (_view) - _view->canvas()->copy_selection(); -} - - -void -PatchWindow::event_delete() -{ - if (_view) - _view->canvas()->destroy_selection(); -} - - -void -PatchWindow::on_show() -{ - if (_position_stored) - move(_x, _y); - - Gtk::Window::on_show(); -} - - -void -PatchWindow::on_hide() -{ - _position_stored = true; - get_position(_x, _y); - Gtk::Window::on_hide(); -} - - -bool -PatchWindow::on_key_press_event(GdkEventKey* event) -{ - if (event->keyval == GDK_Delete) { - cerr << "FIXME: delete key\n"; - /* - if (_patch && _patch->get_view()) { - assert(_patch->get_view()->canvas()); - _patch->get_view()->canvas()->destroy_selected(); - }*/ - return true; - } else { - return Gtk::Window::on_key_press_event(event); - } -} - - -void -PatchWindow::event_quit() -{ - Gtk::MessageDialog d(*this, "Would you like to quit just Ingenuity\nor kill the engine as well?", - true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - - Gtk::Button* b = d.add_button(Gtk::Stock::REMOVE, 2); // kill - b->set_label("_Kill Engine"); - Gtk::Widget* kill_img = Gtk::manage(new Gtk::Image(Gtk::Stock::CLOSE, Gtk::ICON_SIZE_BUTTON)); - b->set_image(*kill_img); - - b = d.add_button(Gtk::Stock::QUIT, 1); // just exit - b->set_label("_Quit"); - Gtk::Widget* close_img = Gtk::manage(new Gtk::Image(Gtk::Stock::QUIT, Gtk::ICON_SIZE_BUTTON)); - b->set_image(*close_img); - b->grab_default(); - - int ret = d.run(); - if (ret == 1) { - App::instance().quit(); - } else if (ret == 2) { - App::instance().engine()->quit(); - App::instance().quit(); - } - // Otherwise cancelled, do nothing -} - - -void -PatchWindow::event_destroy() -{ - App::instance().engine()->destroy(_patch->path()); -} - - -void -PatchWindow::event_clear() -{ - App::instance().engine()->clear_patch(_patch->path()); -} - - -void -PatchWindow::event_arrange() -{ - _view->canvas()->arrange(); -} - - -void -PatchWindow::event_fullscreen_toggled() -{ - // FIXME: ugh, use GTK signals to track state and know for sure - static bool is_fullscreen = false; - - if (!is_fullscreen) { - fullscreen(); - is_fullscreen = true; - } else { - unfullscreen(); - is_fullscreen = false; - } -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchWindow.h b/src/progs/ingenuity/PatchWindow.h deleted file mode 100644 index f4399a20..00000000 --- a/src/progs/ingenuity/PatchWindow.h +++ /dev/null @@ -1,141 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHWINDOW_H -#define PATCHWINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include "client/PatchModel.h" -#include "PatchView.h" -using Ingen::Client::PatchModel; - -using std::string; using std::list; - - -namespace Ingen { namespace Client { - class PatchModel; - class PortModel; - class ControlModel; - class MetadataModel; -} } -using namespace Ingen::Client; - - -namespace Ingenuity { - -class LoadPluginWindow; -class LoadPatchWindow; -class NewSubpatchWindow; -class LoadSubpatchWindow; -class NewSubpatchWindow; -class NodeControlWindow; -class PatchDescriptionWindow; -class SubpatchModule; -class OmPort; -class BreadCrumbBox; - - -/** A window for a patch. - * - * \ingroup Ingenuity - */ -class PatchWindow : public Gtk::Window -{ -public: - PatchWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); - ~PatchWindow(); - - void set_patch_from_path(const Path& path, SharedPtr view); - void set_patch(SharedPtr pc, SharedPtr view); - - SharedPtr patch() const { return _patch; } - - Gtk::MenuItem* menu_view_control_window() { return _menu_view_control_window; } - -protected: - void on_show(); - void on_hide(); - bool on_key_press_event(GdkEventKey* event); - -private: - void event_import(); - void event_import_location(); - void event_save(); - void event_save_as(); - void event_upload(); - void event_copy(); - void event_delete(); - void event_quit(); - void event_destroy(); - void event_clear(); - void event_fullscreen_toggled(); - void event_arrange(); - void event_show_properties(); - void event_show_controls(); - void event_show_engine(); - - SharedPtr _patch; - SharedPtr _view; - - bool _enable_signal; - bool _position_stored; - int _x; - int _y; - - Gtk::MenuItem* _menu_import; - Gtk::MenuItem* _menu_import_location; - Gtk::MenuItem* _menu_save; - Gtk::MenuItem* _menu_save_as; - Gtk::MenuItem* _menu_upload; - Gtk::MenuItem* _menu_cut; - Gtk::MenuItem* _menu_copy; - Gtk::MenuItem* _menu_paste; - Gtk::MenuItem* _menu_delete; - Gtk::MenuItem* _menu_configuration; - Gtk::MenuItem* _menu_close; - Gtk::MenuItem* _menu_quit; - Gtk::MenuItem* _menu_fullscreen; - Gtk::MenuItem* _menu_clear; - Gtk::MenuItem* _menu_destroy_patch; - Gtk::MenuItem* _menu_arrange; - Gtk::MenuItem* _menu_view_engine_window; - Gtk::MenuItem* _menu_view_control_window; - Gtk::MenuItem* _menu_view_patch_properties; - Gtk::MenuItem* _menu_view_messages_window; - Gtk::MenuItem* _menu_view_patch_tree_window; - Gtk::MenuItem* _menu_help_about; - - Gtk::VBox* _vbox; - Gtk::Viewport* _viewport; - BreadCrumbBox* _breadcrumb_box; - - //Gtk::Statusbar* _status_bar; - - /** Invisible bin used to store breadcrumbs when not shown by a view */ - Gtk::Alignment _breadcrumb_bin; -}; - - -} // namespace Ingenuity - -#endif // PATCHWINDOW_H diff --git a/src/progs/ingenuity/Port.cpp b/src/progs/ingenuity/Port.cpp deleted file mode 100644 index b13ccda9..00000000 --- a/src/progs/ingenuity/Port.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "client/PortModel.h" -#include "client/ControlModel.h" -#include "Configuration.h" -#include "App.h" -#include "Port.h" -using std::cerr; using std::endl; - -using namespace Ingen::Client; - -namespace Ingenuity { - - -/** @param flip Make an input port appear as an output port, and vice versa. - */ -Port::Port(boost::shared_ptr module, SharedPtr pm, bool flip, bool destroyable) -: LibFlowCanvas::Port(module, - pm->path().name(), - flip ? (!pm->is_input()) : pm->is_input(), - App::instance().configuration()->get_port_color(pm.get())), - _port_model(pm) -{ - assert(module); - assert(_port_model); - - if (destroyable) - _menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Destroy", - sigc::mem_fun(this, &Port::on_menu_destroy))); -} - - -void -Port::on_menu_destroy() -{ - App::instance().engine()->destroy(_port_model->path()); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/Port.h b/src/progs/ingenuity/Port.h deleted file mode 100644 index b006ba45..00000000 --- a/src/progs/ingenuity/Port.h +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PORT_H -#define PORT_H - -#include -#include -#include -#include - -namespace Ingen { namespace Client { class PortModel; } } -using Ingen::Client::PortModel; - -namespace Ingenuity { - - -/** A Port on an Module. - * - * \ingroup Ingenuity - */ -class Port : public LibFlowCanvas::Port -{ -public: - Port(boost::shared_ptr module, SharedPtr pm, bool flip = false, bool destroyable = false); - - virtual ~Port() {} - - SharedPtr model() const { return _port_model; } - -private: - - void on_menu_destroy(); - - SharedPtr _port_model; -}; - - -} // namespace Ingenuity - -#endif // PORT_H diff --git a/src/progs/ingenuity/PortPropertiesWindow.cpp b/src/progs/ingenuity/PortPropertiesWindow.cpp deleted file mode 100644 index eb23c542..00000000 --- a/src/progs/ingenuity/PortPropertiesWindow.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/NodeModel.h" -#include "client/PluginModel.h" -#include "App.h" -#include "ControlGroups.h" -#include "PortPropertiesWindow.h" - -using std::string; - -namespace Ingenuity { - - -PortPropertiesWindow::PortPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) - : Gtk::Dialog(cobject) - , _enable_signal(false) - , _control(NULL) -{ - xml->get_widget("port_properties_min_spinner", _min_spinner); - xml->get_widget("port_properties_max_spinner", _max_spinner); - xml->get_widget("port_properties_cancel_button", _cancel_button); - xml->get_widget("port_properties_ok_button", _ok_button); - - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, - &PortPropertiesWindow::cancel)); - - _ok_button->signal_clicked().connect(sigc::mem_fun(this, - &PortPropertiesWindow::ok)); -} - - -/** Set the port this window is associated with. - * This function MUST be called before using this object in any way. - */ -void -PortPropertiesWindow::init(ControlGroup* control, SharedPtr pm) -{ - assert(pm); - assert(control); - - _port_model = pm; - _control = control; - - - set_title(pm->path() + " Properties"); - - // FIXME: code duplication w/ ControlGroups.cpp - float min = 0.0f; - float max = 1.0f; - - const Atom& min_atom = pm->get_metadata("ingen:minimum"); - const Atom& max_atom = pm->get_metadata("ingen_maximum"); - if (min_atom.type() == Atom::FLOAT && max_atom.type() == Atom::FLOAT) { - min = min_atom.get_float(); - max = max_atom.get_float(); - } - - const SharedPtr parent = PtrCast(pm->parent()); - - if (parent && parent->plugin() && parent->plugin()->type() == PluginModel::LV2) { - min = slv2_port_get_minimum_value( - parent->plugin()->slv2_plugin(), - slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), - pm->path().name().c_str())); - max = slv2_port_get_maximum_value( - parent->plugin()->slv2_plugin(), - slv2_plugin_get_port_by_symbol(parent->plugin()->slv2_plugin(), - pm->path().name().c_str())); - } - - if (max <= min) - max = min + 1.0f; - - _initial_min = min; - _initial_max = max; - - _min_spinner->set_value(min); - _min_spinner->signal_value_changed().connect(sigc::mem_fun(*this, &PortPropertiesWindow::min_changed)); - _max_spinner->set_value(max); - _max_spinner->signal_value_changed().connect(sigc::mem_fun(*this, &PortPropertiesWindow::max_changed)); - - pm->metadata_update_sig.connect(sigc::mem_fun(this, &PortPropertiesWindow::metadata_update)); - - _enable_signal = true; -} - - -void -PortPropertiesWindow::metadata_update(const string& key, const Atom& value) -{ - _enable_signal = false; - - if ( (key == "ingen:minimum") && value.type() == Atom::FLOAT) - _min_spinner->set_value(value.get_float()); - else if ( (key == "ingen:maximum") && value.type() == Atom::FLOAT) - _max_spinner->set_value(value.get_float()); - - _enable_signal = true; -} - - -void -PortPropertiesWindow::min_changed() -{ - float min = _min_spinner->get_value(); - const float max = _max_spinner->get_value(); - - if (min >= max) { - min = max - 1.0; - _min_spinner->set_value(min); - } - - _control->set_range(min, max); - - if (_enable_signal) - App::instance().engine()->set_metadata(_port_model->path(), "ingen:minimum", min); -} - - -void -PortPropertiesWindow::max_changed() -{ - const float min = _min_spinner->get_value(); - float max = _max_spinner->get_value(); - - if (max <= min) { - max = min + 1.0; - _max_spinner->set_value(max); - } - - _control->set_range(min, max); - - if (_enable_signal) - App::instance().engine()->set_metadata(_port_model->path(), "ingen:maximum", max); -} - - -void -PortPropertiesWindow::cancel() -{ - App::instance().engine()->set_metadata(_port_model->path(), "ingen:minimum", _initial_min); - App::instance().engine()->set_metadata(_port_model->path(), "ingen:maximum", _initial_max); - delete this; -} - - -void -PortPropertiesWindow::ok() -{ - delete this; -} - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/PortPropertiesWindow.h b/src/progs/ingenuity/PortPropertiesWindow.h deleted file mode 100644 index adb0a2f0..00000000 --- a/src/progs/ingenuity/PortPropertiesWindow.h +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PORTPROPERTIESWINDOW_H -#define PORTPROPERTIESWINDOW_H - -#include -#include -#include -#include "client/PortModel.h" -using namespace Ingen::Client; - -namespace Ingenuity { - -class ControlGroup; - - -/** Port properties window. - * - * Loaded by libglade as a derived object. - * - * \ingroup Ingenuity - */ -class PortPropertiesWindow : public Gtk::Dialog -{ -public: - PortPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - - void init(ControlGroup* control, SharedPtr port_model); - -private: - void metadata_update(const string& key, const Atom& value); - void min_changed(); - void max_changed(); - - void ok(); - void cancel(); - - bool _enable_signal; - - float _initial_min; - float _initial_max; - - ControlGroup* _control; - SharedPtr _port_model; - Gtk::SpinButton* _min_spinner; - Gtk::SpinButton* _max_spinner; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; -}; - -} // namespace Ingenuity - -#endif // PORTPROPERTIESWINDOW_H diff --git a/src/progs/ingenuity/RenameWindow.cpp b/src/progs/ingenuity/RenameWindow.cpp deleted file mode 100644 index 28a8ddfe..00000000 --- a/src/progs/ingenuity/RenameWindow.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "interface/EngineInterface.h" -#include "client/ObjectModel.h" -#include "client/Store.h" -#include "App.h" -#include "RenameWindow.h" - -using std::string; - -namespace Ingenuity { - - -RenameWindow::RenameWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("rename_name_entry", _name_entry); - glade_xml->get_widget("rename_message_label", _message_label); - glade_xml->get_widget("rename_cancel_button", _cancel_button); - glade_xml->get_widget("rename_ok_button", _ok_button); - - _name_entry->signal_changed().connect(sigc::mem_fun(this, &RenameWindow::name_changed)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &RenameWindow::cancel_clicked)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &RenameWindow::ok_clicked)); - - _ok_button->property_sensitive() = false; -} - - -/** Set the object this window is renaming. - * This function MUST be called before using this object in any way. - */ -void -RenameWindow::set_object(SharedPtr object) -{ - _object = object; - _name_entry->set_text(object->path().name()); -} - - -/** Called every time the user types into the name input box. - * Used to display warning messages, and enable/disable the rename button. - */ -void -RenameWindow::name_changed() -{ - assert(_name_entry); - assert(_message_label); - assert(_object); - assert(_object->parent()); - - string name = _name_entry->get_text(); - if (name.find("/") != string::npos) { - _message_label->set_text("Name may not contain '/'"); - _ok_button->property_sensitive() = false; - //} else if (_object->parent()->patch_model()->get_node(name) != NULL) { - } else if (App::instance().store()->object(_object->parent()->path().base() + name)) { - _message_label->set_text("An object already exists with that name."); - _ok_button->property_sensitive() = false; - } else if (name.length() == 0) { - _message_label->set_text(""); - _ok_button->property_sensitive() = false; - } else { - _message_label->set_text(""); - _ok_button->property_sensitive() = true; - } -} - - -void -RenameWindow::cancel_clicked() -{ - cout << "cancel\n"; - _name_entry->set_text(""); - hide(); -} - - -/** Rename the object. - * - * It shouldn't be possible for this to be called with an invalid name set - * (since the Rename button should be deactivated). This is just shinification - * though - the engine will handle invalid names gracefully. - */ -void -RenameWindow::ok_clicked() -{ - string name = _name_entry->get_text(); - assert(name.length() > 0); - assert(name.find("/") == string::npos); - - App::instance().engine()->rename(_object->path(), name); - - hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/RenameWindow.h b/src/progs/ingenuity/RenameWindow.h deleted file mode 100644 index 04f765d4..00000000 --- a/src/progs/ingenuity/RenameWindow.h +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RENAMEWINDOW_H -#define RENAMEWINDOW_H - -#include -#include -#include -#include "client/ObjectModel.h" -using Ingen::Client::ObjectModel; - -namespace Ingenuity { - - -/** Rename window. Handles renaming of any (Ingen) object. - * - * \ingroup Ingenuity - */ -class RenameWindow : public Gtk::Window -{ -public: - RenameWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - - void present(SharedPtr object) { set_object(object); Gtk::Window::present(); } - -private: - void set_object(SharedPtr object); - - void name_changed(); - void cancel_clicked(); - void ok_clicked(); - - SharedPtr _object; - - Gtk::Entry* _name_entry; - Gtk::Label* _message_label; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; -}; - -} // namespace Ingenuity - -#endif // RENAMEWINDOW_H diff --git a/src/progs/ingenuity/SubpatchModule.cpp b/src/progs/ingenuity/SubpatchModule.cpp deleted file mode 100644 index 53958375..00000000 --- a/src/progs/ingenuity/SubpatchModule.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "SubpatchModule.h" -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "App.h" -#include "NodeModule.h" -#include "NodeControlWindow.h" -#include "PatchWindow.h" -#include "PatchCanvas.h" -#include "Port.h" -#include "WindowFactory.h" -using std::cerr; using std::cout; using std::endl; - -namespace Ingenuity { - - -SubpatchModule::SubpatchModule(boost::shared_ptr canvas, SharedPtr patch) -: NodeModule(canvas, patch), - _patch(patch) -{ - assert(canvas); - assert(patch); -} - - -void -SubpatchModule::on_double_click(GdkEventButton* event) -{ - assert(_patch); - - SharedPtr parent = PtrCast(_patch->parent()); - - PatchWindow* const preferred = ( (parent && (event->state & GDK_SHIFT_MASK)) - ? NULL - : App::instance().window_factory()->patch_window(parent) ); - - App::instance().window_factory()->present_patch(_patch, preferred); -} - - - -/** Browse to this patch in current (parent's) window - * (unless an existing window is displaying it) - */ -void -SubpatchModule::browse_to_patch() -{ - assert(_patch->parent()); - - SharedPtr parent = PtrCast(_patch->parent()); - - PatchWindow* const preferred = ( (parent) - ? App::instance().window_factory()->patch_window(parent) - : NULL ); - - App::instance().window_factory()->present_patch(_patch, preferred); -} - - - -void -SubpatchModule::show_dialog() -{ - cerr << "FIXME: dialog\n"; - //m_patch->show_control_window(); -} - - -void -SubpatchModule::menu_remove() -{ - App::instance().engine()->destroy(_patch->path()); -} - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/SubpatchModule.h b/src/progs/ingenuity/SubpatchModule.h deleted file mode 100644 index 36e9a2d3..00000000 --- a/src/progs/ingenuity/SubpatchModule.h +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef SUBPATCHMODULE_H -#define SUBPATCHMODULE_H - -#include -#include -#include -#include "client/PatchModel.h" -#include "PatchPortModule.h" -#include "NodeModule.h" -using std::string; using std::list; - -namespace Ingen { namespace Client { - class PatchModel; - class NodeModel; - class PortModel; - class PatchWindow; -} } -using namespace Ingen::Client; - -namespace Ingenuity { - -class PatchCanvas; -class NodeControlWindow; - - -/** A module to represent a subpatch - * - * \ingroup Ingenuity - */ -class SubpatchModule : public NodeModule -{ -public: - SubpatchModule(boost::shared_ptr canvas, SharedPtr controller); - virtual ~SubpatchModule() {} - - void on_double_click(GdkEventButton* ev); - - void show_dialog(); - void browse_to_patch(); - void menu_remove(); - - SharedPtr patch() { return _patch; } - -protected: - SharedPtr _patch; -}; - - -} // namespace Ingenuity - -#endif // SUBPATCHMODULE_H diff --git a/src/progs/ingenuity/ThreadedLoader.cpp b/src/progs/ingenuity/ThreadedLoader.cpp deleted file mode 100644 index 43bc76c8..00000000 --- a/src/progs/ingenuity/ThreadedLoader.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include "client/PatchModel.h" -#include "module/Module.h" -#include "App.h" -#include "ThreadedLoader.h" -using std::cout; using std::endl; - -namespace Ingenuity { - - -ThreadedLoader::ThreadedLoader(SharedPtr engine) - : _serialisation_module(Ingen::Shared::load_module("ingen_serialisation")) - , _engine(engine) - , _deprecated_loader(engine) - , _serializer(*App::instance().rdf_world()) -{ - // FIXME: rework this so the thread is only present when it's doing something (save mem) - if (_serialisation_module) { - Loader* (*new_loader)() = NULL; - bool found = _serialisation_module->get_symbol("new_loader", (void*&)new_loader); - if (found) - _loader = SharedPtr(new_loader()); - } - - if (_loader) { - start(); - } else { - cerr << "WARNING: Failed to load ingen_serialisation module, unable to load patches." << endl;; - cerr << "If you are running from the source tree, run ingenuity_dev." << endl; - } -} - - -ThreadedLoader::~ThreadedLoader() -{ -} - - -void -ThreadedLoader::_whipped() -{ - _mutex.lock(); - - while ( ! _events.empty() ) { - _events.front()(); - _events.pop_front(); - } - - _mutex.unlock(); -} - -/** FIXME: use poly parameter */ -void -ThreadedLoader::load_patch(bool merge, - const string& data_base_uri, - const Path& data_path, - MetadataMap engine_data, - optional engine_parent, - optional engine_name, - optional engine_poly) -{ - _mutex.lock(); - - // FIXME: Filthy hack to load deprecated patches based on file extension - if (data_base_uri.substr(data_base_uri.length()-3) == ".om") { - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(_deprecated_loader, &DeprecatedLoader::load_patch), - data_base_uri, - engine_parent, - (engine_name) ? engine_name.get() : "", - (engine_poly) ? engine_poly.get() : 1, - engine_data, - false))); - } else { - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(_loader.get(), &Ingen::Serialisation::Loader::load), - App::instance().engine(), - App::instance().rdf_world(), - data_base_uri, - engine_parent, - (engine_name) ? engine_name.get() : "", - // FIXME: poly here - "", - engine_data ))); - } - - _mutex.unlock(); - - whip(); -} - - -void -ThreadedLoader::save_patch(SharedPtr model, const string& filename, bool recursive) -{ - _mutex.lock(); - - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(this, &ThreadedLoader::save_patch_event), - model, filename, recursive))); - - _mutex.unlock(); - - whip(); -} - - -void -ThreadedLoader::save_patch_event(SharedPtr model, const string& filename, bool recursive) -{ - if (recursive) - cerr << "FIXME: Recursive save." << endl; - - _serializer.start_to_filename(filename); - _serializer.serialize(model); - _serializer.finish(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/ThreadedLoader.h b/src/progs/ingenuity/ThreadedLoader.h deleted file mode 100644 index 1846cece..00000000 --- a/src/progs/ingenuity/ThreadedLoader.h +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef THREADEDLOADER_H -#define THREADEDLOADER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/PatchModel.h" -#include "client/Serializer.h" -#include "client/DeprecatedLoader.h" -#include "serialisation/Loader.h" -using std::string; -using std::list; -using boost::optional; - -using namespace Ingen::Client; -using namespace Ingen::Serialisation; - -namespace Ingenuity { - - -/** Thread for loading patch files. - * - * This is a seperate thread so it can send all the loading message without - * blocking everything else, so the app can respond to the incoming events - * caused as a result of the patch loading, while the patch loads. - * - * Implemented as a slave with a list of closures (events) which processes - * all events in the (mutex protected) list each time it's whipped. - * - * \ingroup Ingenuity - */ -class ThreadedLoader : public Raul::Slave -{ -public: - ThreadedLoader(SharedPtr engine); - ~ThreadedLoader(); - - // FIXME: there's a pattern here.... - // (same core interface as Loader/Serializer) - - void load_patch(bool merge, - const string& data_base_uri, - const Path& data_path, - MetadataMap engine_data, - optional engine_parent, - optional engine_name = optional(), - optional engine_poly = optional()); - - void save_patch(SharedPtr model, const string& filename, bool recursive); - -private: - - void save_patch_event(SharedPtr model, const string& filename, bool recursive); - - /** Returns nothing and takes no parameters (because they have all been bound) */ - typedef sigc::slot Closure; - - void _whipped(); - - SharedPtr _serialisation_module; - - SharedPtr _engine; - SharedPtr _loader; - - DeprecatedLoader _deprecated_loader; - Serializer _serializer; - Raul::Mutex _mutex; - list _events; -}; - - -} // namespace Ingenuity - -#endif // LOADERRTHREAD_H diff --git a/src/progs/ingenuity/UploadPatchWindow.cpp b/src/progs/ingenuity/UploadPatchWindow.cpp deleted file mode 100644 index 400c2369..00000000 --- a/src/progs/ingenuity/UploadPatchWindow.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include "interface/EngineInterface.h" -#include "client/Serializer.h" -#include "client/PatchModel.h" -#include "UploadPatchWindow.h" -#include "App.h" -#include "Configuration.h" -#include "ThreadedLoader.h" - -using boost::optional; -using namespace Raul; -using namespace std; - -namespace Ingenuity { - - -UploadPatchWindow::UploadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) - : Gtk::Dialog(cobject) - , _thread(NULL) - , _progress_pct(0) - , _response(0) -{ - xml->get_widget("upload_patch_symbol_entry", _symbol_entry); - xml->get_widget("upload_patch_short_name_entry", _short_name_entry); - xml->get_widget("upload_patch_progress", _upload_progress); - xml->get_widget("upload_patch_cancel_button", _cancel_button); - xml->get_widget("upload_patch_upload_button", _upload_button); - - - _symbol_entry->signal_changed().connect(sigc::mem_fun(this, &UploadPatchWindow::symbol_changed)); - _short_name_entry->signal_changed().connect(sigc::mem_fun(this, &UploadPatchWindow::short_name_changed)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &UploadPatchWindow::cancel_clicked)); - _upload_button->signal_clicked().connect(sigc::mem_fun(this, &UploadPatchWindow::upload_clicked)); -} - - -void -UploadPatchWindow::present(SharedPtr patch) -{ - _patch = patch; - - Gtk::Window::present(); -} - - -void -UploadPatchWindow::on_show() -{ - Gtk::Dialog::on_show(); - - Raul::Atom atom = _patch->get_metadata("lv2:symbol"); - if (atom) - _symbol_entry->set_text(atom.get_string()); - - atom = _patch->get_metadata("doap:name"); - if (atom) - _short_name_entry->set_text(atom.get_string()); -} - - -void -UploadPatchWindow::on_hide() -{ - Gtk::Dialog::on_hide(); - - delete _thread; - _thread = NULL; -} - - -bool -UploadPatchWindow::is_symbol(const Glib::ustring& s) -{ - if (s.length() == 0) - return false; - - for (unsigned i=0; i < s.length(); ++i) - if ( !( (s[i] >= 'a' && s[i] <= 'z') - || (s[i] >= 'A' && s[i] <= 'Z') - || (s[i] == '_') - || (i > 0 && s[i] >= '0' && s[i] <= '9') ) ) - return false; - - return true; -} - - -void -UploadPatchWindow::symbol_changed() -{ - _upload_button->property_sensitive() = ( - is_symbol(_symbol_entry->get_text()) - && _short_name_entry->get_text().length() > 0); -} - - -void -UploadPatchWindow::short_name_changed() -{ - _upload_button->property_sensitive() = ( - is_symbol(_symbol_entry->get_text()) - && _short_name_entry->get_text().length() > 0); -} - - -size_t -UploadThread::curl_read_cb(void *ptr, size_t size, size_t nmemb, void *data) -{ - assert(size == 1); - - istringstream* ss = (istringstream*)data; - - return ss->readsome((char*)ptr, nmemb); -} - - -int -UploadThread::curl_progress_cb(void *thread, - double dltotal, - double dlnow, - double ultotal, - double ulnow) -{ - UploadThread* me = (UploadThread*)thread; - me->_win->set_progress(min( - (int)(min(ulnow, (double)me->_length) / me->_length * 100.0), - 99)); - return 0; -} - - -UploadThread::UploadThread(UploadPatchWindow* win, const string& str, const string& url) - : Thread("Upload") - , _curl(NULL) - , _headers(NULL) - , _win(win) - , _length(str.length()) - , _stream(str) - , _url(url) -{ - _curl = curl_easy_init(); - _headers = curl_slist_append(NULL, "Content-type: application/x-turtle"); - - curl_easy_setopt(_curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, _headers); - curl_easy_setopt(_curl, CURLOPT_UPLOAD, 1); - curl_easy_setopt(_curl, CURLOPT_READDATA, &_stream); - curl_easy_setopt(_curl, CURLOPT_READFUNCTION, &UploadThread::curl_read_cb); - curl_easy_setopt(_curl, CURLOPT_INFILESIZE, sizeof(char) * str.length()); - curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, FALSE); - curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &UploadThread::curl_progress_cb); - curl_easy_setopt(_curl, CURLOPT_PROGRESSDATA, this); -} - - -void -UploadThread::_run() -{ - curl_easy_perform(_curl); - - long response; - curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &response); - - printf("Server returned %ld\n", response); - - _win->set_response(response); - _win->set_progress(100); - - curl_slist_free_all(_headers); - curl_easy_cleanup(_curl); - - _headers = NULL; - _curl = NULL; -} - - -bool -UploadPatchWindow::progress_callback() -{ - const int progress = _progress_pct.get(); - const int response = _response.get(); - - _upload_progress->set_fraction(progress / 100.0); - - if (progress == 100) { - if (response == 200) { - _upload_progress->set_text("Transfer completed"); - } else { - _upload_progress->set_fraction(0.0); - char status[4]; - snprintf(status, 4, "%d", (unsigned)response); - string msg = "Transfer failed: Server returned "; - msg.append(status); - _upload_progress->set_text(msg); - } - delete _thread; - _thread = NULL; - _upload_button->set_sensitive(true); - return false; - } else { - return true; - } -} - - -void -UploadPatchWindow::upload_clicked() -{ - assert(!_thread); - - Glib::ustring symbol = _symbol_entry->get_text(); - Glib::ustring short_name = _short_name_entry->get_text(); - - _patch->set_metadata("lv2:symbol", Atom(symbol)); - App::instance().engine()->set_metadata(_patch->path(), "lv2:symbol", Atom(symbol)); - - _patch->set_metadata("doap:name", Atom(short_name)); - App::instance().engine()->set_metadata(_patch->path(), "doap:name", Atom(short_name)); - - _response = 0; - _progress_pct = 0; - - _upload_progress->set_fraction(0.0); - _upload_progress->set_text(""); - - Serializer s(*App::instance().rdf_world()); - s.start_to_string(); - s.serialize(_patch); - const string str = s.finish(); - istringstream stream(str); - - string url = "http://rdf.drobilla.net/ingen_patches/"; - url += symbol + ".ingen.ttl"; - - _thread = new UploadThread(this, str, url); - - _thread->start(); - - _upload_button->set_sensitive(false); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &UploadPatchWindow::progress_callback), 100); -} - - -void -UploadPatchWindow::cancel_clicked() -{ - if (_thread) { - delete _thread; - _thread = NULL; - } - - hide(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/UploadPatchWindow.h b/src/progs/ingenuity/UploadPatchWindow.h deleted file mode 100644 index 36b39b07..00000000 --- a/src/progs/ingenuity/UploadPatchWindow.h +++ /dev/null @@ -1,103 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef UPLOADPATCHWINDOW_H -#define UPLOADPATCHWINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include "client/PatchModel.h" -#include "client/PluginModel.h" -using Ingen::Client::PatchModel; -using Ingen::Client::MetadataMap; - -namespace Ingenuity { - -class UploadPatchWindow; - - -class UploadThread : public Raul::Thread { -public: - UploadThread(UploadPatchWindow* win, - const string& str, - const string& url); - -private: - static size_t curl_read_cb(void* ptr, size_t size, size_t nmemb, void *stream); - static int curl_progress_cb(void* thread, double dltotal, double dlnow, double ultotal, double ulnow); - - void _run(); - - CURL* _curl; - curl_slist* _headers; - UploadPatchWindow* _win; - size_t _length; - std::istringstream _stream; - std::string _url; -}; - - -/* Upload patch dialog. - * - * \ingroup Ingenuity - */ -class UploadPatchWindow : public Gtk::Dialog -{ -public: - UploadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - - void present(SharedPtr patch); - - Gtk::ProgressBar* progress_bar() { return _upload_progress; } - - void set_response(int response) { _response = response; } - void set_progress(int pct) { _progress_pct = pct; } - -private: - bool is_symbol(const Glib::ustring& str); - void symbol_changed(); - void short_name_changed(); - void cancel_clicked(); - void upload_clicked(); - void on_show(); - void on_hide(); - bool progress_callback(); - - UploadThread* _thread; - - SharedPtr _patch; - - Raul::AtomicInt _progress_pct; - Raul::AtomicInt _response; - - Gtk::Entry* _symbol_entry; - Gtk::Entry* _short_name_entry; - Gtk::ProgressBar* _upload_progress; - Gtk::Button* _cancel_button; - Gtk::Button* _upload_button; - -}; - - -} // namespace Ingenuity - -#endif // UPLOADPATCHWINDOW_H diff --git a/src/progs/ingenuity/WindowFactory.cpp b/src/progs/ingenuity/WindowFactory.cpp deleted file mode 100644 index 14a7554f..00000000 --- a/src/progs/ingenuity/WindowFactory.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "WindowFactory.h" -#include "App.h" -#include "PatchWindow.h" -#include "GladeFactory.h" -#include "NodePropertiesWindow.h" -#include "PatchPropertiesWindow.h" -#include "NodeControlWindow.h" -#include "LoadPluginWindow.h" -#include "LoadPatchWindow.h" -#include "LoadRemotePatchWindow.h" -#include "UploadPatchWindow.h" -#include "LoadSubpatchWindow.h" -#include "RenameWindow.h" -#include "NewSubpatchWindow.h" - -namespace Ingenuity { - - -WindowFactory::WindowFactory() -: _load_plugin_win(NULL) -, _load_patch_win(NULL) -, _load_remote_patch_win(NULL) -, _upload_patch_win(NULL) -, _new_subpatch_win(NULL) -, _load_subpatch_win(NULL) -, _node_properties_win(NULL) -, _patch_properties_win(NULL) -{ - Glib::RefPtr xml = GladeFactory::new_glade_reference(); - - xml->get_widget_derived("load_plugin_win", _load_plugin_win); - xml->get_widget_derived("load_patch_win", _load_patch_win); - xml->get_widget_derived("load_remote_patch_win", _load_remote_patch_win); - xml->get_widget_derived("upload_patch_win", _upload_patch_win); - xml->get_widget_derived("new_subpatch_win", _new_subpatch_win); - xml->get_widget_derived("load_subpatch_win", _load_subpatch_win); - xml->get_widget_derived("node_properties_win", _node_properties_win); - xml->get_widget_derived("patch_properties_win", _patch_properties_win); -} - - -WindowFactory::~WindowFactory() -{ - for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) - delete i->second; - - for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i) - delete i->second; - -} - - -void -WindowFactory::clear() -{ - for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) - delete i->second; - - _patch_windows.clear(); - - for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i) - delete i->second; - - _control_windows.clear(); -} - - -/** Returns the number of Patch windows currently visible. - */ -size_t -WindowFactory::num_open_patch_windows() -{ - size_t ret = 0; - for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) - if (i->second->is_visible()) - ++ret; - - return ret; -} - - - -PatchWindow* -WindowFactory::patch_window(SharedPtr patch) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - return (w == _patch_windows.end()) ? NULL : w->second; -} - - -NodeControlWindow* -WindowFactory::control_window(SharedPtr node) -{ - ControlWindowMap::iterator w = _control_windows.find(node->path()); - - return (w == _control_windows.end()) ? NULL : w->second; -} - - -/** Present a PatchWindow for a Patch. - * - * If @a preferred is not NULL, it will be set to display @a patch if the patch - * does not already have a visible window, otherwise that window will be presented and - * @a preferred left unmodified. - */ -void -WindowFactory::present_patch(SharedPtr patch, PatchWindow* preferred, SharedPtr view) -{ - assert( !view || view->patch() == patch); - - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) { - (*w).second->present(); - } else if (preferred) { - w = _patch_windows.find(preferred->patch()->path()); - assert((*w).second == preferred); - - preferred->set_patch(patch, view); - _patch_windows.erase(w); - _patch_windows[patch->path()] = preferred; - preferred->present(); - - } else { - PatchWindow* win = new_patch_window(patch, view); - win->present(); - } -} - - -PatchWindow* -WindowFactory::new_patch_window(SharedPtr patch, SharedPtr view) -{ - assert( !view || view->patch() == patch); - - Glib::RefPtr xml = GladeFactory::new_glade_reference("patch_win"); - - PatchWindow* win = NULL; - xml->get_widget_derived("patch_win", win); - assert(win); - - win->set_patch(patch, view); - _patch_windows[patch->path()] = win; - - win->signal_delete_event().connect(sigc::bind<0>( - sigc::mem_fun(this, &WindowFactory::remove_patch_window), win)); - - return win; -} - - -bool -WindowFactory::remove_patch_window(PatchWindow* win, GdkEventAny* ignored) -{ - if (_patch_windows.size() <= 1) { - Gtk::MessageDialog d(*win, "This is the last remaining open patch " - "window. Closing this window will exit Ingenuity (the engine will " - "remain running).\n\nAre you sure you want to quit?", - true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); - int ret = d.run(); - if (ret == Gtk::RESPONSE_CLOSE) - App::instance().quit(); - else - return true; - } - - PatchWindowMap::iterator w = _patch_windows.find(win->patch()->path()); - - assert((*w).second == win); - _patch_windows.erase(w); - - delete win; - - return false; -} - - -void -WindowFactory::present_controls(SharedPtr node) -{ - NodeControlWindow* win = control_window(node); - - if (win) { - win->present(); - } else { - win = new_control_window(node); - win->present(); - } -} - - -NodeControlWindow* -WindowFactory::new_control_window(SharedPtr node) -{ - size_t poly = 1; - if (node->polyphonic()) - poly = ((PatchModel*)node->parent().get())->poly(); - - NodeControlWindow* win = new NodeControlWindow(node, poly); - - _control_windows[node->path()] = win; - - win->signal_delete_event().connect(sigc::bind<0>( - sigc::mem_fun(this, &WindowFactory::remove_control_window), win)); - - return win; -} - - -bool -WindowFactory::remove_control_window(NodeControlWindow* win, GdkEventAny* ignored) -{ - ControlWindowMap::iterator w = _control_windows.find(win->node()->path()); - - assert((*w).second == win); - _control_windows.erase(w); - - delete win; - - return true; -} - - -void -WindowFactory::present_load_plugin(SharedPtr patch, MetadataMap data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_plugin_win->set_transient_for(*w->second); - - _load_plugin_win->present(patch, data); -} - - -void -WindowFactory::present_load_patch(SharedPtr patch, MetadataMap data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_patch_win->set_transient_for(*w->second); - - _load_patch_win->set_merge(); // Import is the only choice - - _load_patch_win->present(patch, data); -} - - -void -WindowFactory::present_load_remote_patch(SharedPtr patch, MetadataMap data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_remote_patch_win->set_transient_for(*w->second); - - _load_remote_patch_win->set_merge(); // Import is the only choice - - _load_remote_patch_win->present(patch, data); -} - - -void -WindowFactory::present_upload_patch(SharedPtr patch) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _upload_patch_win->set_transient_for(*w->second); - - _upload_patch_win->present(patch); -} - - -void -WindowFactory::present_new_subpatch(SharedPtr patch, MetadataMap data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _new_subpatch_win->set_transient_for(*w->second); - - _new_subpatch_win->present(patch, data); -} - - -void -WindowFactory::present_load_subpatch(SharedPtr patch, MetadataMap data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_subpatch_win->set_transient_for(*w->second); - - _load_subpatch_win->present(patch, data); -} - - -void -WindowFactory::present_rename(SharedPtr object) -{ - PatchWindowMap::iterator w = _patch_windows.find(object->path()); - - if (w != _patch_windows.end()) - _rename_win->set_transient_for(*w->second); - - _rename_win->present(object); -} - - -void -WindowFactory::present_properties(SharedPtr node) -{ - SharedPtr patch = PtrCast(node); - if (patch) { - - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - if (w != _patch_windows.end()) - _patch_properties_win->set_transient_for(*w->second); - - _patch_properties_win->present(patch); - - } else { - - PatchWindowMap::iterator w = _patch_windows.find(node->parent()->path()); - if (w != _patch_windows.end()) - _node_properties_win->set_transient_for(*w->second); - - _node_properties_win->present(node); - } -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/WindowFactory.h b/src/progs/ingenuity/WindowFactory.h deleted file mode 100644 index 085ff9b6..00000000 --- a/src/progs/ingenuity/WindowFactory.h +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef WINDOW_FACTORY_H -#define WINDOW_FACTORY_H - -#include -#include -#include -#include "client/PatchModel.h" -#include "PatchView.h" - -using Ingen::Client::PatchModel; - -namespace Ingenuity { - -class PatchWindow; -class NodeControlWindow; -class NodePropertiesWindow; -class PatchPropertiesWindow; -class LoadPatchWindow; -class LoadRemotePatchWindow; -class UploadPatchWindow; -class RenameWindow; - - -/** Manager/Factory for all windows. - * - * This serves as a nice centralized spot for all window management issues, - * as well as an enumeration of all the windows in Ingenuity (the goal being - * to reduce that number as much as possible). - */ -class WindowFactory { -public: - WindowFactory(); - ~WindowFactory(); - - size_t num_open_patch_windows(); - - PatchWindow* patch_window(SharedPtr patch); - NodeControlWindow* control_window(SharedPtr node); - - void present_patch(SharedPtr patch, - PatchWindow* preferred = NULL, - SharedPtr patch = SharedPtr()); - - void present_controls(SharedPtr node); - - void present_load_plugin(SharedPtr patch, MetadataMap data = MetadataMap()); - void present_load_patch(SharedPtr patch, MetadataMap data = MetadataMap()); - void present_load_remote_patch(SharedPtr patch, MetadataMap data = MetadataMap()); - void present_upload_patch(SharedPtr patch); - void present_new_subpatch(SharedPtr patch, MetadataMap data = MetadataMap()); - void present_load_subpatch(SharedPtr patch, MetadataMap data = MetadataMap()); - void present_rename(SharedPtr object); - void present_properties(SharedPtr node); - - bool remove_patch_window(PatchWindow* win, GdkEventAny* ignored = NULL); - - void clear(); - -private: - typedef std::map PatchWindowMap; - typedef std::map ControlWindowMap; - - PatchWindow* new_patch_window(SharedPtr patch, SharedPtr view); - - - NodeControlWindow* new_control_window(SharedPtr node); - bool remove_control_window(NodeControlWindow* win, GdkEventAny* ignored); - - PatchWindowMap _patch_windows; - ControlWindowMap _control_windows; - - LoadPluginWindow* _load_plugin_win; - LoadPatchWindow* _load_patch_win; - LoadRemotePatchWindow* _load_remote_patch_win; - UploadPatchWindow* _upload_patch_win; - NewSubpatchWindow* _new_subpatch_win; - LoadSubpatchWindow* _load_subpatch_win; - NodePropertiesWindow* _node_properties_win; - PatchPropertiesWindow* _patch_properties_win; - RenameWindow* _rename_win; -}; - -} - -#endif // WINDOW_FACTORY_H diff --git a/src/progs/ingenuity/cmdline.c b/src/progs/ingenuity/cmdline.c deleted file mode 100644 index 85c580d5..00000000 --- a/src/progs/ingenuity/cmdline.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - File autogenerated by gengetopt version 2.10 - generated with the following command: - gengetopt - - The developers of gengetopt consider the fixed text that goes in all - gengetopt output files to be in the public domain: - we make no copyright claims on it. -*/ - - -#include -#include -#include - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "getopt.h" - -#include "cmdline.h" - -void -cmdline_parser_print_version (void) -{ - printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION); -} - -void -cmdline_parser_print_help (void) -{ - cmdline_parser_print_version (); - printf("\n" - "Usage: %s [OPTIONS]...\n", CMDLINE_PARSER_PACKAGE); - printf(" -h --help Print help and exit\n"); - printf(" -V --version Print version and exit\n"); - printf(" -uSTRING --engine-url=STRING Ingen OSC URL to connect to\n"); - printf(" -pINT --client-port=INT Client port to listen on\n"); -} - - -static char *gengetopt_strdup (const char *s); - -/* gengetopt_strdup() */ -/* strdup.c replacement of strdup, which is not standard */ -char * -gengetopt_strdup (const char *s) -{ - char *result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} - -int -cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) -{ - int c; /* Character of the parsed option. */ - int missing_required_options = 0; - - args_info->help_given = 0 ; - args_info->version_given = 0 ; - args_info->engine_url_given = 0 ; - args_info->client_port_given = 0 ; -#define clear_args() { \ - args_info->engine_url_arg = NULL; \ -} - - clear_args(); - - optarg = 0; - optind = 1; - opterr = 1; - optopt = '?'; - - while (1) - { - int option_index = 0; - char *stop_char; - - static struct option long_options[] = { - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { "engine-url", 1, NULL, 'u' }, - { "client-port", 1, NULL, 'p' }, - { NULL, 0, NULL, 0 } - }; - - stop_char = 0; - c = getopt_long (argc, argv, "hVu:p:", long_options, &option_index); - - if (c == -1) break; /* Exit from `while (1)' loop. */ - - switch (c) - { - case 'h': /* Print help and exit. */ - clear_args (); - cmdline_parser_print_help (); - exit (EXIT_SUCCESS); - - case 'V': /* Print version and exit. */ - clear_args (); - cmdline_parser_print_version (); - exit (EXIT_SUCCESS); - - case 'u': /* Ingen OSC URL to connect to. */ - if (args_info->engine_url_given) - { - fprintf (stderr, "%s: `--engine-url' (`-u') option given more than once\n", CMDLINE_PARSER_PACKAGE); - clear_args (); - exit (EXIT_FAILURE); - } - args_info->engine_url_given = 1; - args_info->engine_url_arg = gengetopt_strdup (optarg); - break; - - case 'p': /* Client port to listen on. */ - if (args_info->client_port_given) - { - fprintf (stderr, "%s: `--client-port' (`-p') option given more than once\n", CMDLINE_PARSER_PACKAGE); - clear_args (); - exit (EXIT_FAILURE); - } - args_info->client_port_given = 1; - args_info->client_port_arg = strtol (optarg,&stop_char,0); - break; - - - case 0: /* Long option with no short option */ - - case '?': /* Invalid option. */ - /* `getopt_long' already printed an error message. */ - exit (EXIT_FAILURE); - - default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c\n", CMDLINE_PARSER_PACKAGE, c); - abort (); - } /* switch */ - } /* while */ - - - if ( missing_required_options ) - exit (EXIT_FAILURE); - - return 0; -} diff --git a/src/progs/ingenuity/cmdline.ggo b/src/progs/ingenuity/cmdline.ggo deleted file mode 100644 index 432fb646..00000000 --- a/src/progs/ingenuity/cmdline.ggo +++ /dev/null @@ -1,7 +0,0 @@ -# Process this file with gengetopt -u to generate the necessary code (in cmdline.h, cmdline.c) - -package "ingenuity - A GUI client for the Ingen realtime audio processor" - -option "engine-url" u "Ingen OSC URL to connect to" string no -option "client-port" p "Client port to listen on" int no - diff --git a/src/progs/ingenuity/cmdline.h b/src/progs/ingenuity/cmdline.h deleted file mode 100644 index dca25a89..00000000 --- a/src/progs/ingenuity/cmdline.h +++ /dev/null @@ -1,45 +0,0 @@ -/* cmdline.h */ - -/* File autogenerated by gengetopt version 2.10 */ - -#ifndef CMDLINE_H -#define CMDLINE_H - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef CMDLINE_PARSER_PACKAGE -#define CMDLINE_PARSER_PACKAGE "ingenuity - A GUI client for the Ingen realtime audio processor" -#endif - -#ifndef CMDLINE_PARSER_VERSION -#define CMDLINE_PARSER_VERSION VERSION -#endif - -struct gengetopt_args_info -{ - char * engine_url_arg; /* Ingen OSC URL to connect to. */ - int client_port_arg; /* Client port to listen on. */ - - int help_given ; /* Whether help was given. */ - int version_given ; /* Whether version was given. */ - int engine_url_given ; /* Whether engine-url was given. */ - int client_port_given ; /* Whether client-port was given. */ - -} ; - -int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info); - -void cmdline_parser_print_help(void); -void cmdline_parser_print_version(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CMDLINE_H */ diff --git a/src/progs/ingenuity/ingen.svg b/src/progs/ingenuity/ingen.svg deleted file mode 100644 index a15ed7e7..00000000 --- a/src/progs/ingenuity/ingen.svg +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - diff --git a/src/progs/ingenuity/ingenuity.desktop b/src/progs/ingenuity/ingenuity.desktop deleted file mode 100644 index 0db837dd..00000000 --- a/src/progs/ingenuity/ingenuity.desktop +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Name=Ingenuity -Version=0.4.0pre -Comment=Create synthesizers and effects processors in a modular environment -Exec=ingenuity -Terminal=false -Icon=ingen-icon.svg -Type=Application -Categories=Application;AudioVideo;Sound;Audio diff --git a/src/progs/ingenuity/ingenuity.desktop.in b/src/progs/ingenuity/ingenuity.desktop.in deleted file mode 100644 index 40fc7e56..00000000 --- a/src/progs/ingenuity/ingenuity.desktop.in +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Name=Ingenuity -Version=@PACKAGE_VERSION@ -Comment=Create synthesizers and effects processors in a modular environment -Exec=ingenuity -Terminal=false -Icon=ingen-icon.svg -Type=Application -Categories=Application;AudioVideo;Sound;Audio diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade deleted file mode 100644 index 6eaf300e..00000000 --- a/src/progs/ingenuity/ingenuity.glade +++ /dev/null @@ -1,3044 +0,0 @@ - - - - - - Ingenuity - 640 - 480 - ingen.svg - - - True - - - True - - - True - _File - True - - - - - True - Load a patch into the current patch (merge with existing contents). - _Import... - True - - - - - True - gtk-open - 1 - - - - - - - True - Import a patch from a URI - Import _Location... - True - - - - - True - gtk-open - 1 - - - - - - - True - - - - - True - Save this patch - gtk-save - True - True - - - - - - True - Save this patch to a specific file name - Save _As... - True - - - - True - gtk-save-as - 1 - - - - - - - True - _Upload... - True - - - - - True - gtk-network - 1 - - - - - - - True - - - - - True - Configure OmGtk - Confi_guration... - True - - - - True - gtk-preferences - 1 - - - - - - - True - - - - - True - Close this window (patch will not be destroyed) - gtk-close - True - True - - - - - - True - - - - - True - Quit Ingenuity (engine may continue running) - gtk-quit - True - True - - - - - - - - - - True - _Edit - True - - - - - True - Remove all objects from patch - gtk-clear - True - True - - - - - - True - - - - - True - False - gtk-cut - True - True - - - - - - True - gtk-copy - True - True - - - - - - True - False - gtk-paste - True - True - - - - - - True - gtk-delete - True - True - - - - - - - - - - True - _Patch - True - - - - - True - gtk-fullscreen - True - True - - - - - - True - - - - - True - Automatically arrange canvas - _Arrange - True - - - - True - gtk-sort-ascending - 1 - - - - - - - True - View/Edit controls for this patch - _Controls... - True - - - - - True - gtk-preferences - 1 - - - - - - - True - View/Edit properties for this patch - _Properties... - True - - - - - True - gtk-properties - 1 - - - - - - - True - Destoy this patch (remove it from the engine) - _Destroy - True - - - - True - gtk-delete - 1 - - - - - - - - - - - True - _Windows - True - - - - - - True - Connect to, Disconnect from, or Launch Engine - _Engine... - True - - - - - True - gtk-execute - 1 - - - - - - - True - View all patches in the engine as a heirarchial list - _Patch Tree... - True - - - - - True - gtk-index - 1 - - - - - - - True - View error messages from the engine - _Messages... - True - - - - - True - gtk-info - 1 - - - - - - - - - - - True - _Help - True - - - - - - True - Right-click the canvas to add objects - True - - - - True - gtk-info - 1 - - - - - - - True - - - - - True - gtk-about - True - True - - - - - - - - - - False - False - - - - - True - True - GTK_POLICY_NEVER - GTK_POLICY_NEVER - - - True - GTK_SHADOW_NONE - - - - - - - - 1 - - - - - - - 8 - Load Plugin - GTK_WIN_POS_CENTER_ON_PARENT - 640 - 480 - ingen.svg - - - True - 1 - - - True - True - 2 - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - - - True - True - All plugins available for loading - 2 - True - True - - - - - - - True - 3 - 3 - 12 - - - True - True - Clear filter text (show all plugins) - gtk-clear - True - - - 2 - 3 - GTK_FILL - - - - - - True - Name contains: - - - GTK_FILL - - - - - - True - True - True - Search string to filter plugin list - * - - - 1 - 2 - 6 - - - - - True - False - True - Add selected plugin to patch - gtk-add - True - - - 2 - 3 - 2 - 3 - GTK_FILL - - - - - - True - - - True - True - Name of new Module - * - - - - - True - True - Polyphonic - True - True - True - - - False - False - 8 - 1 - - - - - 1 - 2 - 2 - 3 - GTK_FILL - GTK_FILL - 6 - - - - - True - - - 2 - 3 - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - True - 1 - Node Name: - True - - - 2 - 3 - GTK_FILL - - - - - - False - False - 1 - - - - - - - 320 - 8 - Create Subpatch - GTK_WIN_POS_CENTER_ON_PARENT - ingen.svg - GDK_WINDOW_TYPE_HINT_DIALOG - - - True - - - True - 2 - 2 - - - True - True - True - * - True - - - 1 - 2 - - 4 - - - - - True - True - 1 0 100 1 10 10 - 1 - - - 1 - 2 - 1 - 2 - GTK_FILL - - 4 - - - - - True - 0 - Polyphony: - - - 1 - 2 - GTK_FILL - GTK_EXPAND - 5 - - - - - True - 0 - Name: - - - GTK_FILL - GTK_EXPAND - 5 - - - - - - - True - True - - - False - False - 1 - - - - - True - 4 - GTK_BUTTONBOX_END - - - True - True - gtk-cancel - True - - - - - True - True - True - True - - - True - 0 - 0 - - - True - 2 - - - True - gtk-ok - - - False - False - - - - - True - Create - True - - - False - False - 1 - - - - - - - - - 1 - - - - - 2 - - - - - - - Load Subpatch - GTK_WIN_POS_CENTER_ON_PARENT - ingen.svg - GDK_WINDOW_TYPE_HINT_DIALOG - - - True - 24 - - - True - 2 - 4 - 12 - 4 - - - True - - - True - True - Specify the name for the new patch - Specify: - True - True - load_subpatch_name_from_file_radio - - - False - False - - - - - True - False - True - Specify the name for the new patch - * - True - - - False - 1 - - - - - 3 - 4 - GTK_FILL - - - - - True - 0 - - - 2 - 3 - GTK_FILL - - - - - - True - True - Set polyphony to the same value as the parent (containing) patch - Same as parent (?) - True - True - load_subpatch_poly_from_file_radio - - - 2 - 3 - 1 - 2 - GTK_FILL - - - - - - True - - - True - True - Specify a custom polyphony value for new patch - Specify: - True - True - load_subpatch_poly_from_file_radio - - - False - False - - - - - True - False - True - Specify a custom polyphony value for new patch - 1 0 1000 1 10 10 - 1 - - - False - 1 - - - - - 3 - 4 - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - True - Use the polyphony value stored in the patch file - Load from file - True - True - True - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - - True - True - Use the name stored in the patch file - Load from file - True - True - True - - - 1 - 2 - GTK_FILL - - - - - - True - 0 - <b>Polyphony: </b> - True - - - 1 - 2 - GTK_FILL - - - - - - True - 0 - <b>Name: </b> - True - - - GTK_FILL - - - - - - False - 2 - - - - - True - GTK_BUTTONBOX_END - - - True - True - True - gtk-cancel - True - -6 - - - - - True - True - True - True - gtk-open - True - -5 - - - 1 - - - - - False - GTK_PACK_END - - - - - - - Load Patch - GTK_WIN_POS_CENTER_ON_PARENT - ingen.svg - GDK_WINDOW_TYPE_HINT_DIALOG - - - 24 - - - True - 1 - 4 - 12 - 4 - - - True - - - True - True - Specify: - True - True - load_patch_poly_from_current_radio - - - False - False - - - - - True - False - True - Specify a custom polyphony value for new patch - 1 0 100 1 10 10 - 1 - - - False - 1 - - - - - 3 - 4 - GTK_FILL - GTK_FILL - - - - - True - True - Use the polyphony value stored in the patch file - Load from file - True - True - load_patch_poly_from_current_radio - - - 2 - 3 - GTK_FILL - - - - - - True - True - Use the same polyphony as the current patch - Keep current - True - True - True - - - 1 - 2 - GTK_FILL - - - - - - True - 0 - <b>Polyphony: </b> - True - - - GTK_FILL - - - - - - False - 2 - - - - - True - GTK_BUTTONBOX_END - - - True - True - True - gtk-cancel - True - -6 - - - - - True - True - True - True - gtk-open - True - -5 - - - 1 - - - - - False - GTK_PACK_END - - - - - - - window1 - - - True - 4 - 2 - - - - - - - - - - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - 0 - 4 - 4 - <b>Name</b> - True - True - - - False - False - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 1 - 1 - 0 - 0 - 2 - 2 - 2 - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - 0 -9.9999999999999999e+45 1.0000000000000001e+63 1 10 10 - 4 - - - - - 1 - - - - - False - False - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 -1e+113 1e+137 0 0 0 - 63 - False - - - False - 1 - - - - - 3 - 4 - - - - - True - - - 1 - 2 - GTK_FILL - - - - - True - - - True - - - True - GTK_TOOLBAR_BOTH_HORIZ - - - True - - - True - - - True - GTK_SHADOW_NONE - - - - - - - - - - False - False - - - - - True - - - True - - - - - - False - - - - - - - True - False - - - True - - - False - False - - - - - True - Enable DSP processing - True - gtk-execute - True - - - False - - - - - True - - - True - 4 - gtk-copy - - - - - False - False - - - - - True - - - True - True - 1 0 100 1 10 10 - 1 - - - - - False - False - - - - - True - - - False - False - - - - - True - Save patch to a file - gtk-save - - - False - - - - - True - - - False - False - - - - - True - Clear (Destroy all children) - True - gtk-clear - - - False - - - - - True - Destroy this patch - gtk-delete - - - False - - - - - True - - - False - False - - - - - True - Refresh view - gtk-refresh - - - False - - - - - True - Zoom to normal size - True - gtk-zoom-100 - - - False - - - - - True - Fit patch to window - True - gtk-zoom-fit - - - False - - - - - False - 1 - - - - - False - False - - - - - True - True - 1 - GTK_SHADOW_IN - - - - - - 1 - - - - - 2 - 3 - GTK_FILL - - - - - True - - - True - 0 - - - True - True - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - - - True - GTK_SHADOW_NONE - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - - - - - - - - True - True - - - True - Apply changed controls to all voices - All Voices - True - True - - - False - False - - - - - True - 5 - - - True - True - Apply changed controls to one voice only - Specific Voice: - True - True - control_panel_all_voices_radio - - - False - False - - - - - True - False - True - Voice control changes are applied to - 1 1 100 1 10 10 - 1 - True - - - 1 - - - - - False - False - 1 - - - - - False - 5 - 1 - - - - - - - - - 400 - 180 - 8 - Messages - Ingenuity - ingen.svg - - - True - 6 - - - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - - - True - True - Error messages from the engine since the last time "Clear" was pressed - 5 - 5 - False - GTK_WRAP_WORD - 5 - 5 - False - False - - - - - - - True - 6 - GTK_BUTTONBOX_END - - - True - False - True - True - gtk-clear - True - - - - - True - True - gtk-close - True - - - 1 - - - - - False - 1 - - - - - - - 8 - Configuration - Ingenuity - ingen.svg - - - True - 6 - - - True - 2 - 2 - - - True - 0 - - - 1 - 2 - GTK_FILL - - - - - - True - <i>Example: /foo/bar:/home/john/patches:/usr/share/om/patches</i> - True - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - - True - True - * - - - 1 - 2 - - - - - - True - <b>Patch Search Path: </b> - True - - - GTK_FILL - - - - - - False - - - - - True - 6 - GTK_BUTTONBOX_END - - - True - True - Save these settings for future sessions - gtk-save - True - - - - - True - True - gtk-cancel - True - - - 1 - - - - - True - True - Apply these settings to this session only - gtk-ok - True - - - 2 - - - - - False - 1 - - - - - - - 400 - 200 - 8 - Patch Description - GTK_WIN_POS_CENTER_ON_PARENT - ingen.svg - - - True - 6 - - - True - 5 - - - True - Author: - - - False - False - - - - - True - True - * - - - 1 - - - - - False - False - - - - - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - - - True - True - A short description of the patch to be included in the patch file - GTK_WRAP_WORD - - - - - 1 - - - - - True - 5 - GTK_BUTTONBOX_END - - - True - True - True - gtk-cancel - True - - - - - True - True - True - Apply these changes to be saved the next time the patch is saved - gtk-ok - True - - - 1 - - - - - False - False - 2 - - - - - - - 250 - Rename - GTK_WIN_POS_CENTER_ON_PARENT - ingen.svg - - - True - 5 - - - True - - - True - New name: - - - False - False - - - - - True - True - * - True - - - 1 - - - - - - - True - True - - - False - 6 - 1 - - - - - True - 5 - GTK_BUTTONBOX_END - - - True - True - True - gtk-cancel - True - - - - - True - True - True - True - - - True - 0 - 0 - - - True - 2 - - - True - gtk-ok - - - False - False - - - - - True - Rename - True - - - False - False - 1 - - - - - - - - - 1 - - - - - False - 2 - - - - - - - 6 - Node Properties - Ingenuity - ingen.svg - - - True - - - True - 0 - <b>Node</b> - True - - - False - False - - - - - True - 12 - 6 - - - True - 4 - - - True - Path: - - - False - False - - - - - True - - - - - False - False - 1 - - - - - False - False - - - - - True - False - True - Polyphonic - True - True - - - False - False - 1 - - - - - 6 - 1 - - - - - 240 - True - 0 - <b>Plugin</b> - True - - - False - False - 2 - - - - - True - 12 - 3 - 2 - 10 - 6 - - - True - 0 - - - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - - True - 0 - Name: - - - 2 - 3 - GTK_FILL - - - - - - True - 0 - - - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - - True - 0 - URI: - - - 1 - 2 - GTK_FILL - - - - - - True - 0 - Type: - - - GTK_FILL - - - - - - True - 0 - - - - - 1 - 2 - GTK_FILL - - - - - - 3 - - - - - - - True - GDK_WINDOW_TYPE_HINT_NORMAL - Ingenuity - Copyright (C) 2005-2007 Dave Robillard <http://drobilla.net> - A graphical client for the Ingen audio system - http://drobilla.net/software/ingen - Licensed under the GNU GPL, Version 2. - -See COPYING file included with this distribution, or http://www.gnu.org/licenses/gpl.txt for more information - Author: - Dave Robillard <dave@drobilla.net> - -Contributors: - Lars Luthman - DSSI enhancements, bugfixes - Mario Lang - SuperCollider bindings, bugfixes - Leonard Ritter - Python bindings - - translator-credits - Usability / UI Design: - Thorsten Wilms - ingen.svg - True - - - - - - - False - GTK_PACK_END - - - - - - - 320 - 340 - 8 - Patches - Ingenuity - ingen.svg - - - True - True - 3 - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - - - True - True - All patches loaded in the engine - True - - - - - - - 6 - Engine - Ingenuity - False - ingen.svg - GDK_WINDOW_TYPE_HINT_DIALOG - - - True - 6 - - - True - - - True - - - True - 12 - gtk-disconnect - 3 - - - False - - - - - True - 5 - True - - - True - 0.10000000149 - - - - False - False - - - - - True - 0 - Not Connected - - - False - 1 - - - - - 1 - - - - - False - - - - - True - - - 4 - 1 - - - - - True - 3 - 2 - 8 - - - True - 0 - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - - True - False - True - Use internal engine - True - True - connect_server_radiobutton - - - 2 - 3 - GTK_FILL - - - - - - True - True - Launch and connect to server on port: - True - True - connect_server_radiobutton - - - 1 - 2 - GTK_FILL - - - - - - True - True - Connect to running server at: - True - True - - - GTK_FILL - - - - - - True - - - True - True - * - True - 28 - osc.udp://localhost:16180 - - - - - 1 - 2 - GTK_FILL - GTK_FILL - 8 - - - - - True - - - True - False - True - 16180 1 65535 1 10 10 - 1 - True - - - False - False - - - - - 1 - 2 - 1 - 2 - GTK_FILL - 8 - - - - - 2 - - - - - 2 - - - - - True - GTK_BUTTONBOX_END - - - True - True - True - gtk-quit - True - - - - - True - False - True - True - gtk-disconnect - True - -6 - - - 1 - - - - - True - True - True - True - gtk-connect - True - -6 - - - 2 - - - - - False - False - GTK_PACK_END - - - - - - - True - - - True - Input - True - - - - - True - Add an audio input to this patch - Audio - True - - - - - - True - Add a control input (and a control slider for it) to this patch - Control - True - - - - - - True - Add a MIDI input to this patch - MIDI - True - - - - - - - - True - gtk-connect - 1 - - - - - - - True - Output - True - - - - - True - Add an audio output to this patch - Audio - True - - - - - - True - Add a control output to this patch - Control - True - - - - - - True - Add a MIDI output to this patch - MIDI - True - - - - - - - - True - gtk-connect - 1 - - - - - - - True - Load a plugin as a child of this patch - _Plugin... - True - - - - True - gtk-execute - 1 - - - - - - - True - Load a patch as a child of this patch - _Load Patch... - True - - - - True - gtk-open - 1 - - - - - - - True - Create a new (empty) patch as a child of this patch - _New Patch... - True - - - - True - gtk-new - 1 - - - - - - - 8 - Load Remote Patch - GDK_WINDOW_TYPE_HINT_DIALOG - - - True - 8 - - - True - 8 - - - True - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - - - True - True - - - - - - - True - - - True - URI: - - - False - False - - - - - True - True - * - 78 - - - 1 - - - - - False - 1 - - - - - 2 - - - - - True - GTK_BUTTONBOX_END - - - True - True - True - gtk-cancel - True - -6 - - - - - True - False - True - True - True - gtk-open - True - -5 - - - 1 - - - - - False - GTK_PACK_END - - - - - - - 8 - Upload Patch - False - GDK_WINDOW_TYPE_HINT_DIALOG - - - True - 9 - - - True - 2 - 2 - 8 - - - True - 0 - Short Name: - - - 1 - 2 - GTK_FILL - - - - - - True - 0 - Symbol: - - - GTK_FILL - - - - - - True - True - Enter a short name for this patch, e.g. "Mega Synth" - * - True - - - 1 - 2 - 1 - 2 - - - - - - True - True - Enter a short name suitable for use as an identifier or filename. - -The first character must be one of _, a-z or A-Z and subsequenct characters can be from _, a-z, A-Z or 0-9. - - * - True - - - 1 - 2 - - - - - - 2 - - - - - True - 4 - Succesfully uploaded patches will be available immediately in the remote patch browser. - -By uploading patches, you agree to license them under the Creative Commons Attribution-Share Alike 3.0 License. - -Thank you for contributing. - True - - - False - False - 3 - - - - - True - Upload progress - 0.10000000149 - - - False - False - 4 - - - - - True - GTK_BUTTONBOX_END - - - True - True - True - gtk-close - True - -7 - - - - - True - False - True - True - True - -5 - - - True - 0 - 0 - - - True - 2 - - - True - gtk-ok - - - False - False - - - - - True - Upload - True - - - False - False - 1 - - - - - - - - - 1 - - - - - False - GTK_PACK_END - - - - - - - - - True - _Properties... - True - - - - True - gtk-properties - 1 - - - - - - - 8 - GTK_WINDOW_POPUP - Port Properties - Ingenuity - False - GTK_WIN_POS_MOUSE - True - GDK_WINDOW_TYPE_HINT_DIALOG - - - True - 8 - - - True - 2 - 2 - 2 - 4 - - - True - 0 - Maximum Value: - - - 1 - 2 - GTK_FILL - - - - - - True - 0 - Minimum Value: - - - GTK_FILL - - - - - - True - True - 1 -99999 99999 1 10 10 - 1 - 5 - True - - - 1 - 2 - 1 - 2 - - - - - - True - True - 0 -100000000 100000000 1 10 10 - 1 - 5 - True - - - 1 - 2 - - - - - - 2 - - - - - True - GTK_BUTTONBOX_END - - - True - True - True - gtk-cancel - True - -6 - - - - - True - True - True - True - gtk-ok - True - -5 - - - 1 - - - - - False - GTK_PACK_END - - - - - - diff --git a/src/progs/ingenuity/ingenuity.gladep b/src/progs/ingenuity/ingenuity.gladep deleted file mode 100644 index 7cd9c6ce..00000000 --- a/src/progs/ingenuity/ingenuity.gladep +++ /dev/null @@ -1,9 +0,0 @@ - - - - - Ingenuity - ingenuity - C++ - FALSE - diff --git a/src/progs/ingenuity/ingenuity_dev b/src/progs/ingenuity/ingenuity_dev deleted file mode 100755 index b77d2fe6..00000000 --- a/src/progs/ingenuity/ingenuity_dev +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env sh - -INGEN_MODULE_PATH=../../libs/engine/.libs:../../libs/serialisation/.libs ./ingenuity diff --git a/src/progs/ingenuity/main.cpp b/src/progs/ingenuity/main.cpp deleted file mode 100644 index 8170833f..00000000 --- a/src/progs/ingenuity/main.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "cmdline.h" -#include "ConnectWindow.h" -#include "App.h" -#include "Configuration.h" -#ifdef HAVE_LASH - #include "LashController.h" -#endif - -using namespace Ingenuity; - - -int -main(int argc, char** argv) -{ - string engine_url = "osc.udp://localhost:16180"; - int client_port = 0; - - /* **** Parse command line options **** */ - gengetopt_args_info args_info; - if (cmdline_parser (argc, argv, &args_info) != 0) - return 1; - - if (args_info.engine_url_given) - engine_url = args_info.engine_url_arg; - if (args_info.client_port_given) - client_port = args_info.client_port_arg; - - Gnome::Canvas::init(); - Gtk::Main gtk_main(argc, argv); - Gtk::Window::set_default_icon_from_file(PKGDATADIR "/ingen-icon.svg"); - - /* Instantiate all singletons */ - App::instantiate(); - - /* Load settings */ - App::instance().configuration()->load_settings(); - App::instance().configuration()->apply_settings(); - -#ifdef HAVE_LASH - lash_args_t* lash_args = lash_extract_args(&argc, &argv); - LashController* lash_controller = new LashController(lash_args); -#endif - - App::instance().connect_window()->start(); - gtk_main.run(); - - return 0; -} - diff --git a/src/progs/patch_loader/Makefile.am b/src/progs/patch_loader/Makefile.am deleted file mode 100644 index f16cc495..00000000 --- a/src/progs/patch_loader/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -EXTRA_DIST = README - -ingen_load_CXXFLAGS = -I$(top_srcdir)/src/libs -I$(top_srcdir)/src/common @LSIGCPP_CFLAGS@ @RAUL_CFLAGS@ @GLIBMM_CFLAGS@ @RASQAL_CFLAGS@ -DINGEN_MODULE_DIR=\"$(libdir)/ingen\" -ingen_load_LDADD = ../../libs/client/libingen_client.la ../../libs/module/libingen_module.la @RAUL_LIBS@ @LSIGCPP_LIBS@ @GLIBMM_LIBS@ @RASQAL_LIBS@ - -bin_PROGRAMS = ingen_load - -#ingen_load_DEPENDENCIES = ../../libs/client/libingen_client.la - -ingen_load_SOURCES = \ - patch_loader.cpp \ - cmdline.h \ - cmdline.c diff --git a/src/progs/patch_loader/README b/src/progs/patch_loader/README deleted file mode 100644 index 9f3b6f4b..00000000 --- a/src/progs/patch_loader/README +++ /dev/null @@ -1,5 +0,0 @@ -This is a stand-alone patch loader for Om. It has no user interface, it -just launches, loads the patch(es) passed as a parameter, and exits. - -Useful for loading patches from scripts, other apps, etc. or just using -Om patches without loading the GUI. diff --git a/src/progs/patch_loader/cmdline.c b/src/progs/patch_loader/cmdline.c deleted file mode 100644 index 0606cb7b..00000000 --- a/src/progs/patch_loader/cmdline.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - File autogenerated by gengetopt version 2.10 - generated with the following command: - gengetopt -u - - The developers of gengetopt consider the fixed text that goes in all - gengetopt output files to be in the public domain: - we make no copyright claims on it. -*/ - - -#include -#include -#include - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "getopt.h" - -#include "cmdline.h" - -void -cmdline_parser_print_version (void) -{ - printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION); -} - -void -cmdline_parser_print_help (void) -{ - cmdline_parser_print_version (); - printf("\n" - "Usage: %s [OPTIONS]... [FILES]...\n", CMDLINE_PARSER_PACKAGE); - printf(" -h --help Print help and exit\n"); - printf(" -V --version Print version and exit\n"); - printf(" -uSTRING --engine-url=STRING Om engine URL to connect to\n"); - printf(" -pINT --client-port=INT Client port to listen on\n"); -} - - -static char *gengetopt_strdup (const char *s); - -/* gengetopt_strdup() */ -/* strdup.c replacement of strdup, which is not standard */ -char * -gengetopt_strdup (const char *s) -{ - char *result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} - -int -cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) -{ - int c; /* Character of the parsed option. */ - int missing_required_options = 0; - - args_info->help_given = 0 ; - args_info->version_given = 0 ; - args_info->engine_url_given = 0 ; - args_info->client_port_given = 0 ; -#define clear_args() { \ - args_info->engine_url_arg = NULL; \ -} - - clear_args(); - - args_info->inputs = NULL; - args_info->inputs_num = 0; - - optarg = 0; - optind = 1; - opterr = 1; - optopt = '?'; - - while (1) - { - int option_index = 0; - char *stop_char; - - static struct option long_options[] = { - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { "engine-url", 1, NULL, 'u' }, - { "client-port", 1, NULL, 'p' }, - { NULL, 0, NULL, 0 } - }; - - stop_char = 0; - c = getopt_long (argc, argv, "hVu:p:", long_options, &option_index); - - if (c == -1) break; /* Exit from `while (1)' loop. */ - - switch (c) - { - case 'h': /* Print help and exit. */ - clear_args (); - cmdline_parser_print_help (); - exit (EXIT_SUCCESS); - - case 'V': /* Print version and exit. */ - clear_args (); - cmdline_parser_print_version (); - exit (EXIT_SUCCESS); - - case 'u': /* Om engine URL to connect to. */ - if (args_info->engine_url_given) - { - fprintf (stderr, "%s: `--engine-url' (`-u') option given more than once\n", CMDLINE_PARSER_PACKAGE); - clear_args (); - exit (EXIT_FAILURE); - } - args_info->engine_url_given = 1; - args_info->engine_url_arg = gengetopt_strdup (optarg); - break; - - case 'p': /* Client port to listen on. */ - if (args_info->client_port_given) - { - fprintf (stderr, "%s: `--client-port' (`-p') option given more than once\n", CMDLINE_PARSER_PACKAGE); - clear_args (); - exit (EXIT_FAILURE); - } - args_info->client_port_given = 1; - args_info->client_port_arg = strtol (optarg,&stop_char,0); - break; - - - case 0: /* Long option with no short option */ - - case '?': /* Invalid option. */ - /* `getopt_long' already printed an error message. */ - exit (EXIT_FAILURE); - - default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c\n", CMDLINE_PARSER_PACKAGE, c); - abort (); - } /* switch */ - } /* while */ - - - if ( missing_required_options ) - exit (EXIT_FAILURE); - - if (optind < argc) - { - int i = 0 ; - - args_info->inputs_num = argc - optind ; - args_info->inputs = - (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; - while (optind < argc) - args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ; - } - - return 0; -} diff --git a/src/progs/patch_loader/cmdline.ggo b/src/progs/patch_loader/cmdline.ggo deleted file mode 100644 index 5acd6737..00000000 --- a/src/progs/patch_loader/cmdline.ggo +++ /dev/null @@ -1,7 +0,0 @@ -# Process this file with gengetopt -u to generate the necessary code (in cmdline.h, cmdline.c) - -package "om_patch_loader - A command line patch loading client for Om" - -option "engine-url" u "Om engine URL to connect to" string no -option "client-port" p "Client port to listen on" int no - diff --git a/src/progs/patch_loader/cmdline.h b/src/progs/patch_loader/cmdline.h deleted file mode 100644 index b417c664..00000000 --- a/src/progs/patch_loader/cmdline.h +++ /dev/null @@ -1,47 +0,0 @@ -/* cmdline.h */ - -/* File autogenerated by gengetopt version 2.10 */ - -#ifndef CMDLINE_H -#define CMDLINE_H - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef CMDLINE_PARSER_PACKAGE -#define CMDLINE_PARSER_PACKAGE "om_patch_loader - A command line patch loading client for the Om realtime modular synthesizer" -#endif - -#ifndef CMDLINE_PARSER_VERSION -#define CMDLINE_PARSER_VERSION VERSION -#endif - -struct gengetopt_args_info -{ - char * engine_url_arg; /* Om engine URL to connect to. */ - int client_port_arg; /* Client port to listen on. */ - - int help_given ; /* Whether help was given. */ - int version_given ; /* Whether version was given. */ - int engine_url_given ; /* Whether engine-url was given. */ - int client_port_given ; /* Whether client-port was given. */ - - char **inputs ; /* unamed options */ - unsigned inputs_num ; /* unamed options number */ -} ; - -int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info); - -void cmdline_parser_print_help(void); -void cmdline_parser_print_version(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CMDLINE_H */ diff --git a/src/progs/patch_loader/new_patch_loader.cpp b/src/progs/patch_loader/new_patch_loader.cpp deleted file mode 100644 index cee48827..00000000 --- a/src/progs/patch_loader/new_patch_loader.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include "cmdline.h" // generated by gengetopt -#include "OSCEngineInterface.h" -#include "PatchLibrarian.h" - -using std::cout; using std::cerr; using std::endl; - -using namespace Ingen::Client; - - -int -main(int argc, char** argv) -{ - const char* engine_url = NULL; - int client_port = 0; - - /* Parse command line options */ - gengetopt_args_info args_info; - if (cmdline_parser (argc, argv, &args_info) != 0) - return 1; - - if (args_info.engine_url_given) { - engine_url = args_info.engine_url_arg; - } else { - cout << "[Main] No engine URL specified. Attempting to use osc.udp://localhost:16180" << endl; - engine_url = "osc.udp://localhost:16180"; - } - - if (args_info.client_port_given) - client_port = args_info.client_port_arg; - else - client_port = 0; // will choose a free port automatically - - OSCEngineInterface engine(engine_url); - - /* Connect to engine */ - if (!engine.attach()) { - cerr << "Unable to connect to engine" << endl; - return 1; - } - - engine.activate(); - engine.register_client(); - - /*int id = engine.get_next_request_id(); - engine.set_wait_response_id(id); - engine.load_plugins(id); - engine.wait_for_response(); - */ - engine.load_plugins(); - - // Load patches - for (uint i=0; i < args_info.inputs_num; ++i) - PatchLibrarian::load_patch(&engine, args_info.inputs[i]); - - return 0; -} diff --git a/src/progs/patch_loader/patch_loader.cpp b/src/progs/patch_loader/patch_loader.cpp deleted file mode 100644 index 57bba0e0..00000000 --- a/src/progs/patch_loader/patch_loader.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include "client/OSCEngineSender.h" -#include "client/PatchModel.h" -#include "module/Module.h" -#include "serialisation/serialisation.h" -#include "serialisation/Loader.h" -#include "cmdline.h" // generated by gengetopt - -using namespace std; -using namespace Ingen::Client; -using namespace Ingen::Serialisation; - - -int main(int argc, char** argv) -{ - const char* engine_url = NULL; - int client_port = 0; - - /* **** Parse command line options **** */ - - gengetopt_args_info args_info; - if (cmdline_parser (argc, argv, &args_info) != 0) - return 1; - - if (args_info.engine_url_given) { - engine_url = args_info.engine_url_arg; - } else { - cout << "[Main] No engine URL specified. Attempting to use osc.udp://localhost:16180" << endl; - engine_url = "osc.udp://localhost:16180"; - } - - if (args_info.client_port_given) - client_port = args_info.client_port_arg; - - - /* **** Mr. Spock.. Engage **** */ - - Raul::RDF::World rdf_world; - rdf_world.add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#"); - rdf_world.add_prefix("ingen", "http://drobilla.net/ns/ingen#"); - rdf_world.add_prefix("ingenuity", "http://drobilla.net/ns/ingenuity#"); - rdf_world.add_prefix("lv2", "http://lv2plug.in/ontology#"); - rdf_world.add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); - rdf_world.add_prefix("doap", "http://usefulinc.com/ns/doap#"); - - SharedPtr engine(new OSCEngineSender(engine_url)); - - /* Connect to engine */ - engine->attach(-1, client_port); - engine->activate(); - //engine->register_client(NULL); // FIXME - - //int id = engine->get_next_request_id(); - //engine->set_wait_response_id(id); - //engine->load_plugins(id); - //engine->wait_for_response(); - /* FIXME: Make this work like this: - * engine->load_plugins(); - * engine->wait_for_response(); - */ - - SharedPtr module = Ingen::Shared::load_module("ingen_serialisation"); - - if (!module) { - cerr << "Unable to load ingen_serialisation module, exiting." << endl; - return -1; - } - - Loader* (*new_loader)() = NULL; - - bool found = module->get_symbol("new_loader", (void*&)new_loader); - - if (!found) { - cerr << "Unable to find module entry point, exiting." << endl; - return -1; - } - - SharedPtr loader(new_loader()); - - // Load patches - for (uint i=0; i < args_info.inputs_num; ++i) { - cerr << "FIXME: load patch under root" << endl; - cerr << "Load " << args_info.inputs[i] << endl; - loader->load(engine, &rdf_world, - string("file:") + args_info.inputs[i], Path("/"), ""); - } - - return 0; -} diff --git a/src/progs/python/ingen.py b/src/progs/python/ingen.py index 5e013e5f..07698719 100644 --- a/src/progs/python/ingen.py +++ b/src/progs/python/ingen.py @@ -367,22 +367,22 @@ class Environment: for connection in self.getConnections(): print ">>> %s -> %s" % (connection.getSrcPort().getPath(), connection.getDstPort().getPath()) - #~ /om/engine_enabled - Notification engine's DSP has been enabled. + #~ /ingen/engine_enabled - Notification engine's DSP has been enabled. def __ingen__engine_enabled(self): self.enabled = True - #~ /om/engine_disabled - Notification engine's DSP has been disabled. + #~ /ingen/engine_disabled - Notification engine's DSP has been disabled. def __ingen__engine_disabled(self): self.enabled = False - #~ /om/new_node - Notification of a new node's creation. + #~ /ingen/new_node - Notification of a new node's creation. #~ * path (string) - Path of the new node #~ * polyphonic (integer-boolean) - Node is polyphonic (1 for yes, 0 for no) #~ * type (string) - Type of plugin (LADSPA, DSSI, Internal, Patch) #~ * lib-name (string) - Name of library if a plugin (ie cmt.so) #~ * plug-label (string) - Label of plugin in library (ie adsr_env) - #~ * New nodes are sent as a blob. The first message in the blob will be this one (/om/new_node), followed by a series of /om/new_port commands, followed by /om/new_node_end. + #~ * New nodes are sent as a blob. The first message in the blob will be this one (/ingen/new_node), followed by a series of /om/new_port commands, followed by /om/new_node_end. def __ingen__new_node(self,path,polyphonic,plugintype,libname,pluginlabel): node = self.getNode(path) node.setPolyphonic(polyphonic) @@ -393,13 +393,13 @@ class Environment: def __ingen__new_node_end(self): pass - #~ /om/node_removal - Notification of a node's destruction. + #~ /ingen/node_removal - Notification of a node's destruction. #~ * path (string) - Path of node (which no longer exists) def __ingen__node_removal(self,path): node = self.getNode(path) node.remove() - #~ /om/new_port - Notification of a node's destruction. + #~ /ingen/new_port - Notification of a node's destruction. #~ * path (string) - Path of new port #~ * type (string) - Type of port (CONTROL or AUDIO) @@ -420,37 +420,37 @@ class Environment: port.setMinValue(minvalue) port.setMaxValue(maxvalue) - #~ /om/port_removal - Notification of a port's destruction. + #~ /ingen/port_removal - Notification of a port's destruction. #~ * path (string) - Path of port (which no longer exists) def __ingen__port_removal(self,path): port = self.getPort(path) port.remove() - #~ /om/patch_destruction - Notification of a patch's destruction. + #~ /ingen/patch_destruction - Notification of a patch's destruction. #~ * path (string) - Path of patch (which no longer exists) def __ingen__patch_destruction(self,path): patch = self.getPatch(path) patch.remove() - #~ /om/patch_enabled - Notification a patch's DSP processing has been enabled. + #~ /ingen/patch_enabled - Notification a patch's DSP processing has been enabled. #~ * path (string) - Path of enabled patch def __ingen__patch_enabled(self,path): patch = self.getPatch(path) patch.setEnabled(True) - #~ /om/patch_disabled - Notification a patch's DSP processing has been disabled. + #~ /ingen/patch_disabled - Notification a patch's DSP processing has been disabled. #~ * path (string) - Path of disabled patch def __ingen__patch_disabled(self,path): patch = self.getPatch(path) patch.setEnabled(False) - #~ /om/new_connection - Notification a new connection has been made. + #~ /ingen/new_connection - Notification a new connection has been made. #~ * src-path (string) - Path of the source port #~ * dst-path (string) - Path of the destination port def __ingen__new_connection(self,srcpath,dstpath): self.getConnection(srcpath,dstpath) - #~ /om/disconnection - Notification a connection has been unmade. + #~ /ingen/disconnection - Notification a connection has been unmade. #~ * src-path (string) - Path of the source port #~ * dst-path (string) - Path of the destination port def __ingen__disconnection(self,srcpath,dstpath): @@ -459,7 +459,7 @@ class Environment: connection.remove() del self.connections[portpair] - #~ /om/metadata/update - Notification of a piece of metadata. + #~ /ingen/metadata/update - Notification of a piece of metadata. #~ * path (string) - Path of the object associated with metadata (can be a node, patch, or port) #~ * key (string) #~ * value (string) @@ -467,7 +467,7 @@ class Environment: object = self.getObject(path) object.setMetaData(key,value) - #~ /om/control_change - Notification the value of a port has changed + #~ /ingen/control_change - Notification the value of a port has changed #~ * path (string) - Path of port #~ * value (float) - New value of port #~ * This will only send updates for values set by clients of course - not values changing because of connections to other ports! @@ -475,7 +475,7 @@ class Environment: port = self.getPort(path) port.setValue(value) - #~ /om/new_patch - Notification of a new patch + #~ /ingen/new_patch - Notification of a new patch #~ * path (string) - Path of new patch #~ * poly (int) - Polyphony of new patch (not a boolean like new_node) def __ingen__new_patch(self,path,poly): @@ -502,7 +502,7 @@ class ClientProxy: result = self.om.sendMsgBlocking(self.name, *args) if not result: return None - if result[0] == "/om/response/ok": + if result[0] == "/ingen/response/ok": return True print "ERROR: %s" % result[1][1] return False @@ -519,7 +519,7 @@ class ClientProxy: class Client(DatagramProtocol, ClientProxy): def __init__(self): - ClientProxy.__init__(self, self, "/om") + ClientProxy.__init__(self, self, "/ingen") def startProtocol(self): self.transport.connect("127.0.0.1", 16180) @@ -550,15 +550,15 @@ class Client(DatagramProtocol, ClientProxy): os._exit(-1) def messageReceived(self, (msg, args)): - if msg == "/om/error": + if msg == "/ingen/error": print "ERROR: %r" % args return - if msg == "/om/response/ok": + if msg == "/ingen/response/ok": omcall = self.calls[args[0]] omcall.result = (msg,args) omcall.done = True return - if msg == "/om/response/error": + if msg == "/ingen/response/error": omcall = self.calls[args[0]] omcall.result = (msg,args) omcall.done = True diff --git a/src/progs/python/ingenecho.py b/src/progs/python/ingenecho.py index 7ed2cef5..1dcfc313 100644 --- a/src/progs/python/ingenecho.py +++ b/src/progs/python/ingenecho.py @@ -17,11 +17,11 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -import omsynth +import ingen import os,time,sys def main(om): - om.setEnvironment(omsynth.Environment()) + om.setEnvironment(ingen.Environment()) om.engine.activate() om.engine.register_client(om.getAddressAsString()) om.request.all_objects(om.getAddressAsString()) @@ -30,11 +30,11 @@ def main(om): time.sleep(3) om.getEnvironment().printPatch() om.getEnvironment().printConnections() - print "omecho will now monitor and mirror changes in the structure" + print "ingenecho will now monitor and mirror changes in the structure" print "hit return to exit when youre done" sys.stdin.readline() om.engine.unregister_client(om.getAddressAsString()) os._exit(0) if __name__ == "__main__": - omsynth.startClient(main) + ingen.startClient(main) diff --git a/src/progs/server/Makefile.am b/src/progs/server/Makefile.am deleted file mode 100644 index ab384494..00000000 --- a/src/progs/server/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -AM_CXXFLAGS = @RAUL_CFLAGS@ @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs -DINGEN_MODULE_DIR=\"$(libdir)/ingen\" - -MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = ingen_dev - -# -# Stand-alone engine -# -if BUILD_SERVER - -bin_PROGRAMS = ingen -ingen_LDADD = @RAUL_LIBS@ @JACK_LIBS@ @LOSC_LIBS@ @ALSA_LIBS@ @LASH_LIBS@ @SLV2_LIBS@ -lrt ../../libs/module/libingen_module.la -ingen_DEPENDENCIES = ../../libs/module/libingen_module.la - -ingen_SOURCES = \ - main.cpp \ - cmdline.h \ - cmdline.c - -endif # BUILD_SERVER - - -## -## Jack internal client -## -#if BUILD_IN_PROCESS_ENGINE -# -# -## FIXME: broken -# -# -## FIXME: Figure out how to get this properly -#omdir = $(prefix)/lib/jack -# -#om_la_CFLAGS = -fPIC -#om_LTLIBRARIES = om.la -#om_la_LDFLAGS = -module -avoid-version @JACK_LIBS@ @LOSC_LIBS@ @ALSA_LIBS@ @LASH_LIBS@ @SLV2_LIBS@ -#om_la_SOURCES = OmInProcess.cpp -# -#endif # BUILD_IN_PROCESS_ENGINE - - - - diff --git a/src/progs/server/cmdline.c b/src/progs/server/cmdline.c deleted file mode 100644 index 1e97e1ef..00000000 --- a/src/progs/server/cmdline.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - File autogenerated by gengetopt version 2.19.1 - generated with the following command: - gengetopt -u - - The developers of gengetopt consider the fixed text that goes in all - gengetopt output files to be in the public domain: - we make no copyright claims on it. -*/ - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "getopt.h" - -#include "cmdline.h" - -const char *gengetopt_args_info_purpose = ""; - -const char *gengetopt_args_info_usage = "Usage: Om - An OSC controlled realtime modular synthesizer [OPTIONS]... \n [FILES]..."; - -const char *gengetopt_args_info_description = ""; - -const char *gengetopt_args_info_help[] = { - " -h, --help Print help and exit", - " -V, --version Print version and exit", - " -p, --port=STRING OSC port to listen on (default=`16180')", - " -i, --in-jackd Run engine as in-process JACK client (default=off)", - 0 -}; - -static -void clear_given (struct gengetopt_args_info *args_info); -static -void clear_args (struct gengetopt_args_info *args_info); - -static int -cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error); - - -static char * -gengetopt_strdup (const char *s); - -static -void clear_given (struct gengetopt_args_info *args_info) -{ - args_info->help_given = 0 ; - args_info->version_given = 0 ; - args_info->port_given = 0 ; - args_info->in_jackd_given = 0 ; -} - -static -void clear_args (struct gengetopt_args_info *args_info) -{ - args_info->port_arg = gengetopt_strdup ("16180"); - args_info->port_orig = NULL; - args_info->in_jackd_flag = 0; - -} - -static -void init_args_info(struct gengetopt_args_info *args_info) -{ - args_info->help_help = gengetopt_args_info_help[0] ; - args_info->version_help = gengetopt_args_info_help[1] ; - args_info->port_help = gengetopt_args_info_help[2] ; - args_info->in_jackd_help = gengetopt_args_info_help[3] ; - -} - -void -cmdline_parser_print_version (void) -{ - printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION); -} - -void -cmdline_parser_print_help (void) -{ - int i = 0; - cmdline_parser_print_version (); - - if (strlen(gengetopt_args_info_purpose) > 0) - printf("\n%s\n", gengetopt_args_info_purpose); - - printf("\n%s\n\n", gengetopt_args_info_usage); - - if (strlen(gengetopt_args_info_description) > 0) - printf("%s\n", gengetopt_args_info_description); - - while (gengetopt_args_info_help[i]) - printf("%s\n", gengetopt_args_info_help[i++]); -} - -void -cmdline_parser_init (struct gengetopt_args_info *args_info) -{ - clear_given (args_info); - clear_args (args_info); - init_args_info (args_info); - - args_info->inputs = NULL; - args_info->inputs_num = 0; -} - -static void -cmdline_parser_release (struct gengetopt_args_info *args_info) -{ - - unsigned int i; - if (args_info->port_arg) - { - free (args_info->port_arg); /* free previous argument */ - args_info->port_arg = 0; - } - if (args_info->port_orig) - { - free (args_info->port_orig); /* free previous argument */ - args_info->port_orig = 0; - } - - for (i = 0; i < args_info->inputs_num; ++i) - free (args_info->inputs [i]); - - if (args_info->inputs_num) - free (args_info->inputs); - - clear_given (args_info); -} - -int -cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) -{ - FILE *outfile; - int i = 0; - - outfile = fopen(filename, "w"); - - if (!outfile) - { - fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); - return EXIT_FAILURE; - } - - if (args_info->help_given) { - fprintf(outfile, "%s\n", "help"); - } - if (args_info->version_given) { - fprintf(outfile, "%s\n", "version"); - } - if (args_info->port_given) { - if (args_info->port_orig) { - fprintf(outfile, "%s=\"%s\"\n", "port", args_info->port_orig); - } else { - fprintf(outfile, "%s\n", "port"); - } - } - if (args_info->in_jackd_given) { - fprintf(outfile, "%s\n", "in-jackd"); - } - - fclose (outfile); - - i = EXIT_SUCCESS; - return i; -} - -void -cmdline_parser_free (struct gengetopt_args_info *args_info) -{ - cmdline_parser_release (args_info); -} - - -/* gengetopt_strdup() */ -/* strdup.c replacement of strdup, which is not standard */ -char * -gengetopt_strdup (const char *s) -{ - char *result = NULL; - if (!s) - return result; - - result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} - -int -cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) -{ - return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); -} - -int -cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) -{ - int result; - - result = cmdline_parser_internal (argc, argv, args_info, override, initialize, check_required, NULL); - - if (result == EXIT_FAILURE) - { - cmdline_parser_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) -{ - return EXIT_SUCCESS; -} - -int -cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error) -{ - int c; /* Character of the parsed option. */ - - int error = 0; - struct gengetopt_args_info local_args_info; - - if (initialize) - cmdline_parser_init (args_info); - - cmdline_parser_init (&local_args_info); - - optarg = 0; - optind = 0; - opterr = 1; - optopt = '?'; - - while (1) - { - int option_index = 0; - char *stop_char; - - static struct option long_options[] = { - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { "port", 1, NULL, 'p' }, - { "in-jackd", 0, NULL, 'i' }, - { NULL, 0, NULL, 0 } - }; - - stop_char = 0; - c = getopt_long (argc, argv, "hVp:i", long_options, &option_index); - - if (c == -1) break; /* Exit from `while (1)' loop. */ - - switch (c) - { - case 'h': /* Print help and exit. */ - cmdline_parser_print_help (); - cmdline_parser_free (&local_args_info); - exit (EXIT_SUCCESS); - - case 'V': /* Print version and exit. */ - cmdline_parser_print_version (); - cmdline_parser_free (&local_args_info); - exit (EXIT_SUCCESS); - - case 'p': /* OSC port to listen on. */ - if (local_args_info.port_given) - { - fprintf (stderr, "%s: `--port' (`-p') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); - goto failure; - } - if (args_info->port_given && ! override) - continue; - local_args_info.port_given = 1; - args_info->port_given = 1; - if (args_info->port_arg) - free (args_info->port_arg); /* free previous string */ - args_info->port_arg = gengetopt_strdup (optarg); - if (args_info->port_orig) - free (args_info->port_orig); /* free previous string */ - args_info->port_orig = gengetopt_strdup (optarg); - break; - - case 'i': /* Run engine as in-process JACK client. */ - if (local_args_info.in_jackd_given) - { - fprintf (stderr, "%s: `--in-jackd' (`-i') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); - goto failure; - } - if (args_info->in_jackd_given && ! override) - continue; - local_args_info.in_jackd_given = 1; - args_info->in_jackd_given = 1; - args_info->in_jackd_flag = !(args_info->in_jackd_flag); - break; - - - case 0: /* Long option with no short option */ - case '?': /* Invalid option. */ - /* `getopt_long' already printed an error message. */ - goto failure; - - default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); - abort (); - } /* switch */ - } /* while */ - - - - - cmdline_parser_release (&local_args_info); - - if ( error ) - return (EXIT_FAILURE); - - if (optind < argc) - { - int i = 0 ; - int found_prog_name = 0; - /* whether program name, i.e., argv[0], is in the remaining args - (this may happen with some implementations of getopt, - but surely not with the one included by gengetopt) */ - - i = optind; - while (i < argc) - if (argv[i++] == argv[0]) { - found_prog_name = 1; - break; - } - i = 0; - - args_info->inputs_num = argc - optind - found_prog_name; - args_info->inputs = - (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; - while (optind < argc) - if (argv[optind++] != argv[0]) - args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ; - } - - return 0; - -failure: - - cmdline_parser_release (&local_args_info); - return (EXIT_FAILURE); -} diff --git a/src/progs/server/cmdline.ggo b/src/progs/server/cmdline.ggo deleted file mode 100644 index 9635a8f5..00000000 --- a/src/progs/server/cmdline.ggo +++ /dev/null @@ -1,7 +0,0 @@ -# Process this file with gengetopt -u to generate the necessary code (in cmdline.h, cmdline.c) - -package "Om - An OSC controlled realtime modular synthesizer" - -option "port" p "OSC port to listen on" string default="16180" no -option "in-jackd" i "Run engine as in-process JACK client" flag off - diff --git a/src/progs/server/cmdline.h b/src/progs/server/cmdline.h deleted file mode 100644 index 5253162c..00000000 --- a/src/progs/server/cmdline.h +++ /dev/null @@ -1,69 +0,0 @@ -/* cmdline.h */ - -/* File autogenerated by gengetopt version 2.19.1 */ - -#ifndef CMDLINE_H -#define CMDLINE_H - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef CMDLINE_PARSER_PACKAGE -#define CMDLINE_PARSER_PACKAGE "Om - An OSC controlled realtime modular synthesizer" -#endif - -#ifndef CMDLINE_PARSER_VERSION -#define CMDLINE_PARSER_VERSION VERSION -#endif - -struct gengetopt_args_info -{ - const char *help_help; /* Print help and exit help description. */ - const char *version_help; /* Print version and exit help description. */ - char * port_arg; /* OSC port to listen on (default='16180'). */ - char * port_orig; /* OSC port to listen on original value given at command line. */ - const char *port_help; /* OSC port to listen on help description. */ - int in_jackd_flag; /* Run engine as in-process JACK client (default=off). */ - const char *in_jackd_help; /* Run engine as in-process JACK client help description. */ - - int help_given ; /* Whether help was given. */ - int version_given ; /* Whether version was given. */ - int port_given ; /* Whether port was given. */ - int in_jackd_given ; /* Whether in-jackd was given. */ - - char **inputs ; /* unamed options */ - unsigned inputs_num ; /* unamed options number */ -} ; - -extern const char *gengetopt_args_info_purpose; -extern const char *gengetopt_args_info_usage; -extern const char *gengetopt_args_info_help[]; - -int cmdline_parser (int argc, char * const *argv, - struct gengetopt_args_info *args_info); -int cmdline_parser2 (int argc, char * const *argv, - struct gengetopt_args_info *args_info, - int override, int initialize, int check_required); -int cmdline_parser_file_save(const char *filename, - struct gengetopt_args_info *args_info); - -void cmdline_parser_print_help(void); -void cmdline_parser_print_version(void); - -void cmdline_parser_init (struct gengetopt_args_info *args_info); -void cmdline_parser_free (struct gengetopt_args_info *args_info); - -int cmdline_parser_required (struct gengetopt_args_info *args_info, - const char *prog_name); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CMDLINE_H */ diff --git a/src/progs/server/ingen_dev b/src/progs/server/ingen_dev deleted file mode 100755 index bd8857f7..00000000 --- a/src/progs/server/ingen_dev +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env sh - -INGEN_MODULE_PATH=../../libs/engine/.libs ./ingen diff --git a/src/progs/server/main.cpp b/src/progs/server/main.cpp deleted file mode 100644 index e92b635f..00000000 --- a/src/progs/server/main.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include "config.h" -#include "module/Module.h" -#include "engine/util.h" -#include "engine/Engine.h" -#include "engine/EventSource.h" -#ifdef HAVE_LASH -#include "engine/LashDriver.h" -#endif -#ifdef BUILD_IN_PROCESS_ENGINE -#include -#include -#endif -#include "cmdline.h" - -using std::cout; using std::endl; using std::cerr; -using namespace Ingen; - -SharedPtr engine; - - -void -catch_int(int) -{ - signal(SIGINT, catch_int); - signal(SIGTERM, catch_int); - - std::cout << "[Main] Ingen interrupted." << std::endl; - engine->quit(); -} - - -#ifdef BUILD_IN_PROCESS_ENGINE - -jack_client_t* jack_client; -jack_intclient_t jack_intclient; - - -void -unload_in_process_engine(int) -{ - jack_status_t status; - int ret = EXIT_SUCCESS; - - cout << "Unloading..."; - status = jack_internal_client_unload(jack_client, jack_intclient); - if (status & JackFailure) { - cout << "failed" << endl; - ret = EXIT_FAILURE; - } else { - cout << "done" << endl; - } - jack_client_close(jack_client); - exit(ret); -} - - -int -load_in_process_engine(const char* port) -{ - int ret = EXIT_SUCCESS; - - jack_status_t status; - - if ((jack_client = jack_client_open("om_load", JackNoStartServer, - &status)) != NULL) { - jack_intclient = - jack_internal_client_load(jack_client, "Ingen", - (jack_options_t)(JackLoadName|JackLoadInit), - &status, "om", port); - if (status == 0) { - cout << "Engine loaded" << endl; - signal(SIGINT, unload_in_process_engine); - signal(SIGTERM, unload_in_process_engine); - - while (1) { - sleep(1); - } - } else if (status & JackFailure) { - cerr << "Could not load om.so" << endl; - ret = EXIT_FAILURE; - } - - jack_client_close(jack_client); - } else { - cerr << "jack_client_open failed" << endl; - ret = EXIT_FAILURE; - } -} - -#endif // BUILD_IN_PROCESS_ENGINE - - -int -main(int argc, char** argv) -{ -#ifdef HAVE_LASH - lash_args_t* lash_args = lash_extract_args(&argc, &argv); -#endif - - int ret = EXIT_SUCCESS; - - /* Parse command line options */ - gengetopt_args_info args_info; - if (cmdline_parser (argc, argv, &args_info) != 0) - return EXIT_FAILURE; - - - if (args_info.in_jackd_flag) { -#ifdef BUILD_IN_PROCESS_ENGINE - ret = load_in_process_engine(args_info.port_arg); -#else - cerr << "In-process Jack client support not enabled in this build." << endl; - ret = EXIT_FAILURE; -#endif - } else { - signal(SIGINT, catch_int); - signal(SIGTERM, catch_int); - - set_denormal_flags(); - - SharedPtr module = Ingen::Shared::load_module("ingen_engine"); - - if (!module) { - cerr << "Aborting. If you are running from the source tree, run ingen_dev." << endl; - return -1; - } - - Engine* (*new_engine)() = NULL; - - bool found = module->get_symbol("new_engine", (void*&)new_engine); - - if (!found) { - cerr << "Unable to find module entry point, exiting." << endl; - return -1; - } - - SharedPtr engine(new_engine()); - - engine->start_jack_driver(); - engine->start_osc_driver(args_info.port_arg); - - engine->activate(); - -#ifdef HAVE_LASH - lash_driver = new LashDriver(engine, lash_args); -#endif - - engine->main(); - - engine->event_source()->deactivate(); - -#ifdef HAVE_LASH - delete lash_driver; -#endif - - } - - return ret; -} - diff --git a/src/progs/supercollider/Ingen.sc b/src/progs/supercollider/Ingen.sc index cb366d58..873c8c2b 100644 --- a/src/progs/supercollider/Ingen.sc +++ b/src/progs/supercollider/Ingen.sc @@ -1,6 +1,6 @@ // TODO: // * Keep track of established connections. -Om : Model { +Ingen : Model { classvar <>program = "om", <>patchLoader = "om_patch_loader"; classvar <>oscURL, uiClass; var OmInternalNode, - \LADSPA -> OmLADSPANode, - \DSSI -> OmDSSINode + \Internal -> IngenInternalNode, + \LADSPA -> IngenLADSPANode, + \DSSI -> IngenDSSINode ]; - uiClass = OmEmacsUI + uiClass = IngenEmacsUI } *new { | netaddr | ^super.new.init(netaddr) @@ -76,7 +76,7 @@ Om : Model { "response/error" -> {|id,text| requestHandlers.removeAt(id); allocator.free(id); - ("Om"+text).error } + ("Ingen"+text).error } ].collect({|a| var func = a.value; OSCresponder(addr, "/om/"++a.key, {|time,resp,msg| @@ -110,11 +110,11 @@ Om : Model { patch.changed(\newNode, node); } { if (patch.getNode(nodeName).class != nodeTypeMap[type]) { - ("Om sent an existng node with differing type"+path).warn + ("Ingen sent an existng node with differing type"+path).warn } } } { - ("Om tried to create node in non-existing patch"+patchPath).warn + ("Ingen tried to create node in non-existing patch"+patchPath).warn } } { ("Invalid path in node creation"+path).warn @@ -135,17 +135,17 @@ Om : Model { parent = this.getNode(basePath) ? this.getPatch(basePath); if (parent.notNil) { if (parent.hasPort(portName).not) { - port = OmPort.new(portName, parent, type, dir, hint, def, min, max); + port = IngenPort.new(portName, parent, type, dir, hint, def, min, max); parent.ports[portName.asSymbol] = port; parent.changed(\newPort, port) } { if (parent.getPort(portName).porttype != type) { - ("Om tried to create an already existing port with differing type" + ("Ingen tried to create an already existing port with differing type" +path).warn } } } { - ("Om tried to create port on non-existing object"+basePath).warn + ("Ingen tried to create port on non-existing object"+basePath).warn } } { ("Invalid path in port creation"+path).warn @@ -163,7 +163,7 @@ Om : Model { if (node.notNil) { node.parent.nodes.removeAt(node.name.asSymbol).free } { - ("Om attempting to remove non-existing node"+path).warn + ("Ingen attempting to remove non-existing node"+path).warn } }, "port_removal" -> {|path| @@ -171,7 +171,7 @@ Om : Model { if (port.notNil) { port.parent.ports.removeAt(port.name.asSymbol).free } { - ("Om attempting to remove non-existing port"+path).warn + ("Ingen attempting to remove non-existing port"+path).warn } }, "patch_destruction" -> {|path| @@ -179,7 +179,7 @@ Om : Model { if (patch.notNil) { patch.parent.patches.removeAt(patch.name.asSymbol).free } { - ("Om attempting to remove non-existing patch"+path).warn + ("Ingen attempting to remove non-existing patch"+path).warn } }, "program_add" -> {|path,bank,program,name| @@ -187,7 +187,7 @@ Om : Model { if (node.respondsTo(\prProgramAdd)) { node.prProgramAdd(bank,program,name) } { - ("Om tried to add program info to"+node).warn + ("Ingen tried to add program info to"+node).warn } } ].collect({|a| @@ -217,7 +217,7 @@ Om : Model { addr.sendMsg("/om/ping", id) }; requestHandlers.removeAt(id); - "Om engine boot failed".error; + "Ingen engine boot failed".error; } } getPatch {|path, mustExist=true| @@ -267,7 +267,7 @@ Om : Model { } at {|path|^this.getObject(path.asString)} *boot {|func| - ^Om.new.waitForBoot {|e| + ^Ingen.new.waitForBoot {|e| e.activate { e.register { e.loadPlugins { @@ -286,18 +286,18 @@ Om : Model { booting = true; if (addr.addr == 2130706433) { if (loadIntoJack) { - ("jack_load"+"-i"+addr.port+"Om"+"om").unixCmd + ("jack_load"+"-i"+addr.port+"Ingen"+"om").unixCmd } { (program+"-p"+addr.port).unixCmd } } { - "You have to manually boot Om now".postln + "You have to manually boot Ingen now".postln } } loadPatch {|patchPath| (patchLoader + patchPath).unixCmd } activate { | handler | this.sendReq("engine/activate", { - root = OmPatch("",nil,this); + root = IngenPatch("",nil,this); this.changed(\newPatch, root); handler.value }) @@ -377,7 +377,7 @@ Om : Model { } quit { if (loadIntoJack) { - ("jack_unload"+"Om").unixCmd; + ("jack_unload"+"Ingen").unixCmd; booting=false; requestResponders.do(_.remove); notificationResponders.do(_.remove); @@ -445,7 +445,7 @@ Om : Model { } } -OmMetadata { +IngenMetadata { var object, dict; *new {|obj|^super.new.metadataInit(obj)} metadataInit {|obj| @@ -463,22 +463,22 @@ OmMetadata { } } -OmObject : Model { +IngenObject : Model { var