New upstream version 0.13.0~dfsg1
authorJaromír Mikeš <mira.mikes@seznam.cz>
Thu, 1 Sep 2016 23:34:23 +0000 (01:34 +0200)
committerJaromír Mikeš <mira.mikes@seznam.cz>
Thu, 1 Sep 2016 23:34:23 +0000 (01:34 +0200)
46 files changed:
.travis.yml
ChangeLog
Makefile.am
configure.ac
src/core/channel.h
src/core/conf.cpp
src/core/conf.h
src/core/const.h
src/core/midiChannel.h
src/core/midiMapConf.cpp
src/core/mixerHandler.cpp
src/core/patch_DEPR_.cpp
src/core/plugin.cpp
src/core/plugin.h
src/core/pluginHost.cpp
src/core/pluginHost.h
src/core/recorder.cpp
src/core/recorder.h
src/core/sampleChannel.cpp
src/core/wave.cpp
src/core/wave.h
src/glue/glue.cpp
src/glue/storage.cpp
src/glue/storage.h
src/gui/dialogs/gd_about.cpp
src/gui/dialogs/gd_actionEditor.cpp
src/gui/dialogs/gd_browser.cpp
src/gui/dialogs/gd_browser.h
src/gui/dialogs/gd_config.cpp
src/gui/dialogs/gd_editor.cpp
src/gui/dialogs/gd_mainWindow.cpp
src/gui/dialogs/gd_pluginList.cpp
src/gui/dialogs/gd_pluginWindowGUI.cpp
src/gui/elems/ge_actionChannel.cpp
src/gui/elems/ge_actionChannel.h
src/gui/elems/ge_browser.cpp
src/gui/elems/ge_browser.h
src/gui/elems/ge_mixed.cpp
src/gui/elems/ge_sampleChannel.cpp
src/utils/log.cpp
src/utils/string.cpp [new file with mode: 0644]
src/utils/string.h [new file with mode: 0644]
src/utils/utils.cpp
src/utils/utils.h
tests/resources/test.wav [new file with mode: 0644]
tests/wave.cpp

index 8ea13bf1551e7173c5d781f6e8bbd6ceb3af3483..5c770bcf6c728c4869c1b7e587a1dc1004e8dcab 100644 (file)
@@ -14,10 +14,12 @@ notifications:
     on_failure: always
 
 before_install:
+  - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y # for gcc 6
   - sudo apt-get update -qq
-  - sudo apt-get install -y libsndfile1-dev libsamplerate0-dev libfltk1.3-dev libasound2-dev libxpm-dev libpulse-dev libjack-dev libxrandr-dev libx11-dev libxinerama-dev libxcursor-dev
+  - sudo apt-get install -y gcc-6 g++-6 libsndfile1-dev libsamplerate0-dev libfltk1.3-dev libasound2-dev libxpm-dev libpulse-dev libjack-dev libxrandr-dev libx11-dev libxinerama-dev libxcursor-dev
 
 before_script:
+  - sudo ln -f -s /usr/bin/g++-6 /usr/bin/g++
 
   # Download and build latest version of RtMidi
 
@@ -34,10 +36,6 @@ before_script:
   - sudo ldconfig
   - cd ..
 
-  # Download wav file for testing purposes
-
-  - wget http://download.wavetlan.com/SVV/Media/HTTP/WAV/Media-Convert/Media-Convert_test3_PCM_Stereo_VBR_16SS_11025Hz.wav -O test.wav
-
   # Download midimaps package for testing purposes
 
   - wget https://github.com/monocasual/giada-midimaps/archive/master.zip -O giada-midimaps-master.zip
@@ -47,9 +45,9 @@ before_script:
 
   # Download vst plugin for testing purposes
 
-  - wget 'http://downloads.sourceforge.net/project/distrho/2014-08-26/dexed-linux64bit-fixed.tar.xz?r=http%3A%2F%2Fdistrho.sourceforge.net%2Fports&ts=1454876566&use_mirror=freefr' -O dexed.tar.xz
-  - tar xf dexed.tar.xz dexed-linux64bit/Dexed.so
-  - cp dexed-linux64bit/Dexed.so .
+  - wget http://www.discodsp.com/download/?id=18 -O bliss-linux.zip
+  - unzip bliss-linux.zip -d bliss-linux
+  - cp bliss-linux/64-bit/Bliss64Demo.so .
 
   # Build Giada. Note the CFLAGS: optimization levels are set to O1 in order
   # not to throw up nasty errors from JUCE modules.
index c39f012803eee2ecbda85bec356c8f205cd8ab34..abcbc3fe01d5deff77c42bfd8539b223971bef79 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 --------------------------------------------------------------------------------
 
 
+0.13.0 ---
+- Deep file browser refactoring
+- Save browser's scroll position and last item selected on opening
+- Load patches/projects/samples on double click
+- 64 bit builds for Windows
+- Prevent deprecated patch from crashing if a plugin is not found in the stack
+- Force logger to flush to file on Windows
+- Add more default values for windows' dimensions and positions
+- Avoid crashes on Configuration panel if no midimaps were selected
+- Fix missing keyRelease actions in action editor
+- Update JUCE to version 4.2.3
+- Don't include JUCE on tests without VST support (GitHub #75)
+- Fix compilation errors on GCC 6 (GitHub #82)
+- Fix wrong channel's actions count that prevented "R" button to be toggled
+  properly
+- Fixed a bug that prevented actions on frame 0 to being properly reproduced
+
+
 0.12.2 --- 2016 . 06 . 02
 - Update RtAudio to version 4.1.2
 - Add WASAPI support on Windows
index 5d43fcd7afc2e5b3690f04a24b2fca4129e96eea..a78f094e70b5662c818feb0178201faf888a9613 100644 (file)
@@ -135,7 +135,9 @@ src/utils/gui_utils.h                  \
 src/utils/gui_utils.cpp                \
 src/utils/gvector.h                    \
 src/utils/utils.h                      \
-src/utils/utils.cpp
+src/utils/utils.cpp                    \
+src/utils/string.h                     \
+src/utils/string.cpp
 
 if WITH_VST
 giada_SOURCES +=                                              \
@@ -164,8 +166,17 @@ giada_CPPFLAGS =
 #
 
 if WITH_VST
-giada_CPPFLAGS += -I./src/deps/juce -I./src/deps/vst -I/usr/include \
-  -I/usr/include/freetype2
+giada_CPPFLAGS +=                          \
+  -I./src/deps/juce                        \
+  -I./src/deps/vst                         \
+  -I/usr/include                           \
+  -I/usr/include/freetype2                 \
+  -DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1 \
+  -DJUCE_STANDALONE_APPLICATION=1          \
+  -DJUCE_PLUGINHOST_VST=1                  \
+  -DJUCE_PLUGINHOST_VST3=0                 \
+  -DJUCE_PLUGINHOST_AU=0
+giada_CXXFLAGS += -Wno-error=misleading-indentation
 endif
 
 if LINUX
@@ -182,7 +193,7 @@ if WINDOWS
 giada_LDADD = -lrtaudio -ldsound -lwsock32 -lm -lfltk -lwininet -lgdi32 \
   -lshell32 -lvfw32 -lrpcrt4 -luuid -lcomctl32 -lole32 -lws2_32 -lsndfile \
   -lsamplerate -lrtmidi -lwinmm -lsetupapi -lksuser -lpthreadGC2 -ljansson \
-  -limm32 -lglu32 -lshell32 -lversion -lopengl32 -loleaut32 -lshlwapi
+  -limm32 -lglu32 -lshell32 -lversion -lopengl32 -loleaut32 -lshlwapi -lcomdlg32
 giada_LDFLAGS = -mwindows -static
 giada_SOURCES += resource.rc
 endif
@@ -227,7 +238,10 @@ src/core/pluginHost.cpp      \
 src/core/dataStorageIni.cpp  \
 src/core/dataStorageJson.cpp \
 src/utils/utils.cpp          \
-src/utils/log.cpp            \
+src/utils/log.cpp
+
+if WITH_VST
+giada_tests_SOURCES +=                                        \
 src/deps/juce/juce_audio_basics/juce_audio_basics.cpp         \
 src/deps/juce/juce_audio_processors/juce_audio_processors.cpp \
 src/deps/juce/juce_core/juce_core.cpp                         \
@@ -236,6 +250,7 @@ src/deps/juce/juce_events/juce_events.cpp                     \
 src/deps/juce/juce_graphics/juce_graphics.cpp                 \
 src/deps/juce/juce_gui_basics/juce_gui_basics.cpp             \
 src/deps/juce/juce_gui_extra/juce_gui_extra.cpp
+endif
 
 giada_tests_LDADD = -ljansson -lsndfile -lsamplerate -lfltk -lXext -lX11 -lXft \
   -lXpm -lm -ljack -lasound -lpthread -ldl -lpulse-simple -lpulse -lrtmidi \
@@ -243,8 +258,18 @@ giada_tests_LDADD = -ljansson -lsndfile -lsamplerate -lfltk -lXext -lX11 -lXft \
 
 giada_tests_CXXFLAGS = -std=c++11
 
-giada_tests_CPPFLAGS = -I./src/deps/juce -I./src/deps/vst -I/usr/include \
-                       -I/usr/include/freetype2
+if WITH_VST
+giada_tests_CPPFLAGS =                     \
+  -I./src/deps/juce                        \
+  -I./src/deps/vst                         \
+  -I/usr/include                           \
+  -I/usr/include/freetype2                 \
+  -DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1 \
+  -DJUCE_STANDALONE_APPLICATION=1          \
+  -DJUCE_PLUGINHOST_VST=1                  \
+  -DJUCE_PLUGINHOST_VST3=0                 \
+  -DJUCE_PLUGINHOST_AU=0
+endif
 
 # make rename ------------------------------------------------------------------
 
index 8257cf4a9a68ea234aef3da4212db4d370c57eda..16fd0c34e808a171354a6d42b55df12791def72d 100644 (file)
@@ -4,7 +4,7 @@
 # prereq & init
 
 AC_PREREQ(2.60)
-AC_INIT([giada], [0.12], [giadaloopmachine@gmail.com])
+AC_INIT([giada], [0.13], [giadaloopmachine@gmail.com])
 AC_CONFIG_SRCDIR([src/main.cpp])
 AM_INIT_AUTOMAKE([subdir-objects])
 
@@ -60,7 +60,7 @@ AC_ARG_ENABLE(
 # test if files needed for Travis CI are present. If so, define a new macro
 # RUN_TESTS_WITH_LOCAL_FILES used during the test suite
 
-if test -f "./test.wav" && test -f "giada-midimaps-master.zip" && test -f "dexed.tar.xz" ; then
+if test -f "giada-midimaps-master.zip" && test -f "dexed.tar.xz" ; then
   AC_DEFINE(RUN_TESTS_WITH_LOCAL_FILES)
 fi
 
index 201c6a4658c8d5700f0933c878d007ff93805563..e0ee899032d1e9dd819e6efe196e554a3c5889fb 100644 (file)
 #include "recorder.h"
 
 #ifdef WITH_VST
-// TODO - can we move this stuff to a separate file?
-#include "../deps/juce/juce_audio_basics/juce_audio_basics.h"
-#include "../deps/juce/juce_audio_processors/juce_audio_processors.h"
-#include "../deps/juce/juce_core/juce_core.h"
-#include "../deps/juce/juce_data_structures/juce_data_structures.h"
-#include "../deps/juce/juce_events/juce_events.h"
-#include "../deps/juce/juce_graphics/juce_graphics.h"
-#include "../deps/juce/juce_gui_basics/juce_gui_basics.h"
-#include "../deps/juce/juce_gui_extra/juce_gui_extra.h"
+       #include "../deps/juce/config.h"
 #endif
 
 using std::vector;
index 8475a8ac8caa6da4978b061efe55c4ba378797df..eadbce2e487f1b9bf8afd4ea47cc005e4d078952 100644 (file)
@@ -44,8 +44,8 @@ Conf::Conf()
 
 #if defined(__linux__) || defined(__APPLE__)
 
-       confFilePath = gGetHomePath() + gGetSlash() + CONF_FILENAME;
-       confDirPath  = gGetHomePath() + gGetSlash();
+       confFilePath = gGetHomePath() + G_SLASH + CONF_FILENAME;
+       confDirPath  = gGetHomePath() + G_SLASH;
 
 #elif defined(_WIN32)
 
@@ -102,12 +102,12 @@ void Conf::init()
        limitOutput    = false;
        rsmpQuality    = 0;
 
-       midiPortIn     = DEFAULT_MIDI_PORT_IN;
-       noNoteOff      = false;
-       midiMapPath    = "";
-       midiPortOut    = DEFAULT_MIDI_PORT_OUT;
-       midiSync       = MIDI_SYNC_NONE;
-       midiTCfps      = 25.0f;
+       midiPortIn  = DEFAULT_MIDI_PORT_IN;
+       noNoteOff   = false;
+       midiMapPath = "";
+       midiPortOut = DEFAULT_MIDI_PORT_OUT;
+       midiSync    = MIDI_SYNC_NONE;
+       midiTCfps   = 25.0f;
 
        midiInRewind     = 0x0;
        midiInStartStop  = 0x0;
@@ -129,24 +129,40 @@ void Conf::init()
 
        resizeRecordings = true;
 
-       actionEditorZoom    = 100;
-       actionEditorGridOn  = false;
-       actionEditorGridVal = 1;
-
        mainWindowX = 0;
        mainWindowY = 0;
        mainWindowW = GUI_WIDTH;
        mainWindowH = GUI_HEIGHT;
 
+       browserX         = 0;
+       browserY         = 0;
+       browserW         = 640;
+       browserH         = 480;
+       browserPosition  = 0;
+       browserLastValue = 0;
+
+       actionEditorX       = 0;
+       actionEditorY       = 0;
+       actionEditorW       = 640;
+       actionEditorH       = 480;
+       actionEditorZoom    = 100;
+       actionEditorGridOn  = false;
+       actionEditorGridVal = 1;
+
+       sampleEditorX = 0;
+       sampleEditorY = 0;
+       sampleEditorW = 640;
+       sampleEditorH = 480;
+
        pianoRollY = -1;
        pianoRollH = 422;
 
        #ifdef WITH_VST
 
-       pluginChooserX = 0;
-       pluginChooserY = 0;
-       pluginChooserW = 640;
-       pluginChooserH = 480;
+       pluginChooserX   = 0;
+       pluginChooserY   = 0;
+       pluginChooserW   = 640;
+       pluginChooserH   = 480;
        pluginSortMethod = 0;
 
        #endif
@@ -216,6 +232,9 @@ int Conf::read()
        if (!setInt(jRoot, CONF_KEY_BROWSER_Y, browserY)) return 0;
        if (!setInt(jRoot, CONF_KEY_BROWSER_W, browserW)) return 0;
        if (!setInt(jRoot, CONF_KEY_BROWSER_H, browserH)) return 0;
+       if (!setInt(jRoot, CONF_KEY_BROWSER_POSITION, browserPosition)) return 0;
+       if (!setString(jRoot, CONF_KEY_BROWSER_LAST_PATH, browserLastPath)) return 0;
+       if (!setInt(jRoot, CONF_KEY_BROWSER_LAST_VALUE, browserLastValue)) return 0;
        if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_X, actionEditorX)) return 0;
        if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_Y, actionEditorY)) return 0;
        if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_W, actionEditorW)) return 0;
@@ -314,6 +333,9 @@ int Conf::write()
        json_object_set_new(jRoot, CONF_KEY_BROWSER_Y,                 json_integer(browserY));
        json_object_set_new(jRoot, CONF_KEY_BROWSER_W,                 json_integer(browserW));
        json_object_set_new(jRoot, CONF_KEY_BROWSER_H,                 json_integer(browserH));
+       json_object_set_new(jRoot, CONF_KEY_BROWSER_POSITION,          json_integer(browserPosition));
+       json_object_set_new(jRoot, CONF_KEY_BROWSER_LAST_PATH,         json_string(browserLastPath.c_str()));
+       json_object_set_new(jRoot, CONF_KEY_BROWSER_LAST_VALUE,        json_integer(browserLastValue));
        json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_X,           json_integer(actionEditorX));
        json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_Y,           json_integer(actionEditorY));
        json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_W,           json_integer(actionEditorW));
index 095440cd9dd52e72cd5021a3f4952caa19e09af0..f96265d883fb63d6c610f40df2f1e13efd319ba1 100644 (file)
@@ -109,13 +109,18 @@ public:
        string samplePath;
 
        int  mainWindowX, mainWindowY, mainWindowW, mainWindowH;
-       int  browserX, browserY, browserW, browserH;
+
+       int    browserX, browserY, browserW, browserH, browserPosition, browserLastValue;
+       string browserLastPath;
+
        int  actionEditorX, actionEditorY, actionEditorW, actionEditorH, actionEditorZoom;
        int  actionEditorGridVal;
        int  actionEditorGridOn;
+
        int  sampleEditorX, sampleEditorY, sampleEditorW, sampleEditorH;
   int  sampleEditorGridVal;
   int  sampleEditorGridOn;
+
        int  pianoRollY, pianoRollH;
        int  pluginListX, pluginListY;
        int  configX, configY;
index c6e1101117a7dc727d71b9d09f8f0c57fb68adec..90b362fb46eb2bfc19c7d487a33fcd54fec75a80 100644 (file)
 
 
 /* -- version --------------------------------------------------------------- */
-#define G_VERSION_STR   "0.12.2"
+#define G_VERSION_STR   "0.13.0"
 #define G_APP_NAME      "Giada"
 #define G_VERSION_MAJOR 0
-#define G_VERSION_MINOR 12
-#define G_VERSION_PATCH 2
+#define G_VERSION_MINOR 13
+#define G_VERSION_PATCH 0
 
 #define CONF_FILENAME          "giada.conf"
 
 #ifndef BUILD_DATE
-# define BUILD_DATE __DATE__
+       #define BUILD_DATE __DATE__
+#endif
+
+#ifdef _WIN32
+       #define G_SLASH '\\'
+       #define G_SLASH_STR "\\"
+#else
+       #define G_SLASH '/'
+       #define G_SLASH_STR "/"
 #endif
 
 
@@ -420,6 +428,9 @@ const int MIDI_CHANS[16] = {
 #define CONF_KEY_BROWSER_Y                "browser_y"
 #define CONF_KEY_BROWSER_W                "browser_w"
 #define CONF_KEY_BROWSER_H                "browser_h"
+#define CONF_KEY_BROWSER_POSITION         "browser_position"
+#define CONF_KEY_BROWSER_LAST_PATH        "browser_last_path"
+#define CONF_KEY_BROWSER_LAST_VALUE       "browser_last_value"
 #define CONF_KEY_ACTION_EDITOR_X          "action_editor_x"
 #define CONF_KEY_ACTION_EDITOR_Y          "action_editor_y"
 #define CONF_KEY_ACTION_EDITOR_W          "action_editor_w"
index e0f50b476908823bf17962ad04cced420008a4f1..011ae2f550693cdb911a3dda3153f01629a3e9a8 100644 (file)
 
 
 #ifdef WITH_VST
-// TODO - can we move this stuff to a separate file?
-#include "../deps/juce/juce_audio_basics/juce_audio_basics.h"
-#include "../deps/juce/juce_audio_processors/juce_audio_processors.h"
-#include "../deps/juce/juce_core/juce_core.h"
-#include "../deps/juce/juce_data_structures/juce_data_structures.h"
-#include "../deps/juce/juce_events/juce_events.h"
-#include "../deps/juce/juce_graphics/juce_graphics.h"
-#include "../deps/juce/juce_gui_basics/juce_gui_basics.h"
-#include "../deps/juce/juce_gui_extra/juce_gui_extra.h"
+       #include "../deps/juce/config.h"
 #endif
 
 #include "channel.h"
index bba90bd9fd7f202b690d2e90c4542e32729e7e3d..41d37060337cf8748d90fc7253677a8c50250ffb 100644 (file)
@@ -46,7 +46,7 @@ using std::vector;
 
 void MidiMapConf::init()
 {
-       midimapsPath = gGetHomePath() + gGetSlash() + "midimaps" + gGetSlash();
+       midimapsPath = gGetHomePath() + G_SLASH + "midimaps" + G_SLASH;
 
        /* scan dir of midi maps and load the filenames into <>maps. */
 
index 5d3867b58ccc3935a57d820f9159404aac109aeb..f965e02af78161424d98e7ac6178faa893bf62ee 100644 (file)
@@ -131,7 +131,8 @@ void mh_loadPatch_DEPR_(bool isProject, const char *projPath)
        int numChans = G_Patch_DEPR_.getNumChans();
        for (int i=0; i<numChans; i++) {
                Channel *ch = glue_addChannel(G_Patch_DEPR_.getColumn(i), G_Patch_DEPR_.getType(i));
-               string samplePath = isProject ? projPath + gGetSlash() + G_Patch_DEPR_.getSamplePath(i) : "";
+               string projectPath = projPath;  // safe
+               string samplePath  = isProject ? projectPath + G_SLASH + G_Patch_DEPR_.getSamplePath(i) : "";
                ch->readPatch_DEPR_(samplePath.c_str(), i, &G_Patch_DEPR_, G_Conf.samplerate,
                                G_Conf.rsmpQuality);
        }
index e25874e09815dc9ecf9ab152451d1c3aa8261c12..7c30284faab37614e155c282a5a412a65c5b01ea 100644 (file)
@@ -552,11 +552,13 @@ int Patch_DEPR_::readPlugins()
                                int nparam = atoi(getValue(tmp).c_str());
                                Plugin *pPlugin = G_PluginHost.getPluginByIndex(j, PluginHost::CHANNEL, ch);
                                sprintf(tmp, "chan%d_p%dbypass", ch->index, j);
-                               pPlugin->setBypass(atoi(getValue(tmp).c_str()));
-                               for (int k=0; k<nparam; k++) {
-                                       sprintf(tmp, "chan%d_p%dparam%dvalue", ch->index, j, k);
-                                       float pval = atof(getValue(tmp).c_str());
-                                       pPlugin->setParameter(k, pval);
+                               if (pPlugin) {
+                                       pPlugin->setBypass(atoi(getValue(tmp).c_str()));
+                                       for (int k=0; k<nparam; k++) {
+                                               sprintf(tmp, "chan%d_p%dparam%dvalue", ch->index, j, k);
+                                               float pval = atof(getValue(tmp).c_str());
+                                               pPlugin->setParameter(k, pval);
+                                       }
                                }
                                globalOut &= 1;
                        }
index 61f826141e1aa2dda031f98263b9ac9c758945f1..740bb706c58c8cb630b90f576feceaad18eb31d6 100644 (file)
@@ -41,17 +41,24 @@ int Plugin::idGenerator = 1;
 /* -------------------------------------------------------------------------- */
 
 
-void Plugin::initEditor()
+void Plugin::init()
 {
+  ui     = NULL;
+  id     = idGenerator++;;
+  bypass = false;
+  status = 1;
+
   if (getActiveEditor() != NULL) {
-    gLog("[Plugin::initEditor] plugin has an already active editor!\n");
+    gLog("[Plugin::init] plugin has an already active editor!\n");
     return;
   }
-  ui = createEditor();
+  ui = createEditorIfNeeded();
   if (ui == NULL) {
-    gLog("[Plugin::initEditor] unable to create editor!\n");
+    gLog("[Plugin::init] unable to create editor, the plugin might be GUI-less!\n");
     return;
   }
+
+  gLog("[Plugin::init] editor initialized and ready\n");
 }
 
 
@@ -65,7 +72,6 @@ void Plugin::showEditor(void *parent)
     return;
   }
   ui->setOpaque(true);
-  ui->setVisible(true);
   ui->addToDesktop(0, parent);
 }
 
@@ -75,7 +81,7 @@ void Plugin::showEditor(void *parent)
 
 bool Plugin::isEditorOpen()
 {
-  return ui->isVisible();
+  return ui->isVisible() && ui->isOnDesktop();
 }
 
 
@@ -95,7 +101,6 @@ void Plugin::closeEditor()
 {
   if (ui == NULL)
     return;
-  ui->setVisible(false);
   if (ui->isOnDesktop())
        ui->removeFromDesktop();
 }
index 30b79e626a8145d1daa898af257741a02c49b061..38e411c436e7afd7a32a0c93a167eb673c1ac3f0 100644 (file)
 #define __PLUGIN_H__
 
 
-#include "../deps/juce/juce_audio_basics/juce_audio_basics.h"
-#include "../deps/juce/juce_audio_processors/juce_audio_processors.h"
-#include "../deps/juce/juce_core/juce_core.h"
-#include "../deps/juce/juce_data_structures/juce_data_structures.h"
-#include "../deps/juce/juce_events/juce_events.h"
-#include "../deps/juce/juce_graphics/juce_graphics.h"
-#include "../deps/juce/juce_gui_basics/juce_gui_basics.h"
-#include "../deps/juce/juce_gui_extra/juce_gui_extra.h"
+#include "../deps/juce/config.h"
 
 
 using std::string;
@@ -58,11 +51,7 @@ private:
 
 public:
 
-  /* initEditor
-   * Prepare plugin GUI. 'parent' is a void pointer to the parent window that
-   * will contain it. */
-
-  void initEditor();
+  void init();
 
   void showEditor(void *parent);
 
@@ -80,17 +69,14 @@ public:
 
   string getUniqueId();
 
-  inline void setId() { id = idGenerator++; }
-  inline int  getId() { return id; }
-  inline bool getStatus() { return status; }
-  inline bool isBypassed() { return bypass; }
-  inline int  getEditorW() { return ui->getWidth(); }
-  inline int  getEditorH() { return ui->getHeight(); }
-
-  inline void toggleBypass() { bypass = !bypass; }
-  inline void setStatus(int s) { status = s; }
-  inline void setBypass(bool b) { bypass = b; }
-
+  int  getId()           { return id; }
+  bool getStatus()       { return status; }
+  bool isBypassed()      { return bypass; }
+  int  getEditorW()      { return ui->getWidth(); }
+  int  getEditorH()      { return ui->getHeight(); }
+  void toggleBypass()    { bypass = !bypass; }
+  void setStatus(int s)  { status = s; }
+  void setBypass(bool b) { bypass = b; }
 };
 
 #endif
index 0f7b60b7f4691592a2aa74e4ed4de739003e6f7b..9f31f2edaacfac3932a12ba5e01c1044869fdef6 100644 (file)
@@ -62,7 +62,7 @@ void PluginHost::init(int _buffersize, int _samplerate)
   buffersize = _buffersize;
   missingPlugins = false;
   //unknownPluginList.empty();
-  loadList(gGetHomePath() + gGetSlash() + "plugins.xml");
+  loadList(gGetHomePath() + G_SLASH + "plugins.xml");
 }
 
 
@@ -151,8 +151,10 @@ Plugin *PluginHost::addPlugin(const string &fid, int stackType,
     return NULL;
   }
 
-  p->setStatus(1);
-  p->setId();
+  //p->setStatus(1);
+  //p->setId();
+  //p->initEditor();
+  p->init();
   p->prepareToPlay(samplerate, buffersize);
 
   gLog("[PluginHost::addPlugin] plugin instance with fid=%s created\n", fid.c_str());
index feb7f3805d77d6d36c5b4c420b10eda762bec960..ac741e25cdf17425624680863aa5261653ebcc00 100644 (file)
 
 
 #include <pthread.h>
-//#include "../deps/juce/AppConfig.h"
-// TODO - can we move this stuff to a separate file?
-#include "../deps/juce/juce_audio_basics/juce_audio_basics.h"
-#include "../deps/juce/juce_audio_processors/juce_audio_processors.h"
-#include "../deps/juce/juce_core/juce_core.h"
-#include "../deps/juce/juce_data_structures/juce_data_structures.h"
-#include "../deps/juce/juce_events/juce_events.h"
-#include "../deps/juce/juce_graphics/juce_graphics.h"
-#include "../deps/juce/juce_gui_basics/juce_gui_basics.h"
-#include "../deps/juce/juce_gui_extra/juce_gui_extra.h"
+#include "../deps/juce/config.h"
 
 
 using std::string;
index 87a4791ae12c8b993a9aceff51ad00e61f773e61..53864b0bb36f1273dd3ec931a435426101cf07b4 100644 (file)
@@ -1,11 +1,11 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * recorder
  * Action recorder.
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
  * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
@@ -25,7 +25,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #include <math.h>
@@ -43,8 +43,6 @@
 #include "../utils/utils.h"
 
 
-
-
 extern Mixer       G_Mixer;
 extern Patch_DEPR_ f_patch;
 extern Conf           G_Conf;
@@ -62,7 +60,7 @@ bool sortedActions = false;
 composite cmp;
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void init()
@@ -73,7 +71,7 @@ void init()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 bool canRec(Channel *ch)
@@ -90,7 +88,7 @@ bool canRec(Channel *ch)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void rec(int index, int type, int frame, uint32_t iValue, float fValue)
@@ -162,7 +160,7 @@ void rec(int index, int type, int frame, uint32_t iValue, float fValue)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void clearChan(int index)
@@ -175,12 +173,6 @@ void clearChan(int index)
                        if (j == global.at(i).size()) break;      // for each action j of frame i
                        action *a = global.at(i).at(j);
                        if (a->chan == index)   {
-#ifdef WITH_VST
-#if 0
-                               if (a->type == ACTION_MIDI)
-                                       free(a->event);
-#endif
-#endif
                                free(a);
                                global.at(i).erase(global.at(i).begin() + j);
                        }
@@ -196,7 +188,7 @@ void clearChan(int index)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void clearAction(int index, char act)
@@ -217,14 +209,14 @@ void clearAction(int index, char act)
                }
        }
        Channel *ch = G_Mixer.getChannelByIndex(index);
-       ch->hasActions = false;   /// FIXME - why this? Isn't it useless if we call chanHasActions?
+       ch->hasActions = false;   /// FIXME - why this? Isn't it useless if we call setChanHasActionsStatus?
        optimize();
-       chanHasActions(index);    /// FIXME
+       setChanHasActionsStatus(index);    /// FIXME
        //print();
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void deleteAction(int chan, int frame, char type, bool checkValues, uint32_t iValue, float fValue)
@@ -256,12 +248,6 @@ void deleteAction(int chan, int frame, char type, bool checkValues, uint32_t iVa
                                        while (lockStatus == 0) {
                                                lockStatus = pthread_mutex_trylock(&G_Mixer.mutex_recs);
                                                if (lockStatus == 0) {
-#ifdef WITH_VST
-#if 0
-                                                       if (type == ACTION_MIDI)
-                                                               free(a->event);
-#endif
-#endif
                                                        free(a);
                                                        global.at(i).erase(global.at(i).begin() + j);
                                                        pthread_mutex_unlock(&G_Mixer.mutex_recs);
@@ -277,7 +263,7 @@ void deleteAction(int chan, int frame, char type, bool checkValues, uint32_t iVa
        }
        if (found) {
                optimize();
-               chanHasActions(chan);
+               setChanHasActionsStatus(chan);
                gLog("[REC] action deleted, type=%d frame=%d chan=%d iValue=%d (%X) fValue=%f\n",
                        type, frame, chan, iValue, iValue, fValue);
        }
@@ -287,7 +273,7 @@ void deleteAction(int chan, int frame, char type, bool checkValues, uint32_t iVa
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void deleteActions(int chan, int frame_a, int frame_b, char type)
@@ -304,7 +290,7 @@ void deleteActions(int chan, int frame_a, int frame_b, char type)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void clearAll()
@@ -336,7 +322,7 @@ void clearAll()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void optimize()
@@ -358,7 +344,7 @@ void optimize()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void sortActions()
@@ -376,7 +362,7 @@ void sortActions()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void updateBpm(float oldval, float newval, int oldquanto)
@@ -417,7 +403,7 @@ void updateBpm(float oldval, float newval, int oldquanto)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void updateSamplerate(int systemRate, int patchRate)
@@ -457,7 +443,7 @@ void updateSamplerate(int systemRate, int patchRate)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void expand(int old_fpb, int new_fpb)
@@ -488,7 +474,7 @@ void expand(int old_fpb, int new_fpb)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void shrink(int new_fpb)
@@ -515,26 +501,29 @@ void shrink(int new_fpb)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void chanHasActions(int index)
+void setChanHasActionsStatus(int index)
 {
        Channel *ch = G_Mixer.getChannelByIndex(index);
        if (global.size() == 0) {
                ch->hasActions = false;
                return;
        }
-       for (unsigned i=0; i<global.size() && !ch->hasActions; i++) {
-               for (unsigned j=0; j<global.at(i).size() && !ch->hasActions; j++) {
-                       if (global.at(i).at(j)->chan == index)
+       for (unsigned i=0; i<global.size(); i++) {
+               for (unsigned j=0; j<global.at(i).size(); j++) {
+                       if (global.at(i).at(j)->chan == index) {
                                ch->hasActions = true;
+                               return;
+                       }
                }
        }
+       ch->hasActions = false;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int getNextAction(int chan, char type, int frame, action **out, uint32_t iValue)
@@ -562,7 +551,7 @@ int getNextAction(int chan, char type, int frame, action **out, uint32_t iValue)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int getAction(int chan, char action, int frame, struct action **out)
@@ -580,7 +569,7 @@ int getAction(int chan, char action, int frame, struct action **out)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void startOverdub(int index, char actionMask, int frame)
@@ -622,7 +611,7 @@ void startOverdub(int index, char actionMask, int frame)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void stopOverdub(int frame)
@@ -651,9 +640,10 @@ void stopOverdub(int frame)
 
        /* remove any nested action between keypress----keyrel, then record */
 
-       if (!nullLoop)
+       if (!nullLoop) {
                deleteActions(cmp.a2.chan, cmp.a1.frame, cmp.a2.frame, cmp.a1.type);
                deleteActions(cmp.a2.chan, cmp.a1.frame, cmp.a2.frame, cmp.a2.type);
+       }
 
        if (!ringLoop && !nullLoop) {
                rec(cmp.a2.chan, cmp.a2.type, cmp.a2.frame);
@@ -673,7 +663,7 @@ void stopOverdub(int frame)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void print()
index 363323f974e30f28c835d9be1167f80ce5fdc33e..95a8b65c3a43d5f57ae20ca03bec08dfd03ce0a7 100644 (file)
 #include "const.h"
 #include "mixer.h"
 
-#ifdef WITH_VST
-
-/* before including aeffetx(x).h we must define __cdecl, otherwise VST
- * headers can't be compiled correctly. In windows __cdecl is already
- * defined. */
-
-       #ifdef __GNUC__
-               #ifndef _WIN32
-                       #define __cdecl
-               #endif
-       #endif
-       #include "../deps/vst/aeffectx.h"
-#endif
-
 
 using std::vector;
 
@@ -61,14 +47,15 @@ using std::vector;
  * [global3]-->[vector<_action*>3]-->[a0][a1][a2]                              3[frames4]
  * */
 
-namespace recorder {
-
+namespace recorder
+{
 /* action
  * struct containing fields to describe an atomic action. Note from
  * VST sdk: parameter values, like all VST parameters, are declared as
  * floats with an inclusive range of 0.0 to 1.0 (fValue). */
 
-struct action {
+struct action
+{
        int      chan;    // channel index, i.e. Channel->index
        int      type;
        int      frame;   // redundant info, used by helper functions
@@ -80,7 +67,8 @@ struct action {
  * a group of two actions (keypress+keyrel, muteon+muteoff) used during
  * the overdub process */
 
-struct composite {
+struct composite
+{
        action a1;
        action a2;
 };
@@ -97,11 +85,11 @@ extern bool sortedActions;                  // are actions sorted via sortAction
 
 void init();
 
-/* chanHasActions
+/* setChanHasActionsStatus
  * Check if the channel has at least one action recorded. If false, sets
  * ch->hasActions = false. Used after an action deletion. */
 
-void chanHasActions(int chan);
+void setChanHasActionsStatus(int chan);
 
 /* canRec
  * can a channel rec an action? Call this one BEFORE rec(). */
index 48ee17b4ba8d267e862c7a75333928939274e94f..3b7d5e1984ceb849c4b837c172460571fad62eee 100644 (file)
@@ -713,7 +713,7 @@ bool SampleChannel::allocEmpty(int frames, int samplerate, int takeId)
                return false;
 
        w->name     = "TAKE-" + gItoa(takeId);
-       w->pathfile = gGetCurrentPath() + gGetSlash() + w->name;
+       w->pathfile = gGetCurrentPath() + G_SLASH + w->name;
        wave        = w;
        status      = STATUS_OFF;
        begin       = 0;
@@ -975,11 +975,16 @@ void SampleChannel::start(int frame, bool doQuantize, int quantize,
                                else {
 
                                        /* fillChan only if frame != 0. If you call fillChan on frame == 0
-                                        * a duplicate call to fillChan occurs with loss of data. */
+                                       a duplicate call to fillChan occurs with loss of data. Yeah, but
+                                       what happens if an action really occurs on frame 0 (and it happens,
+                                       for example     when you start the sequencer from the firt beat)? Cheat
+                                       time! Shift a little bit the frame, so that it's no longer zero.  */
 
                                        status = STATUS_PLAY;
                                        sendMidiLplay();
-                                       if (frame != 0)
+                                       if (frame == 0)
+                                               frame = 2;
+                                       //if (frame != 0)
                                                tracker = fillChan(vChan, tracker, frame);
                                }
                        }
index 28b3a4232ad68d511687f86144fcd2c7e920fa15..4bdffc917e461d5ceb2e5ef8795c1ac75c39edd5 100644 (file)
 #include <math.h>
 #include "../utils/utils.h"
 #include "../utils/log.h"
-#include "wave.h"
 #include "init.h"
+#include "const.h"
+#include "wave.h"
+
+
+using std::string;
 
 
 Wave::Wave()
@@ -239,12 +243,12 @@ int Wave::resample(int quality, int newRate)
 /* -------------------------------------------------------------------------- */
 
 
-std::string Wave::basename() const
+string Wave::basename(bool ext) const
 {
-       return gStripExt(gBasename(pathfile.c_str()).c_str());
+       return ext ? gBasename(pathfile) : gStripExt(gBasename(pathfile));
 }
 
-std::string Wave::extension() const
+string Wave::extension() const
 {
        return gGetExt(pathfile.c_str());
 }
@@ -255,10 +259,10 @@ std::string Wave::extension() const
 
 void Wave::updateName(const char *n)
 {
-       std::string ext = gGetExt(pathfile.c_str());
-       name      = gStripExt(gBasename(n).c_str());
-       pathfile  = gDirname(pathfile.c_str()) + gGetSlash() + name + "." + ext;
-       isLogical = true;
+       string ext = gGetExt(pathfile.c_str());
+       name       = gStripExt(gBasename(n).c_str());
+       pathfile   = gDirname(pathfile.c_str()) + G_SLASH + name + "." + ext;
+       isLogical  = true;
 
        /* a wave with updated name must become logical, since the underlying
         * file does not exist yet. */
index 237e52f526a07675f3cba6f75c245973b3903736..f602667de69593285ad7f2f19fcd6a64b17faa67 100644 (file)
@@ -36,6 +36,9 @@
 #include <string>
 
 
+using std::string;
+
+
 class Wave
 {
 private:
@@ -52,8 +55,8 @@ public:
        ~Wave();
        Wave(const Wave &other);
 
-       std::string pathfile; // full path + sample name
-       std::string name;                       // sample name (changeable)
+       string pathfile; // full path + sample name
+       string name;                    // sample name (changeable)
 
        float     *data;
        int        size;                          // wave size (size in stereo: size / 2)
@@ -67,8 +70,8 @@ public:
        inline void channels(int v) { inHeader.channels = v; }
        inline void frames  (int v) { inHeader.frames = v; }
 
-       std::string basename () const;
-       std::string extension() const;
+       string basename (bool ext=false) const;
+       string extension() const;
 
        void updateName(const char *n);
        int  open      (const char *f);
index 7acd5fb550f4a9af6e3650f046343e969c1ae766..ff1670cc9a6fd9beb4f0bdcf8f623928b3b08cd9 100644 (file)
@@ -711,7 +711,7 @@ void glue_setPanning(class gdEditor *win, SampleChannel *ch, float val)
                ch->panRight= 0.0f + val;
 
                char buf[8];
-               sprintf(buf, "%d L", abs((ch->panRight * 100.0f) - 100));
+               sprintf(buf, "%d L", (int) abs((ch->panRight * 100.0f) - 100));
                win->panNum->value(buf);
        }
        else if (val == 1.0f) {
@@ -724,7 +724,7 @@ void glue_setPanning(class gdEditor *win, SampleChannel *ch, float val)
                ch->panRight= 1.0f;
 
                char buf[8];
-               sprintf(buf, "%d R", abs((ch->panLeft * 100.0f) - 100));
+               sprintf(buf, "%d R", (int) abs((ch->panLeft * 100.0f) - 100));
                win->panNum->value(buf);
        }
        win->panNum->redraw();
index daa2fc7342781843700b42c80caf9cb522626a28..d51773693fc5d90a6e179b0bedc749640b0efde8 100644 (file)
@@ -32,6 +32,7 @@
 #include "../gui/elems/ge_keyboard.h"
 #include "../gui/dialogs/gd_mainWindow.h"
 #include "../gui/dialogs/gd_warnings.h"
+#include "../gui/dialogs/gd_browser.h"
 #include "../core/mixer.h"
 #include "../core/mixerHandler.h"
 #include "../core/channel.h"
@@ -62,17 +63,6 @@ extern PluginHost    G_PluginHost;
 #endif
 
 
-static void __glue_setProgressBar__(class gProgress *status, float v)
-{
-       status->value(status->value() + v);
-       //Fl::check();
-       Fl::wait(0);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
 #ifdef WITH_VST
 
 static void __glue_fillPatchGlobalsPlugins__(vector <Plugin *> *host, vector<Patch::plugin_t> *patch)
@@ -160,7 +150,8 @@ static void __glue_fillPatchGlobals__(const string &name)
 /* -------------------------------------------------------------------------- */
 
 
-int glue_savePatch(const string &fullPath, const string &name, bool isProject)
+static bool __glue_savePatch__(const string &fullPath, const string &name,
+               bool isProject)
 {
        G_Patch.init();
 
@@ -170,38 +161,88 @@ int glue_savePatch(const string &fullPath, const string &name, bool isProject)
 
        if (G_Patch.write(fullPath)) {
                gu_update_win_label(name.c_str());
-               gLog("[glue] patch saved as %s\n", fullPath.c_str());
-               return 1;
+               gLog("[glue_savePatch] patch saved as %s\n", fullPath.c_str());
+               return true;
        }
-       return 0;
+       return false;
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-int glue_loadPatch(const string &fullPath, class gProgress *status, bool isProject)
+void glue_savePatch(void *data)
 {
-       /* try to load the new JSON-based patch. If it fails, fall back to deprecated
-       * one. */
+       gdSaveBrowser *browser = (gdSaveBrowser*) data;
+       string name            = browser->getName();
+       string fullPath        = browser->getCurrentPath() + G_SLASH + gStripExt(name) + ".gptc";
+
+       if (name == "") {
+               gdAlert("Please choose a file name.");
+               return;
+       }
+
+       if (gFileExists(fullPath.c_str()))
+               if (!gdConfirmWin("Warning", "File exists: overwrite?"))
+                       return;
+
+       if (__glue_savePatch__(fullPath, name, false)) {  // false == not a project
+               G_Conf.patchPath = gDirname(fullPath);
+               browser->do_callback();
+       }
+       else
+               gdAlert("Unable to save the patch!");
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void glue_loadPatch(void *data)
+{
+       gdLoadBrowser *browser = (gdLoadBrowser*) data;
+       string fullPath        = browser->getSelectedItem();
+       bool isProject         = gIsProject(browser->getSelectedItem());
+
+       browser->showStatusBar();
 
        gLog("[glue] loading %s...\n", fullPath.c_str());
 
        string fileToLoad = fullPath;  // patch file to read from
        string basePath   = "";        // base path, in case of reading from a project
        if (isProject) {
-               fileToLoad = fullPath + gGetSlash() + gStripExt(gBasename(fullPath)) + ".gptc";
-               basePath   = fullPath.c_str() + gGetSlash();
+               fileToLoad = fullPath + G_SLASH + gStripExt(gBasename(fullPath)) + ".gptc";
+               basePath   = fullPath + G_SLASH;
        }
 
-       int res = G_Patch.read(fileToLoad);
+       /* try to load the new JSON-based patch. If it fails, fall back to deprecated
+       * one. */
+
+       int  res = G_Patch.read(fileToLoad);
+       bool deprecated = false;
 
        if (res == PATCH_UNREADABLE) {
                gLog("[glue] failed reading JSON-based patch. Trying with the deprecated method\n");
-               return glue_loadPatch__DEPR__(gBasename(fileToLoad).c_str(), fileToLoad.c_str(), status, isProject);
+               deprecated = true;
+               res = glue_loadPatch__DEPR__(gBasename(fileToLoad).c_str(), fileToLoad.c_str(),
+                               browser->getStatusBar(), isProject);
+       }
+
+       if (res != PATCH_READ_OK) {
+               if (res == PATCH_UNREADABLE)
+                       isProject ? gdAlert("This project is unreadable.") : gdAlert("This patch is unreadable.");
+               else
+               if (res == PATCH_INVALID)
+                       isProject ? gdAlert("This project is not valid.") : gdAlert("This patch is not valid.");
+
+               browser->hideStatusBar();
+               return;
+       }
+       else
+       if (deprecated) {
+               browser->do_callback();
+               return;
        }
-       if (res != PATCH_READ_OK)
-               return res;
 
        /* close all other windows. This prevents segfault if plugin
         * windows GUIs are on. */
@@ -213,7 +254,8 @@ int glue_loadPatch(const string &fullPath, class gProgress *status, bool isProje
 
        glue_resetToInitState(false, false);
 
-       __glue_setProgressBar__(status, 0.1f);
+       browser->setStatusBar(0.1f);
+       //__glue_setProgressBar__(status, 0.1f);
 
        /* Add common stuff, columns and channels. Also increment the progress bar
         * by 0.8 / total_channels steps.  */
@@ -229,7 +271,8 @@ int glue_loadPatch(const string &fullPath, class gProgress *status, bool isProje
                                ch->readPatch(basePath, k, &G_Patch, &G_Mixer.mutex_plugins,
                                                G_Conf.samplerate, G_Conf.rsmpQuality);
                        }
-                       __glue_setProgressBar__(status, steps);
+                       //__glue_setProgressBar__(status, steps);
+                       browser->setStatusBar(steps);
                }
        }
 
@@ -245,14 +288,15 @@ int glue_loadPatch(const string &fullPath, class gProgress *status, bool isProje
        /* save patchPath by taking the last dir of the broswer, in order to
         * reuse it the next time */
 
-       G_Conf.patchPath = gDirname(fullPath.c_str());
+       G_Conf.patchPath = gDirname(fullPath);
 
        /* refresh GUI */
 
        gu_updateControls();
        gu_update_win_label(G_Patch.name.c_str());
 
-       __glue_setProgressBar__(status, 1.0f);
+       browser->setStatusBar(0.1f);
+       //__glue_setProgressBar__(status, 1.0f);
 
        gLog("[glue] patch loaded successfully\n");
 
@@ -263,7 +307,7 @@ int glue_loadPatch(const string &fullPath, class gProgress *status, bool isProje
 
 #endif
 
-       return res;
+       browser->do_callback();
 }
 
 
@@ -359,13 +403,28 @@ int glue_loadPatch__DEPR__(const char *fname, const char *fpath, gProgress *stat
 /* -------------------------------------------------------------------------- */
 
 
-int glue_saveProject(const string &folderPath, const string &projName)
+void glue_saveProject(void *data)
 {
-       if (!gDirExists(folderPath.c_str()) && !gMkdir(folderPath.c_str())) {
-               gLog("[glue] unable to make project directory!\n");
-               return 0;
+       gdSaveBrowser *browser = (gdSaveBrowser*) data;
+       string name            = browser->getName();
+       string folderPath      = browser->getCurrentPath(); //browser->getSelectedItem();
+       string fullPath        = folderPath + G_SLASH + gStripExt(name) + ".gprj";
+
+       if (name == "") {
+               gdAlert("Please choose a project name.");
+               return;
+       }
+
+       if (gIsProject(fullPath.c_str()) && !gdConfirmWin("Warning", "Project exists: overwrite?"))
+               return;
+
+       if (!gDirExists(fullPath.c_str()) && !gMkdir(fullPath.c_str())) {
+               gLog("[glue_saveProject] unable to make project directory!\n");
+               return;
        }
 
+       gLog("[glue_saveProject] project dir created: %s\n", fullPath.c_str());
+
        /* copy all samples inside the folder. Takes and logical ones are saved
         * via glue_saveSample() */
 
@@ -382,7 +441,7 @@ int glue_saveProject(const string &folderPath, const string &projName)
                /* update the new samplePath: everything now comes from the project
                 * folder (folderPath). Also remove any existing file. */
 
-               string samplePath = folderPath + gGetSlash() + ch->wave->basename() + "." + ch->wave->extension();
+               string samplePath = fullPath + G_SLASH + ch->wave->basename(true);
 
                if (gFileExists(samplePath.c_str()))
                        remove(samplePath.c_str());
@@ -390,8 +449,63 @@ int glue_saveProject(const string &folderPath, const string &projName)
                        ch->wave->pathfile = samplePath;
        }
 
-       string gptcPath = folderPath + gGetSlash() + gStripExt(projName.c_str()) + ".gptc";
-       glue_savePatch(gptcPath, projName, true); // true == it's a project
+       string gptcPath = fullPath + G_SLASH + gStripExt(name.c_str()) + ".gptc";
+       if (__glue_savePatch__(gptcPath, name, true)) // true == it's a project
+               browser->do_callback();
+       else
+               gdAlert("Unable to save the project!");
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void glue_loadSample(void *data)
+{
+       gdLoadBrowser *browser = (gdLoadBrowser*) data;
+       string fullPath        = browser->getSelectedItem();
+
+       if (fullPath.empty())
+               return;
+
+       int res = glue_loadChannel((SampleChannel*) browser->getChannel(), fullPath.c_str());
 
-       return 1;
+       if (res == SAMPLE_LOADED_OK) {
+               G_Conf.samplePath = gDirname(fullPath);
+               browser->do_callback();
+               mainWin->delSubWindow(WID_SAMPLE_EDITOR); // if editor is open
+       }
+       else
+               mainWin->keyboard->printChannelMessage(res);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void glue_saveSample(void *data)
+{
+       gdSaveBrowser *browser = (gdSaveBrowser*) data;
+       string name            = browser->getName();
+       string folderPath      = browser->getSelectedItem();
+
+       if (name == "") {
+               gdAlert("Please choose a file name.");
+               return;
+       }
+
+       /* bruteforce check extension. */
+
+       string filePath = folderPath + G_SLASH + gStripExt(name) + ".wav";
+
+       if (gFileExists(filePath))
+               if (!gdConfirmWin("Warning", "File exists: overwrite?"))
+                       return;
+
+       if (((SampleChannel*)browser->getChannel())->save(filePath.c_str())) {
+               G_Conf.samplePath = gDirname(folderPath);
+               browser->do_callback();
+       }
+       else
+               gdAlert("Unable to save this sample!");
 }
index f7d05c1008f2b4193b1a5f96505a387806f0efd5..98be8e8cb64baae174a1a0939e51810061972350 100644 (file)
@@ -40,9 +40,11 @@ using std::string;
 using std::vector;
 
 
-int glue_loadPatch  (const string &fullPath, class gProgress *status, bool isProject);
+void glue_loadPatch  (void *data);
 int glue_loadPatch__DEPR__(const char *fname, const char *fpath, class gProgress *status, bool isProject);
-int glue_savePatch  (const string &fullPath, const string &name, bool isProject);
-int glue_saveProject(const string &folderPath, const string &projName);
+void glue_savePatch  (void *data);
+void glue_saveProject(void *data);
+void glue_saveSample (void *data);
+void glue_loadSample (void *data);
 
 #endif
index 246a36e787e512a9c86f82437e450af6726c2920..3e0e61424acb4ae136b583f38a0823dbeae2b8c5 100644 (file)
@@ -73,8 +73,13 @@ gdAbout::gdAbout()
          "Version " G_VERSION_STR " (" BUILD_DATE ")\n\n"
                "Developed by Monocasual\n"
                "Based on FLTK (%d.%d.%d), RtAudio (%s),\n"
-               "RtMidi (%s), libsamplerate, Jansson (%s) \n"
-               "and libsndfile\n\n"
+               "RtMidi (%s), Libsamplerate, Jansson (%s),\n"
+               "Libsndfile"
+#ifdef WITH_VST
+               ", JUCE (%d.%d.%d)\n\n"
+#else
+               "\n\n"
+#endif
                "Released under the terms of the GNU General\n"
                "Public License (GPL v3)\n\n"
                "News, infos, contacts and documentation:\n"
@@ -82,7 +87,12 @@ gdAbout::gdAbout()
                FL_MAJOR_VERSION, FL_MINOR_VERSION, FL_PATCH_VERSION,
                kernelAudio::getRtAudioVersion().c_str(),
                kernelMidi::getRtMidiVersion().c_str(),
-               JANSSON_VERSION);
+               JANSSON_VERSION
+#ifdef WITH_VST
+               , JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_BUILDNUMBER);
+#else
+               );
+#endif
 
        int tw = 0;
        int th = 0;
index 544e83f93364f0468c50635078684f0cde41159e..ddfcdafc1599f12c2a84615f2461f898b7bc130a 100644 (file)
@@ -1,10 +1,10 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * gd_actionEditor
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
  * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #include <math.h>
@@ -147,7 +147,7 @@ gdActionEditor::gdActionEditor(Channel *chan)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 gdActionEditor::~gdActionEditor() {
@@ -162,14 +162,14 @@ gdActionEditor::~gdActionEditor() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void gdActionEditor::cb_zoomIn(Fl_Widget *w, void *p)  { ((gdActionEditor*)p)->__cb_zoomIn(); }
 void gdActionEditor::cb_zoomOut(Fl_Widget *w, void *p) { ((gdActionEditor*)p)->__cb_zoomOut(); }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void gdActionEditor::__cb_zoomIn() {
@@ -209,7 +209,7 @@ void gdActionEditor::__cb_zoomIn() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void gdActionEditor::__cb_zoomOut() {
@@ -245,7 +245,7 @@ void gdActionEditor::__cb_zoomOut() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void gdActionEditor::update() {
@@ -258,7 +258,7 @@ void gdActionEditor::update() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int gdActionEditor::handle(int e) {
@@ -274,7 +274,7 @@ int gdActionEditor::handle(int e) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int gdActionEditor::getActionType() {
@@ -291,9 +291,9 @@ int gdActionEditor::getActionType() {
 }
 
 
-/* ------------------------------------------------------------------ */
-/* ------------------------------------------------------------------ */
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
 
 
 gGridTool::gGridTool(int x, int y, gdActionEditor *parent)
@@ -320,7 +320,7 @@ gGridTool::gGridTool(int x, int y, gdActionEditor *parent)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 gGridTool::~gGridTool() {
@@ -329,13 +329,13 @@ gGridTool::~gGridTool() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void gGridTool::cb_changeType(Fl_Widget *w, void *p)  { ((gGridTool*)p)->__cb_changeType(); }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void gGridTool::__cb_changeType() {
@@ -344,7 +344,7 @@ void gGridTool::__cb_changeType() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 bool gGridTool::isOn() {
@@ -352,7 +352,7 @@ bool gGridTool::isOn() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int gGridTool::getValue() {
@@ -370,7 +370,7 @@ int gGridTool::getValue() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void gGridTool::calc() {
@@ -413,7 +413,7 @@ void gGridTool::calc() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int gGridTool::getSnapPoint(int v) {
@@ -435,7 +435,7 @@ int gGridTool::getSnapPoint(int v) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int gGridTool::getSnapFrame(int v) {
@@ -464,7 +464,7 @@ int gGridTool::getSnapFrame(int v) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int gGridTool::getCellSize() {
index f427abbe7a9de0ba44ecb3ee80e4e240242d52c1..448ad7495ebea368906be2866a2a49756a6c18fe 100644 (file)
  * -------------------------------------------------------------------------- */
 
 
-#include "../../core/mixer.h"
 #include "../../core/graphics.h"
 #include "../../core/wave.h"
 #include "../../core/channel.h"
 #include "../../core/sampleChannel.h"
-#include "../../core/patch_DEPR_.h"
-#include "../../core/patch.h"
 #include "../../core/conf.h"
 #include "../../glue/glue.h"
 #include "../../glue/channel.h"
 #include "../../glue/storage.h"
+#include "../../utils/gui_utils.h"
 #include "../elems/ge_browser.h"
 #include "../elems/ge_channel.h"
-#include "../elems/ge_keyboard.h"
 #include "gd_browser.h"
-#include "gd_mainWindow.h"
-#include "gd_warnings.h"
 
 
 using std::string;
 
 
-extern Patch_DEPR_   G_Patch_DEPR_;
-extern Patch         G_Patch;
-extern Conf             G_Conf;
-extern Mixer         G_Mixer;
-extern gdMainWindow    *mainWin;
+extern Conf G_Conf;
 
 
-gdBrowser::gdBrowser(const char *title, const char *initPath, Channel *ch, int type, int stackType)
-       :       gWindow  (396, 302, title),
-               ch       (ch),
-               type     (type),
-               stackType(stackType)
+gdBaseBrowser::gdBaseBrowser(int x, int y, int w, int h, const string &title,
+               const string &path, void (*callback)(void*))
+       :       gWindow(x, y, w, h, title.c_str()), callback(callback)
 {
        set_non_modal();
 
-       browser = new gBrowser(8, 36, 380, 230);
-       Fl_Group *group_btn = new Fl_Group(8, 274, 380, 20);
-               gBox *b = new gBox(8, 274, 204, 20);                                            // spacer window border <-> buttons
-               ok        = new gClick(308, 274, 80, 20);
-               cancel  = new gClick(220, 274, 80, 20, "Cancel");
-               status  = new gProgress(8, 274, 204, 20);
-               status->minimum(0);
-               status->maximum(1);
-               status->hide();   // show the bar only if necessary
-       group_btn->resizable(b);
-       group_btn->end();
-
-       Fl_Group *group_upd = new Fl_Group(8, 8, 380, 25);
-               if (type == BROWSER_SAVE_PATCH || type == BROWSER_SAVE_SAMPLE || type == BROWSER_SAVE_PROJECT)  /// bitmask please!
-                       name = new gInput(208, 8, 152, 20);
-               if (type == BROWSER_SAVE_PATCH || type == BROWSER_SAVE_SAMPLE || type == BROWSER_SAVE_PROJECT)  /// bitmask please!
-                       where = new gInput(8, 8, 192, 20);
-               else
-                       where = new gInput(8, 8, 352, 20);
-               updir   = new gClick(368, 8, 20, 20, "", updirOff_xpm, updirOn_xpm);
-       group_upd->resizable(where);
-       group_upd->end();
-
-       end();
-
-       resizable(browser);
-       size_range(w(), h(), 0, 0);
+       groupTop = new Fl_Group(8, 8, w-16, 20);
+               where = new gInput(groupTop->x(), groupTop->y(), 152, 20);
+               updir   = new gClick(groupTop->x()+groupTop->w()-20, groupTop->y(), 20, 20, "", updirOff_xpm, updirOn_xpm);
+       groupTop->end();
+       groupTop->resizable(where);
 
        where->readonly(true);
        where->cursor_color(COLOR_BG_DARK);
+       where->value(path.c_str());
 
-       if (type == BROWSER_SAVE_PATCH || type == BROWSER_SAVE_SAMPLE || type == BROWSER_SAVE_PROJECT)  /// bitmask please!
-               ok->label("Save");
-       else
-               ok->label("Load");
+       updir->callback(cb_up, (void*) this);
 
-       if (type == BROWSER_LOAD_PATCH)
-               ok->callback(cb_load_patch, (void*)this);
-       else
-       if (type == BROWSER_LOAD_SAMPLE)
-               ok->callback(cb_load_sample, (void*)this);
-       else
-       if (type == BROWSER_SAVE_PATCH) {
-               ok->callback(cb_save_patch, (void*)this);
-               name->value(G_Patch.name == "" ? "my_patch.gptc" : G_Patch.name.c_str());
-               name->maximum_size(MAX_PATCHNAME_LEN+5); // +5 for ".gptc"
-       }
-       else
-       if (type == BROWSER_SAVE_SAMPLE) {
-               ok->callback(cb_save_sample, (void*)this);
-               name->value(((SampleChannel*)ch)->wave->name.c_str());
-       }
-       else
-       if (type == BROWSER_SAVE_PROJECT) {
-               ok->callback(cb_save_project, (void*)this);
-               name->value(gStripExt(G_Patch.name).c_str());
-       }
+       browser = new gBrowser(8, groupTop->y()+groupTop->h()+8, w-16, h-73);
+       browser->loadDir(path);
+       if (path == G_Conf.browserLastPath)
+               browser->preselect(G_Conf.browserPosition, G_Conf.browserLastValue);
 
-       ok->shortcut(FL_Enter);
+       Fl_Group *groupButtons = new Fl_Group(8, browser->y()+browser->h()+8, w-16, 20);
+               ok        = new gClick(w-88, groupButtons->y(), 80, 20);
+               cancel  = new gClick(w-ok->w()-96, groupButtons->y(), 80, 20, "Cancel");
+               status  = new gProgress(8, groupButtons->y(), cancel->x()-16, 20);
+               status->minimum(0);
+               status->maximum(1);
+               status->hide();   // show the bar only if necessary
+       groupButtons->resizable(status);
+       groupButtons->end();
+
+       end();
 
-       updir->callback(cb_up, (void*)this);
-       cancel->callback(cb_close, (void*)this);
-       browser->callback(cb_down, this);
-       browser->path_obj = where;
-       browser->init(initPath);
+       cancel->callback(cb_close, (void*) this);
 
-       if (G_Conf.browserW)
-               resize(G_Conf.browserX, G_Conf.browserY, G_Conf.browserW, G_Conf.browserH);
+       resizable(browser);
+       size_range(320, 200);
 
        gu_setFavicon(this);
        show();
@@ -141,189 +95,175 @@ gdBrowser::gdBrowser(const char *title, const char *initPath, Channel *ch, int t
 /* -------------------------------------------------------------------------- */
 
 
-gdBrowser::~gdBrowser() {
+gdBaseBrowser::~gdBaseBrowser()
+{
        G_Conf.browserX = x();
        G_Conf.browserY = y();
        G_Conf.browserW = w();
        G_Conf.browserH = h();
+       G_Conf.browserPosition = browser->position();
+       G_Conf.browserLastPath = gDirname(browser->getSelectedItem());
+       G_Conf.browserLastValue = browser->value();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::cb_load_patch  (Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_load_patch();  }
-void gdBrowser::cb_load_sample (Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_load_sample(); }
-void gdBrowser::cb_save_sample (Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_save_sample(); }
-void gdBrowser::cb_save_patch  (Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_save_patch(); }
-void gdBrowser::cb_save_project(Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_save_project(); }
-void gdBrowser::cb_down        (Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_down(); }
-void gdBrowser::cb_up          (Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_up(); }
-void gdBrowser::cb_close       (Fl_Widget *v, void *p)  { ((gdBrowser*)p)->__cb_close(); }
+void gdBaseBrowser::cb_up   (Fl_Widget *v, void *p) { ((gdBaseBrowser*)p)->__cb_up(); }
+void gdBaseBrowser::cb_close(Fl_Widget *v, void *p) { ((gdBaseBrowser*)p)->__cb_close(); }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_load_patch() {
+void gdBaseBrowser::__cb_up() {
+       string dir = browser->getCurrentDir();
+       dir = dir.substr(0, dir.find_last_of(G_SLASH_STR));  // remove up to the next slash
+       browser->loadDir(dir);
+       where->value(browser->getCurrentDir().c_str());
+}
 
-       if (browser->text(browser->value()) == NULL)
-               return;
 
-       bool isProject = gIsProject(browser->get_selected_item());
-       int res = glue_loadPatch(browser->get_selected_item(), status, isProject);
+/* -------------------------------------------------------------------------- */
+
 
-       if (res == PATCH_UNREADABLE) {
-               status->hide();
-               if (isProject)
-                       gdAlert("This project is unreadable.");
-               else
-                       gdAlert("This patch is unreadable.");
-       }
-       else
-       if (res == PATCH_INVALID) {
-               status->hide();
-               if (isProject)
-                       gdAlert("This project is not valid.");
-               else
-                       gdAlert("This patch is not valid.");
-       }
-       else
-               do_callback();
+void gdBaseBrowser::__cb_close() {
+       do_callback();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_save_sample() {
-
-       if (strcmp(name->value(), "") == 0) {    /// FIXME glue business
-               gdAlert("Please choose a file name.");
-               return;
-       }
+void gdBaseBrowser::setStatusBar(float v)
+{
+       status->value(status->value() + v);
+       Fl::wait(0);
+}
 
-       /* bruteforce check extension. */
 
-       string filename = gStripExt(name->value());
-       char fullpath[PATH_MAX];
-       sprintf(fullpath, "%s/%s.wav", where->value(), filename.c_str());
+/* -------------------------------------------------------------------------- */
 
-       if (gFileExists(fullpath))
-               if (!gdConfirmWin("Warning", "File exists: overwrite?"))
-                       return;
 
-       if (((SampleChannel*)ch)->save(fullpath))
-               do_callback();
-       else
-               gdAlert("Unable to save this sample!");
+string gdBaseBrowser::getSelectedItem()
+{
+       return browser->getSelectedItem();
 }
 
 
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_load_sample() {
-       if (browser->text(browser->value()) == NULL)
-               return;
+gdSaveBrowser::gdSaveBrowser(int x, int y, int w, int h, const string &title,
+               const string &path, const string &_name, void (*cb)(void*), Channel *ch)
+       :       gdBaseBrowser(x, y, w, h, title, path, cb)
+{
+       channel = ch;
 
-       int res = glue_loadChannel((SampleChannel*) ch, browser->get_selected_item());
+       where->size(groupTop->w()-236, 20);
 
-       if (res == SAMPLE_LOADED_OK) {
-               do_callback();
-               mainWin->delSubWindow(WID_SAMPLE_EDITOR); // if editor is open
-       }
-       else
-               mainWin->keyboard->printChannelMessage(res);
+       name = new gInput(where->x()+where->w()+8, 8, 200, 20);
+       name->value(_name.c_str());
+       groupTop->add(name);
+
+       browser->callback(cb_down, (void*) this);
+
+       ok->label("Save");
+       ok->callback(cb_save, (void*) this);
+       ok->shortcut(FL_ENTER);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_down() {
-       const char *path = browser->get_selected_item();
-       if (!path)  // when click on an empty area
-               return;
-       if (!gIsDir(path)) {
-
-               /* set the name of the patch/sample/project as the selected item */
-
-               if (type == BROWSER_SAVE_PATCH || type == BROWSER_SAVE_SAMPLE || type == BROWSER_SAVE_PROJECT) {
-                       if (gIsProject(path)) {
-                               string tmp = browser->text(browser->value());
-                               tmp.erase(0, 4);
-                               name->value(tmp.c_str());
-                       }
-                       else
-                               name->value(browser->text(browser->value()));
-               }
+void gdSaveBrowser::cb_save(Fl_Widget *v, void *p) { ((gdSaveBrowser*)p)->__cb_save(); }
+void gdSaveBrowser::cb_down(Fl_Widget *v, void *p) { ((gdSaveBrowser*)p)->__cb_down(); }
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdSaveBrowser::__cb_down()
+{
+       string path = browser->getSelectedItem();
+
+       if (path.empty())  // when click on an empty area
                return;
+
+       /* if the selected item is a directory just load its content. If it's a file
+        * use it as the file name (i.e. fill name->value()). */
+
+       if (gIsDir(path)) {
+               browser->loadDir(path);
+               where->value(browser->getCurrentDir().c_str());
        }
-       browser->clear();
-       browser->down_dir(path);
-       browser->sort();
+       else
+               name->value(browser->getSelectedItem(false).c_str());
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_up() {
-       browser->clear();
-       browser->up_dir();
-       browser->sort();
+void gdSaveBrowser::__cb_save()
+{
+       callback((void*) this);
 }
 
 
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_save_patch()
+gdLoadBrowser::gdLoadBrowser(int x, int y, int w, int h, const string &title,
+               const string &path, void (*cb)(void*), Channel *ch)
+       :       gdBaseBrowser(x, y, w, h, title, path, cb)
 {
-       if (strcmp(name->value(), "") == 0) {  /// FIXME glue business
-               gdAlert("Please choose a file name.");
-               return;
-       }
+       channel = ch;
 
-       string fullpath = where->value() + gGetSlash() + gStripExt(name->value()) + ".gptc";
+       where->size(groupTop->w()-updir->w()-8, 20);
 
-       if (gFileExists(fullpath.c_str()))
-               if (!gdConfirmWin("Warning", "File exists: overwrite?"))
-                       return;
+       browser->callback(cb_down, (void*) this);
 
-  if (glue_savePatch(fullpath, name->value(), false)) // false == not a project
-               do_callback();
-       else
-               gdAlert("Unable to save the patch!");
+       ok->label("Load");
+       ok->callback(cb_load, (void*) this);
+       ok->shortcut(FL_ENTER);
 }
 
 
+
+
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_save_project()
-{
-       if (strcmp(name->value(), "") == 0) {    /// FIXME glue business
-               gdAlert("Please choose a project name.");
-               return;
-       }
+void gdLoadBrowser::cb_load(Fl_Widget *v, void *p) { ((gdLoadBrowser*)p)->__cb_load(); }
+void gdLoadBrowser::cb_down(Fl_Widget *v, void *p) { ((gdLoadBrowser*)p)->__cb_down(); }
 
-       string fullpath = where->value() + gGetSlash() + gStripExt(name->value()) + ".gprj";
 
-       if (gIsProject(fullpath.c_str()) && !gdConfirmWin("Warning", "Project exists: overwrite?"))
-               return;
+/* -------------------------------------------------------------------------- */
 
-       if (glue_saveProject(fullpath, name->value()))
-               do_callback();
-       else
-               gdAlert("Unable to save the project!");
+
+void gdLoadBrowser::__cb_load()
+{
+       callback((void*) this);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdBrowser::__cb_close() {
-       do_callback();
+void gdLoadBrowser::__cb_down()
+{
+       string path = browser->getSelectedItem();
+
+       if (path.empty() || !gIsDir(path)) // when click on an empty area or not a dir
+               return;
+
+       browser->loadDir(path);
+       where->value(browser->getCurrentDir().c_str());
 }
index 7700fab37e763a1ddb80616c866c063b8d0d369e..bf797ec6d7d515f48e94865ed17bdf4330e22151 100644 (file)
@@ -1,10 +1,10 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * gd_browser
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
  * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #ifndef GD_BROWSER_H
 
 #include <FL/Fl.H>
 #include <FL/Fl_Double_Window.H>
+#include "../elems/ge_mixed.h"
 #include "../elems/ge_window.h"
 
 
-/* TODO - this class must be subclassed into gdPluginBrowser, gdFileBrowser,
- * and so on. It's a real mess right now. */
+class gdBaseBrowser : public gWindow
+{
+protected:
 
-class gdBrowser : public gWindow {
-
-private:
-       static void cb_down(Fl_Widget *v, void *p);
-       static void cb_up  (Fl_Widget *v, void *p);
-       static void cb_load_sample (Fl_Widget *v, void *p);
-       static void cb_save_sample (Fl_Widget *v, void *p);
-       static void cb_load_patch  (Fl_Widget *v, void *p);
-       static void cb_save_patch  (Fl_Widget *v, void *p);
-       static void cb_save_project(Fl_Widget *v, void *p);
-       static void cb_close       (Fl_Widget *w, void *p);
-
-       inline void __cb_down();
-       inline void __cb_up();
-       inline void __cb_load_sample();
-       inline void __cb_save_sample();
-       inline void __cb_save_project();
-       inline void __cb_load_patch();
-       inline void __cb_save_patch();
-       inline void __cb_close();
-       
+       class Fl_Group  *groupTop;
        class gBrowser  *browser;
        class gClick    *ok;
        class gClick    *cancel;
        class gInput    *where;
-       class gInput    *name;
        class gClick    *updir;
        class gProgress *status;
 
-       class Channel *ch;
+       static void cb_up   (Fl_Widget *v, void *p);
+       static void cb_close(Fl_Widget *w, void *p);
+
+       inline void __cb_up  ();
+       inline void __cb_close();
+
+       /* Callback
+        * Fired when the save/load button is pressed. */
+
+       void (*callback)(void*);
+
+       class Channel *channel;
+
+public:
+
+       gdBaseBrowser(int x, int y, int w, int h, const string &title,
+                       const string &path,     void (*callback)(void*));
+
+       ~gdBaseBrowser();
+
+       /* getSelectedItem
+        * Return the full path of the selected file. */
+
+       string getSelectedItem();
+
+       /* setStatusBar
+        * Increment status bar for progress tracking. */
+
+       void setStatusBar(float v);
+
+       inline gProgress *getStatusBar() { return status; }  // TODO - remove with Patch_DEPR_
+       inline void showStatusBar()      { status->show(); }
+       inline void hideStatusBar()      { status->hide(); }
+       inline Channel *getChannel()     { return channel; }
+       inline void fireCallback()       { callback((void*) this); }
+       inline string getCurrentPath()   { return where->value(); }
+};
+
+
+/* -------------------------------------------------------------------------- */
+
+
+class gdSaveBrowser : public gdBaseBrowser
+{
+private:
+
+       class gInput *name;
+
+       static void cb_down(Fl_Widget *v, void *p);
+       static void cb_save(Fl_Widget *w, void *p);
+
+       inline void __cb_down();
+       inline void __cb_save();
+
+public:
+
+       gdSaveBrowser(int x, int y, int w, int h, const string &title,
+                       const string &path,     const string &name, void (*callback)(void*),
+                       class Channel *ch);
+
+       string getName() { return name->value(); }
+};
 
-       /* browser type: see const.h */
 
-       /** FIXME internal enum:
-        * enum browserType {
-                * TYPE_A,
-                * TYPE_B,
-                * ....
-                * }; */
-       int type;
+/* -------------------------------------------------------------------------- */
 
-       /* PluginHost_DEPR_ stack type. Used only when loading plugins */
 
-       int stackType;
+class gdLoadBrowser : public gdBaseBrowser
+{
+private:
 
-       char selectedFile[FILENAME_MAX];
+       static void cb_load(Fl_Widget *w, void *p);
+       static void cb_down(Fl_Widget *v, void *p);
+
+       inline void __cb_load();
+       inline void __cb_down();
 
 public:
-       gdBrowser(const char *title, const char *initPath, class Channel *ch, int type, int stackType=0);
-       ~gdBrowser();
 
-       char* SelectedFile();
+       gdLoadBrowser(int x, int y, int w, int h, const string &title,
+                       const string &path,     void (*callback)(void*), class Channel *ch);
 };
 
 #endif
index 8e47cc347750cc6cfe1035b53ff0cfe45d05dde3..5d7da03e7324ee975f22e81a12ac0777e08a95f5 100644 (file)
@@ -669,12 +669,18 @@ void gTabMidi::fetchMidiMaps()
                midiMap->deactivate();
                return;
        }
+
        for (unsigned i=0; i<G_MidiMap.maps.size(); i++) {
                const char *imap = G_MidiMap.maps.at(i).c_str();
                midiMap->add(imap);
                if (G_Conf.midiMapPath == imap)
                        midiMap->value(i);
        }
+
+       /* Preselect the 0 midimap if nothing is selected but midimaps exist. */
+       
+       if (midiMap->value() == -1 && G_MidiMap.maps.size() > 0)
+               midiMap->value(0);
 }
 
 
@@ -910,7 +916,7 @@ void gTabPlugins::__cb_scan(Fl_Widget *w)
 {
        info->show();
        G_PluginHost.scanDir(folderPath->value(), cb_onScan, (void*) this);
-       G_PluginHost.saveList(gGetHomePath() + gGetSlash() + "plugins.xml");
+       G_PluginHost.saveList(gGetHomePath() + G_SLASH + "plugins.xml");
        info->hide();
        updateCount();
 }
index b6d4d5c1d74b1a568783f389283ca7c3b103e946..501edfe23dd7faa0dd49e1559704e02bc3df08c6 100644 (file)
@@ -202,7 +202,7 @@ gdEditor::gdEditor(SampleChannel *ch)
 
   if (ch->panRight < 1.0f) {
     char buf[8];
-    sprintf(buf, "%d L", abs((ch->panRight * 100.0f) - 100));
+    sprintf(buf, "%d L", (int) abs((ch->panRight * 100.0f) - 100));
     pan->value(ch->panRight);
     panNum->value(buf);
   }
@@ -212,7 +212,7 @@ gdEditor::gdEditor(SampleChannel *ch)
   }
   else {
     char buf[8];
-    sprintf(buf, "%d R", abs((ch->panLeft * 100.0f) - 100));
+    sprintf(buf, "%d R", (int) abs((ch->panLeft * 100.0f) - 100));
     pan->value(2.0f - ch->panLeft);
     panNum->value(buf);
   }
index c10021bbfb263f1e9a6d7d2daca1126f1dadb747..b2012c20ab75519459677dedbdc313ce05029a97 100644 (file)
@@ -43,6 +43,7 @@
 #include "../../core/conf.h"
 #include "../../core/pluginHost.h"
 #include "../../glue/glue.h"
+#include "../../glue/storage.h"
 #include "../elems/ge_keyboard.h"
 #include "gd_warnings.h"
 #include "gd_bpmInput.h"
@@ -57,6 +58,7 @@
 
 extern Mixer                    G_Mixer;
 extern Patch_DEPR_   G_Patch_DEPR_;
+extern Patch         G_Patch;
 extern Conf                             G_Conf;
 extern gdMainWindow *mainWin;
 extern bool                                     G_quit;
@@ -67,6 +69,7 @@ gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **arg
        : gWindow(W, H, title)
 {
        Fl::visible_focus(0);
+
        Fl::background(25, 25, 25);
        Fl::set_boxtype(G_BOX, gDrawBox, 1, 1, 2, 2);    // custom box G_BOX
 
@@ -109,6 +112,7 @@ gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **arg
        add(keyboard);
        callback(cb_endprogram);
        gu_setFavicon(this);
+
        show(argc, argv);
 }
 
@@ -317,7 +321,11 @@ void gMenu::__cb_file()
 
 
        if (strcmp(m->label(), "Open patch or project...") == 0) {
-               gWindow *childWin = new gdBrowser("Load Patch", G_Conf.patchPath.c_str(), 0, BROWSER_LOAD_PATCH);
+               //gWindow *childWin = new gdBrowser("Load Patch", G_Conf.patchPath.c_str(), 0, BROWSER_LOAD_PATCH);
+               //gu_openSubWindow(mainWin, childWin, WID_FILE_BROWSER);
+               gWindow *childWin = new gdLoadBrowser(G_Conf.browserX, G_Conf.browserY,
+                               G_Conf.browserW, G_Conf.browserH, "Load patch or project",
+                               G_Conf.patchPath, glue_loadPatch, NULL);
                gu_openSubWindow(mainWin, childWin, WID_FILE_BROWSER);
                return;
        }
@@ -325,12 +333,16 @@ void gMenu::__cb_file()
                if (G_Mixer.hasLogicalSamples() || G_Mixer.hasEditedSamples())
                        if (!gdConfirmWin("Warning", "You should save a project in order to store\nyour takes and/or processed samples."))
                                return;
-               gWindow *childWin = new gdBrowser("Save Patch", G_Conf.patchPath.c_str(), 0, BROWSER_SAVE_PATCH);
+               gWindow *childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY,
+                               G_Conf.browserW, G_Conf.browserH, "Save patch",
+                               G_Conf.patchPath, G_Patch.name, glue_savePatch, NULL);
                gu_openSubWindow(mainWin, childWin, WID_FILE_BROWSER);
                return;
        }
        if (strcmp(m->label(), "Save project...") == 0) {
-               gWindow *childWin = new gdBrowser("Save Project", G_Conf.patchPath.c_str(), 0, BROWSER_SAVE_PROJECT);
+               gWindow *childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY,
+                               G_Conf.browserW, G_Conf.browserH, "Save project",
+                               G_Conf.patchPath, G_Patch.name, glue_saveProject, NULL);
                gu_openSubWindow(mainWin, childWin, WID_FILE_BROWSER);
                return;
        }
index 9ea9d224fe4e7ad8e0170bab58b2bad3c6a9638f..433284f76ed3fadc0346eef9b3b0c186a0db7443 100644 (file)
@@ -147,12 +147,6 @@ void gdPluginList::__cb_addPlugin() {
       stackType, ch);
   addSubWindow(pc);
   pc->callback(cb_refreshList, (void*)this);   // 'this' refers to gdPluginList
-
-#if 0
-       gdBrowser *b = new gdBrowser("Browse Plugin_DEPR_", G_Conf.pluginPath.c_str(), ch, BROWSER_LOAD_PLUGIN, stackType);
-       addSubWindow(b);
-       b->callback(cb_refreshList, (void*)this);       // 'this' refers to gdPluginList
-#endif
 }
 
 
@@ -363,32 +357,6 @@ void gdPlugin::__cb_openPluginWindow()
   else {
     w = new gdPluginWindow(pPlugin);
   }
-#if 0
-
-       /* TODO - at the moment you can open a window for each plugin in the stack.
-        * This is not consistent with the rest of the gui. You can avoid this by
-        * calling
-        *
-        * gu_openSubWindow(this, new gdPluginWindow(pPlugin), WID_FX);
-        *
-        * instead of the following code.
-        *
-        * EDIT 2 - having only 1 plugin window would be very uncomfortable */
-
-       if (!pParent->hasWindow(pPlugin->getId()+1)) {
-               gWindow *w;
-               if (pPlugin->hasEditor())
-#ifdef __APPLE__
-                       w = new gdPluginWindowGUImac(pPlugin);
-#else
-                       w = new gdPluginWindowGUI(pPlugin);
-#endif
-               else
-                       w = new gdPluginWindow(pPlugin);
-               w->setId(pPlugin->getId()+1);
-               pParent->addSubWindow(w);
-       }
-#endif
 }
 
 
index 01fe5fafc95380d7362c4bb12cf4618d4df75fa1..b50b1f4a1a57e238aab3d466bae89d2804aef7b8 100644 (file)
@@ -52,27 +52,36 @@ gdPluginWindowGUI::gdPluginWindowGUI(Plugin *pPlugin)
   show();
 
 #ifndef __APPLE__
+
   Fl::check();
+
 #endif
 
   gLog("[gdPluginWindowGUI] opening GUI, this=%p, xid=%p\n",
     (void*) this, (void*) fl_xid(this));
 
-  pPlugin->initEditor();
-
 #if defined(__APPLE__)
+
   void *cocoaWindow = (void*) fl_xid(this);
   cocoa_setWindowSize(cocoaWindow, pPlugin->getEditorW(), pPlugin->getEditorH());
   pPlugin->showEditor(cocoa_getViewFromWindow(cocoaWindow));
+
 #else
+
   pPlugin->showEditor((void*) fl_xid(this));
+
 #endif
 
-  resize(0, 0, pPlugin->getEditorW(), pPlugin->getEditorH());
+  int pluginW = pPlugin->getEditorW();
+  int pluginH = pPlugin->getEditorH();
+
+  printf("w=%d h=%d\n", Fl::w(), Fl::h());
+
+  resize((Fl::w() - pluginW) / 2, (Fl::h() - pluginH) / 2, pluginW, pluginH);
 
   Fl::add_timeout(GUI_PLUGIN_RATE, cb_refresh, (void*) this);
 
-  copy_label(pPlugin->getName().toStdString().c_str());
+  copy_label(pPlugin->getName().toRawUTF8());
 
 }
 
index fdedf085141ae88c36489aa5d37181ac61f6c4f0..81b453ab1f514f8dcba6cdbba1a1f258eb9c58fd 100644 (file)
@@ -1,10 +1,10 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * ge_actionChannel
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
  * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #include <FL/fl_draw.H>
@@ -44,11 +44,13 @@ extern Mixer         G_Mixer;
 extern Conf             G_Conf;
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 gActionChannel::gActionChannel(int x, int y, gdActionEditor *pParent, SampleChannel *ch)
- : gActionWidget(x, y, 200, 40, pParent), ch(ch), selected(NULL)
+  : gActionWidget(x, y, 200, 40, pParent),
+    ch           (ch),
+    selected     (NULL)
 {
        size(pParent->totalWidth, h());
 
@@ -58,49 +60,49 @@ gActionChannel::gActionChannel(int x, int y, gdActionEditor *pParent, SampleChan
        for (unsigned i=0; i<recorder::frames.size(); i++) {
                for (unsigned j=0; j<recorder::global.at(i).size(); j++) {
 
-                       recorder::action *ra = recorder::global.at(i).at(j);
-
-                       if (ra->chan == pParent->chan->index) {
-
-                               /* don't show actions > than the grey area */
-
-                               if (recorder::frames.at(i) > G_Mixer.totalFrames)
-                                       continue;
-
-                               /* skip the killchan actions in a singlepress channel. They cannot be recorded
-                                * in such mode, but they can exist if you change from another mode to singlepress */
-
-                               if (ra->type == ACTION_KILLCHAN && ch->mode == SINGLE_PRESS)
-                                       continue;
-
-                               /* also filter out ACTION_KEYREL: it's up to gAction to find the other piece
-                                * (namely frame_b) */
-
-                               if (ra->type & (ACTION_KEYPRESS | ACTION_KILLCHAN))     {
-                                       int ax = x+(ra->frame/pParent->zoom);
-                                       gAction *a = new gAction(
-                                                       ax,           // x
-                                                       y+4,          // y
-                                                       h()-8,        // h
-                                                       ra->frame,        // frame_a
-                                                       i,            // n. of recordings
-                                                       pParent,      // pointer to the pParent window
-                                                       ch,           // pointer to SampleChannel
-                                                       false,        // record = false: don't record it, we are just displaying it!
-                                                       ra->type);    // type of action
-                                       add(a);
-                               }
-                       }
+                       recorder::action *action = recorder::global.at(i).at(j);
+
+      /* Don't show actions:
+      - that don't belong to the displayed channel (!= pParent->chan->index);
+      - that are covered by the grey area (> G_Mixer.totalFrames);
+      - of type ACTION_KILLCHAN in a SINGLE_PRESS channel. They cannot be
+        recorded in such mode, but they can exist if you change from another
+        mode to singlepress;
+      - of type ACTION_KEYREL in a SINGLE_PRESS channel. It's up to gAction to
+        find the other piece (namely frame_b)
+      - not of types ACTION_KEYPRESS | ACTION_KEYREL | ACTION_KILLCHAN */
+
+      if ((action->chan != pParent->chan->index)                            ||
+          (recorder::frames.at(i) > G_Mixer.totalFrames)                    ||
+          (action->type == ACTION_KILLCHAN && ch->mode == SINGLE_PRESS)     ||
+          (action->type == ACTION_KEYREL && ch->mode == SINGLE_PRESS)       ||
+          (action->type & ~(ACTION_KEYPRESS | ACTION_KEYREL | ACTION_KILLCHAN))
+      )
+        continue;
+
+                       int ax = x + (action->frame / pParent->zoom);
+                       gAction *a = new gAction(
+                                       ax,               // x
+                                       y + 4,            // y
+                                       h() - 8,          // h
+                                       action->frame,    // frame_a
+                                       i,                // n. of recordings
+                                       pParent,          // pointer to the pParent window
+                                       ch,               // pointer to SampleChannel
+                                       false,            // record = false: don't record it, we are just displaying it!
+                                       action->type);    // type of action
+                       add(a);
                }
        }
        end(); // mandatory when you add widgets to a fl_group, otherwise mega malfunctions
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-gAction *gActionChannel::getSelectedAction() {
+gAction *gActionChannel::getSelectedAction()
+{
        for (int i=0; i<children(); i++) {
                int action_x  = ((gAction*)child(i))->x();
                int action_w  = ((gAction*)child(i))->w();
@@ -111,11 +113,11 @@ gAction *gActionChannel::getSelectedAction() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void gActionChannel::updateActions() {
-
+void gActionChannel::updateActions()
+{
        /* when zooming, don't delete and re-add actions, just MOVE them. This
         * function shifts the action by a zoom factor. Those singlepress are
         * stretched, as well */
@@ -138,11 +140,11 @@ void gActionChannel::updateActions() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void gActionChannel::draw() {
-
+void gActionChannel::draw()
+{
        /* draw basic boundaries (+ beat bars) and hide the unused area. Then
         * draw the children (the actions) */
 
@@ -161,11 +163,11 @@ void gActionChannel::draw() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int gActionChannel::handle(int e) {
-
+int gActionChannel::handle(int e)
+{
        int ret = Fl_Group::handle(e);
 
        /* do nothing if the widget is deactivated. It could happen for loopmode
@@ -177,69 +179,72 @@ int gActionChannel::handle(int e) {
        switch (e) {
 
                case FL_DRAG: {
-                       if (selected != NULL) {   // if you don't drag an empty area
 
-                               /* if onLeftEdge o onRightEdge are true it means that you're resizing
-                                * an action. Otherwise move the widget. */
+      if (selected == NULL) {  // if you drag an empty area
+        ret = 1;
+        break;
+      }
 
-                               if (selected->onLeftEdge || selected->onRightEdge) {
+                       /* if onLeftEdge o onRightEdge are true it means that you're resizing
+                        * an action. Otherwise move the widget. */
 
-                                       /* some checks: a) cannot resize an action < N pixels, b) no beyond zero,
-                                        * c) no beyond bar maxwidth. Checks for overlap are done in FL_RELEASE */
+                       if (selected->onLeftEdge || selected->onRightEdge) {
 
-                                       if (selected->onRightEdge) {
+                               /* some checks: a) cannot resize an action < N pixels, b) no beyond zero,
+                                * c) no beyond bar maxwidth. Checks for overlap are done in FL_RELEASE */
 
-                                               int aw = Fl::event_x()-selected->x();
-                                               int ah = selected->h();
+                               if (selected->onRightEdge) {
 
-                                               if (Fl::event_x() < selected->x()+gAction::MIN_WIDTH)
-                                                       aw = gAction::MIN_WIDTH;
-                                               else
-                                               if (Fl::event_x() > pParent->coverX)
-                                                       aw = pParent->coverX-selected->x();
+                                       int aw = Fl::event_x()-selected->x();
+                                       int ah = selected->h();
 
-                                               selected->size(aw, ah);
-                                       }
-                                       else {
+                                       if (Fl::event_x() < selected->x()+gAction::MIN_WIDTH)
+                                               aw = gAction::MIN_WIDTH;
+                                       else
+                                       if (Fl::event_x() > pParent->coverX)
+                                               aw = pParent->coverX-selected->x();
 
-                                               int ax = Fl::event_x();
-                                               int ay = selected->y();
-                                               int aw = selected->x()-Fl::event_x()+selected->w();
-                                               int ah = selected->h();
+                                       selected->size(aw, ah);
+                               }
+                               else {
 
-                                               if (Fl::event_x() < x()) {
-                                                       ax = x();
-                                                       aw = selected->w()+selected->x()-x();
-                                               }
-                                               else
-                                               if (Fl::event_x() > selected->x()+selected->w()-gAction::MIN_WIDTH) {
-                                                       ax = selected->x()+selected->w()-gAction::MIN_WIDTH;
-                                                       aw = gAction::MIN_WIDTH;
-                                               }
-                                               selected->resize(ax, ay, aw, ah);
+                                       int ax = Fl::event_x();
+                                       int ay = selected->y();
+                                       int aw = selected->x()-Fl::event_x()+selected->w();
+                                       int ah = selected->h();
+
+                                       if (Fl::event_x() < x()) {
+                                               ax = x();
+                                               aw = selected->w()+selected->x()-x();
                                        }
+                                       else
+                                       if (Fl::event_x() > selected->x()+selected->w()-gAction::MIN_WIDTH) {
+                                               ax = selected->x()+selected->w()-gAction::MIN_WIDTH;
+                                               aw = gAction::MIN_WIDTH;
+                                       }
+                                       selected->resize(ax, ay, aw, ah);
                                }
+                       }
 
-                               /* move the widget around */
+      /* move the widget around */
 
+                       else {
+                               int real_x = Fl::event_x() - actionPickPoint;
+                               if (real_x < x())                                  // don't go beyond the left border
+                                       selected->position(x(), selected->y());
+                               else
+                               if (real_x+selected->w() > pParent->coverX+x())         // don't go beyond the right border
+                                       selected->position(pParent->coverX+x()-selected->w(), selected->y());
                                else {
-                                       int real_x = Fl::event_x() - actionPickPoint;
-                                       if (real_x < x())                                  // don't go beyond the left border
-                                               selected->position(x(), selected->y());
-                                       else
-                                       if (real_x+selected->w() > pParent->coverX+x())         // don't go beyond the right border
-                                               selected->position(pParent->coverX+x()-selected->w(), selected->y());
-                                       else {
-                                               if (pParent->gridTool->isOn()) {
-                                                       int snpx = pParent->gridTool->getSnapPoint(real_x-x()) + x() -1;
-                                                       selected->position(snpx, selected->y());
-                                               }
-                                               else
-                                                       selected->position(real_x, selected->y());
+                                       if (pParent->gridTool->isOn()) {
+                                               int snpx = pParent->gridTool->getSnapPoint(real_x-x()) + x() -1;
+                                               selected->position(snpx, selected->y());
                                        }
+                                       else
+                                               selected->position(real_x, selected->y());
                                }
-                               redraw();
                        }
+                       redraw();
                        ret = 1;
                        break;
                }
@@ -399,23 +404,23 @@ int gActionChannel::handle(int e) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-bool gActionChannel::actionCollides(int frame) {
-
+bool gActionChannel::actionCollides(int frame)
+{
        /* if SINGLE_PRESS we check that the tail (frame_b) of the action doesn't
         * overlap the head (frame) of the new one. First the general case, yet. */
 
        bool collision = false;
 
        for (int i=0; i<children() && !collision; i++)
-               if ( ((gAction*)child(i))->frame_a == frame)
+               if (((gAction*) child(i))->frame_a == frame)
                        collision = true;
 
        if (ch->mode == SINGLE_PRESS) {
                for (int i=0; i<children() && !collision; i++) {
-                       gAction *c = ((gAction*)child(i));
+                       gAction *c = ((gAction*) child(i));
                        if (frame <= c->frame_b && frame >= c->frame_a)
                                collision = true;
                }
@@ -425,15 +430,9 @@ bool gActionChannel::actionCollides(int frame) {
 }
 
 
-/* ------------------------------------------------------------------ */
-/* ------------------------------------------------------------------ */
-/* ------------------------------------------------------------------ */
-
-
-const int gAction::MIN_WIDTH = 8;
-
-
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
 
 
 /** TODO - index is useless?
@@ -485,11 +484,11 @@ gAction::gAction(int X, int Y, int H, int frame_a, unsigned index, gdActionEdito
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-void gAction::draw() {
 
+void gAction::draw()
+{
        int color;
        if (selected)  /// && gActionChannel !disabled
                color = COLOR_BD_1;
@@ -515,11 +514,11 @@ void gAction::draw() {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-int gAction::handle(int e) {
 
+int gAction::handle(int e)
+{
        /* ret = 0 sends the event to the parent window. */
 
        int ret = 0;
@@ -565,11 +564,11 @@ int gAction::handle(int e) {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-void gAction::addAction() {
 
+void gAction::addAction()
+{
        /* always check frame parity */
 
        if (frame_a % 2 != 0)
@@ -597,11 +596,11 @@ void gAction::addAction() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void gAction::delAction() {
-
+void gAction::delAction()
+{
        /* if SINGLE_PRESS you must delete both the keypress and the keyrelease
         * actions. */
 
@@ -619,11 +618,11 @@ void gAction::delAction() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void gAction::moveAction(int frame_a) {
-
+void gAction::moveAction(int frame_a)
+{
        /* easy one: delete previous action and record the new ones. As usual,
         * SINGLE_PRESS requires two jobs. If frame_a is valid, use that frame
         * value. */
@@ -652,25 +651,28 @@ void gAction::moveAction(int frame_a) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int gAction::absx() {
+int gAction::absx()
+{
        return x() - parent->ac->x();
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int gAction::xToFrame_a() {
+int gAction::xToFrame_a()
+{
        return (absx()) * parent->zoom;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int gAction::xToFrame_b() {
+int gAction::xToFrame_b()
+{
        return (absx() + w()) * parent->zoom;
 }
index 38bc8d87866b7836d6ab1878640ce2e3e1443a0a..051feea6e9f3ff9b8383e738117e9c5124de83d5 100644 (file)
@@ -1,10 +1,10 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * ge_actionChannel
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
  * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
+
 
 #ifndef GE_ACTIONCHANNEL_H
 #define GE_ACTIONCHANNEL_H
 
+
 #include <FL/Fl.H>
 #include <FL/Fl_Box.H>
 #include "../../utils/gui_utils.h"
@@ -37,8 +39,8 @@
 #include "ge_actionWidget.h"
 
 
-class gAction : public Fl_Box {
-
+class gAction : public Fl_Box
+{
 private:
 
        bool                  selected;
@@ -48,6 +50,7 @@ private:
   char                  type;     // type of action
 
 public:
+
        gAction(int x, int y, int h, int frame_a, unsigned index,
                                  gdActionEditor *parent, class SampleChannel *ch, bool record,
                            char type);
@@ -80,14 +83,15 @@ public:
        bool onRightEdge;
        bool onLeftEdge;
 
-       static const int MIN_WIDTH;
+       static const int MIN_WIDTH = 8;
 };
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-class gActionChannel : public gActionWidget {
+class gActionChannel : public gActionWidget
+{
 
 private:
 
@@ -125,6 +129,7 @@ private:
        bool actionCollides(int frame);
 
 public:
+
        gActionChannel(int x, int y, gdActionEditor *pParent, class SampleChannel *ch);
        void draw();
        int  handle(int e);
index 8ae7d093efa0cb75ff888bd3377e135765f03469..be64cc85f8c29ac77bc83bc57beb95a3488791e8 100644 (file)
@@ -1,10 +1,10 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * gd_browser
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
  * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #include <limits.h>
 #include "../../core/const.h"
 #include "../../utils/utils.h"
+#include "../../utils/string.h"
 #include "../../utils/log.h"
+#include "../dialogs/gd_browser.h"
 #include "ge_browser.h"
 
 
-gBrowser::gBrowser(int x, int y, int w, int h, const char *L)
- : Fl_Hold_Browser(x, y, w, h, L)
+gBrowser::gBrowser(int x, int y, int w, int h)
+ : Fl_File_Browser(x, y, w, h)
 {
        box(G_BOX);
        textsize(GUI_FONT_SIZE_BASE);
        textcolor(COLOR_TEXT_0);
        selection_color(COLOR_BG_1);
        color(COLOR_BG_0);
+  type(FL_SELECT_BROWSER);
 
        this->scrollbar.color(COLOR_BG_0);
        this->scrollbar.selection_color(COLOR_BG_1);
@@ -52,256 +55,117 @@ gBrowser::gBrowser(int x, int y, int w, int h, const char *L)
        this->hscrollbar.selection_color(COLOR_BG_1);
        this->hscrollbar.labelcolor(COLOR_BD_1);
        this->hscrollbar.slider(G_BOX);
-}
-
-
-/* ------------------------------------------------------------------ */
-
-
-gBrowser::~gBrowser() {}
-
-
-/* ------------------------------------------------------------------ */
-
 
-void gBrowser::init(const char *init_path) {
-
-       gLog("[gBrowser] init path = '%s'\n", init_path);
-
-       if (init_path == NULL || !gIsDir(init_path)) {
-#if defined(__linux__) || defined(__APPLE__)
-               path_obj->value("/home");
-#elif defined(_WIN32)
-
-               /* SHGetFolderPath is deprecated. We should use SHGetKnownFolderPath
-                * but that would break compatibility with XP. On Vista, GetFolderPath
-                * is a wrapper of GetKnownFolderPath, so no problem. */
-
-               char winRoot[1024];
-               SHGetFolderPath(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, 0, winRoot); // si parte dal Desktop
-               path_obj->value(winRoot);
-#endif
-               gLog("[gBrowser] init_path null or invalid, using default\n");
-       }
-       else
-               path_obj->value(init_path);
-
-       refresh();
-       sort();
+  take_focus();  // let it have focus on startup
 }
 
 
-/* ------------------------------------------------------------------ */
-
-
-void gBrowser::refresh() {
-  DIR *dp;
-  struct dirent *ep;
-  dp = opendir(path_obj->value());
-  if (dp != NULL) {
-               while ((ep = readdir(dp))) {
-
-                       /* skip:
-                        * - "." e ".."
-                        * - hidden files */
-
-                       if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0) {
-                               if (ep->d_name[0] != '.') {
-
-                                       /* is it a folder? add square brackets. Is it a file? Append
-                                        * a '/' (on Windows seems useless, though) */
-
-                                       std::string file = path_obj->value();
-                                       file.insert(file.size(), gGetSlash());
-                                       file += ep->d_name;
-
-                                       if (gIsDir(file.c_str())) {
-                                               char name[PATH_MAX];
-                                               sprintf(name, "@b[%s]", ep->d_name);
-                                               add(name);
-                                       }
-                                       else
-                                       if (gIsProject(file.c_str())) {
-                                               char name[PATH_MAX];
-                                               sprintf(name, "@i@b%s", ep->d_name);
-                                               add(name);
-                                       }
-                                       else
-                                               add(ep->d_name);
-                               }
-                       }
-               }
-               closedir(dp);
-  }
-  else
-    gLog("[gBrowser] Couldn't open the directory '%s'\n", path_obj->value());
-}
+/* -------------------------------------------------------------------------- */
 
 
-/* ------------------------------------------------------------------ */
+void gBrowser::loadDir(const string &dir)
+{
+  currentDir = dir;
+  load(currentDir.c_str());
 
+  /* hide "../", it just screws up things  */
 
-void gBrowser::sort() {
-       for (int t=1; t<=size(); t++)
-               for (int r=t+1; r<=size(); r++)
-                       if (strcmp(text(t), text(r)) > 0)
-                               swap(t,r);
+  if (text(1) != NULL && strcmp(text(1), "../") == 0)
+    remove(1);
 }
 
 
-/* ------------------------------------------------------------------ */
-
-
-void gBrowser::up_dir() {
-
-       /* updir = remove last folder from the path. Start from strlen(-1) to
-        * skip the trailing slash */
-
-       int i = strlen(path_obj->value())-1;
+/* -------------------------------------------------------------------------- */
 
-       /* on Windows an updir from the path "X:\" (3 chars long) must redirect
-        * to the list of available devices. */
-
-#if defined(_WIN32)
-       if (i <= 3 || !strcmp(path_obj->value(), "All drives")) {
-               path_obj->value("All drives");
-               showDrives();
-               return;
-       }
-       else {
-               while (i >= 0) {
-                       if (path_obj->value()[i] == '\\')
-                               break;
-                       i--;
-               }
-
-               /* delete the last part of the string, from i to len-i, ie everything
-                * after the "/" */
-
-               std::string tmp = path_obj->value();
-               tmp.erase(i, tmp.size()-i);
-
-               /* if tmp.size == 2 we have something like 'C:'. Add a trailing
-                * slash */
-
-               if (tmp.size() == 2)
-                       tmp += "\\";
-
-               path_obj->value(tmp.c_str());
-               refresh();
-       }
-#elif defined(__linux__) || defined (__APPLE__)
-       while (i >= 0) {
-               if (path_obj->value()[i] == '/')
+int gBrowser::handle(int e)
+{
+       int ret = Fl_File_Browser::handle(e);
+  switch (e) {
+    case FL_FOCUS:
+               case FL_UNFOCUS:
+                       ret = 1;                        // enables receiving Keyboard events
                        break;
-               i--;
-       }
-
-       /* i == 0 means '/', the root dir. It's meaningless to go updir */
-
-       if (i==0)
-               path_obj->value("/");
-       else {
-
-               /* delete the last part of the string, from i to len-i, ie everything
-                * after the "/" */
-
-               std::string tmp = path_obj->value();
-               tmp.erase(i, tmp.size()-i);
-               path_obj->value(tmp.c_str());
-       }
-       refresh();
-#endif
+    case FL_KEYDOWN:  // keyboard
+      if (Fl::event_key(FL_Down))
+        select(value() + 1);
+      else
+      if (Fl::event_key(FL_Up))
+        select(value() - 1);
+      else
+      if (Fl::event_key(FL_Enter))
+        ((gdBaseBrowser*) parent())->fireCallback();
+      ret = 1;
+      break;
+    case FL_PUSH:    // mouse
+      if (Fl::event_clicks() > 0)  // double click
+        ((gdBaseBrowser*) parent())->fireCallback();
+      ret = 1;
+      break;
+    case FL_RELEASE: // mouse
+      /* nasty trick to keep the selection on mouse release */
+      if (value() > 1) {
+        select(value() - 1);
+        select(value() + 1);
+      }
+      else {
+        select(value() + 1);
+        select(value() - 1);
+      }
+      ret = 1;
+      break;
+  }
+       return ret;
 }
 
+/* -------------------------------------------------------------------------- */
 
-/* ------------------------------------------------------------------ */
 
-
-void gBrowser::down_dir(const char *path) {
-       path_obj->value(path);
-       refresh();
+string gBrowser::getCurrentDir()
+{
+  return normalize(gGetRealPath(currentDir));
 }
 
 
-/* ------------------------------------------------------------------ */
-
-
-const char *gBrowser::get_selected_item() {
-
-       /* click on an empty line */
-
-       if (text(value()) == NULL)
-               return NULL;
-
-       selected_item = text(value());
-
-       /* @ = formatting marks.
-        * @b = bold, i.e. a directory. Erease '@b[' and ']' */
-
-       if (selected_item[0] == '@') {
-               if (selected_item[1] == 'b') {
-                       selected_item.erase(0, 3);
-                       selected_item.erase(selected_item.size()-1, 1);
-               }
-               else
-               if (selected_item[1] == 'i')
-                       selected_item.erase(0, 4);
-       }
+/* -------------------------------------------------------------------------- */
 
-#if defined(__linux__) || defined(__APPLE__)
 
-       /* add path to file name, to get an absolute path. Avoid double
-        * slashes like '//' */
-
-       if (strcmp("/", path_obj->value()))
-               selected_item.insert(0, "/");
-
-       selected_item.insert(0, path_obj->value());
-       return selected_item.c_str();
-#elif defined(_WIN32)
-
-       /* if path is 'All drives' we are in the devices list and the user
-        * has clicked on a device such as 'X:\' */
+string gBrowser::getSelectedItem(bool fullPath)
+{
+  if (!fullPath)     // no full path requested? return the selected text
+    return normalize(text(value()));
+  else
+  if (value() == 0)  // no rows selected? return current directory
+    return normalize(currentDir);
+  else
+    return normalize(gGetRealPath(currentDir + G_SLASH + normalize(text(value()))));
+}
 
-       if (strcmp(path_obj->value(), "All drives") == 0)
-                       return selected_item.c_str();
-       else {
 
-               /* add '\' if the path is like 'X:\' */
+/* -------------------------------------------------------------------------- */
 
-               if (strlen(path_obj->value()) > 3) /// shouln't it be == 3?
-                       selected_item.insert(0, "\\");
 
-               selected_item.insert(0, path_obj->value());
-               return selected_item.c_str();
-       }
-#endif
+void gBrowser::preselect(int pos, int line)
+{
+  position(pos);
+  select(line);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-#ifdef _WIN32
-void gBrowser::showDrives() {
-
-       /* GetLogicalDriveStrings fills drives like that:
-        *
-        * a:\[null]b:\[null]c:\[null]...[null][null]
-        *
-        * where [null] stands for \0. */
+string gBrowser::normalize(const string &s)
+{
+  string out = s;
 
-       char drives[64];
-       char *i = drives;               // pointer to 0th element in drives
-       GetLogicalDriveStrings(64, drives);
+  /* our crappy version of Clang doesn't seem to support std::string::back() */
 
-       /* code stolen from the web, still unknown. (Jan 09, 2012). */
+#ifdef __APPLE__
+  if (out[out.length() - 1] == G_SLASH)
+#else
+  if (out.back() == G_SLASH)
+#endif
 
-       while (*i) {
-               add(i);
-               i = &i[strlen(i) + 1];
-       }
+    out = out.substr(0, out.size()-1);
+  return out;
 }
-
-#endif
index 0fbc1b725897a5d57c52522b3a94c2822ede5e47..e338143862268425d9b684120551fbfcc6c1af19 100644 (file)
@@ -1,10 +1,10 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * ge_browser
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
  * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
+
 
 #ifndef GE_BROWSER_H
 #define GE_BROWSER_H
 
 #include <FL/Fl.H>
-#include <FL/Fl_Hold_Browser.H>
+#include <FL/Fl_File_Browser.H>
 #include <string>
 #include "ge_mixed.h"
 
-class gBrowser : public Fl_Hold_Browser {
+
+using std::string;
+
+
+class gBrowser : public Fl_File_Browser
+{
+private:
+
+       string currentDir;
+
+       /* normalize
+        * Make sure the string never ends with a trailing slash. */
+
+       string normalize(const string &s);
+
 public:
-       gBrowser(int x, int y, int w, int h, const char *L=0);
-       ~gBrowser();
-       void init(const char *init_path=NULL);
-       void refresh();
-       void sort();
-       void up_dir();
-       void down_dir(const char *path);
-       const char *get_selected_item();
 
-       /* path_obj
-        * the actual path*/
+       gBrowser(int x, int y, int w, int h);
 
-       class gInput *path_obj;
+       /* init
+        * Initialize browser and show 'dir' as initial directory. */
 
-       /* selected_item
-        * choosen item */
+       void loadDir(const string &dir);
 
-       std::string selected_item;
+       /* getSelectedItem
+        * Return the full path or just the displayed name of the i-th selected item.
+        * Always with the trailing slash! */
 
-#ifdef _WIN32
-private:
+       string getSelectedItem(bool fullPath=true);
 
-       /* showDrives [WIN32 only]
-        * lists all the available drivers */
+       string getCurrentDir();
 
-       void showDrives();
-#endif
+       void preselect(int position, int line);
+
+       int handle(int e);
 };
 
 #endif
index 7069e6cdd88f7e70ee8a5ed6d1834d2e5dd3a75a..60abf9e924b90190aae1aa785aa704e1057aee7e 100644 (file)
@@ -612,9 +612,10 @@ void gBaseButton::trimLabel()
       len--;
     }
   }
-  else
+  else {
     out = "";
-    copy_label(out.c_str());
+  }
+  copy_label(out.c_str());
 }
 
 
index d098faafb6e3d7477c1dea25c0dc6aaea338b82e..3838a9e62bf8ecb6ff35904d40abac65b02ac95a 100644 (file)
@@ -38,6 +38,7 @@
 #include "../../core/midiChannel.h"
 #include "../../glue/glue.h"
 #include "../../glue/channel.h"
+#include "../../glue/storage.h"
 #include "../../utils/gui_utils.h"
 #include "../dialogs/gd_mainWindow.h"
 #include "../dialogs/gd_keyGrabber.h"
@@ -366,20 +367,21 @@ void gSampleChannel::__cb_readActions()
 
 void gSampleChannel::openBrowser(int type)
 {
-       const char *title = "";
+       gWindow *childWin = NULL;
        switch (type) {
                case BROWSER_LOAD_SAMPLE:
-                       title = "Browse Sample";
+                       childWin = new gdLoadBrowser(G_Conf.browserX, G_Conf.browserY,
+                                       G_Conf.browserW, G_Conf.browserH, "Browse sample",
+                                       G_Conf.samplePath.c_str(), glue_loadSample, ch);
                        break;
                case BROWSER_SAVE_SAMPLE:
-                       title = "Save Sample";
-                       break;
-               case -1:
-                       title = "Edit Sample";
+                       childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY,
+                                       G_Conf.browserW, G_Conf.browserH, "Save sample", \
+                                       G_Conf.samplePath.c_str(), "", glue_saveSample, ch);
                        break;
        }
-       gWindow *childWin = new gdBrowser(title, G_Conf.samplePath.c_str(), ch, type);
-       gu_openSubWindow(mainWin, childWin,     WID_FILE_BROWSER);
+       if (childWin)
+               gu_openSubWindow(mainWin, childWin,     WID_FILE_BROWSER);
 }
 
 
index 0834d63ecc0659b1b8bc1f497cd3fe519737b4f3..1ebef9fd82cdb65ed977628b1238563fe0e4b7cd 100644 (file)
@@ -72,8 +72,12 @@ void gLog(const char *format, ...) {
                return;
   va_list args;
   va_start(args, format);
-  if (mode == LOG_MODE_FILE && stat == true)
+  if (mode == LOG_MODE_FILE && stat == true) {
                vfprintf(f, format, args);
+#ifdef _WIN32
+               fflush(f);
+#endif
+       }
   else
                vprintf(format, args);
   va_end(args);
diff --git a/src/utils/string.cpp b/src/utils/string.cpp
new file mode 100644 (file)
index 0000000..167ed83
--- /dev/null
@@ -0,0 +1,56 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * utils
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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 3 of the License, or (at your option) any later version.
+ *
+ * Giada - Your Hardcore Loopmachine 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include "string.h"
+#include <limits.h>
+
+
+using std::string;
+
+
+string gGetRealPath(const string &path)
+{
+       string out = "";
+
+#if defined(__linux__) || defined(__APPLE__)
+
+       char *buf = realpath(path.c_str(), NULL);
+
+#else // Windows
+
+       char *buf = _fullpath(NULL, path.c_str(), PATH_MAX);
+
+#endif
+
+       if (buf) {
+               out = buf;
+               free(buf);
+       }
+       return out;
+}
diff --git a/src/utils/string.h b/src/utils/string.h
new file mode 100644 (file)
index 0000000..758b742
--- /dev/null
@@ -0,0 +1,45 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * utils
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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 3 of the License, or (at your option) any later version.
+ *
+ * Giada - Your Hardcore Loopmachine 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef __UTILS_STRING_H__
+#define __UTILS_STRING_H__
+
+
+#include <string>
+#include <cstdio>
+#include <vector>
+#include "log.h"
+
+
+using std::string;
+
+
+string gGetRealPath(const string &path);
+
+#endif
index 1f7a117211cf950e850e1e9320dbc82567fbcecb..16e00f49817d883c45262b683c55b2b4d2359c23 100644 (file)
@@ -27,7 +27,6 @@
  * -------------------------------------------------------------------------- */
 
 
-#include "utils.h"
 #if defined(_WIN32)                    // getcwd (unix) or __getcwd (win)
        #include <direct.h>
        #include <windows.h>
        #include <libgen.h>     // basename unix
        #include <pwd.h>        // getpwuid
 #endif
+#include "../core/const.h"
+#include "utils.h"
 
 
 using std::string;
 using std::vector;
 
 
-bool gFileExists(const char *filename) {
+bool gFileExists(const char *filename)
+{
        FILE *fh = fopen(filename, "rb");
        if (!fh) {
                return 0;
@@ -66,6 +68,12 @@ bool gFileExists(const char *filename) {
 }
 
 
+bool gFileExists(const string &filename)
+{
+       return gFileExists(filename.c_str());
+}
+
+
 /* -------------------------------------------------------------------------- */
 
 
@@ -111,6 +119,11 @@ bool gIsDir(const char *path)
 }
 
 
+bool gIsDir(const string &path)
+{
+       return gIsDir(path.c_str());
+}
+
 /* -------------------------------------------------------------------------- */
 
 
@@ -152,18 +165,11 @@ bool gMkdir(const string &path)
 
 /* -------------------------------------------------------------------------- */
 
-/* TODO - avoid this shit, just wrap the other call */
-string gBasename(const char *path)
-{
-       string out = path;
-       out.erase(0, out.find_last_of(gGetSlash().c_str())+1);
-       return out;
-}
 
 string gBasename(const string &s)
 {
        string out = s;
-       out.erase(0, out.find_last_of(gGetSlash().c_str())+1);
+       out.erase(0, out.find_last_of(G_SLASH_STR) + 1);
        return out;
 }
 
@@ -171,10 +177,12 @@ string gBasename(const string &s)
 /* -------------------------------------------------------------------------- */
 
 
-string gDirname(const char *path)
+string gDirname(const string &path)
 {
+       if (path.empty())
+               return "";
        string out = path;
-       out.erase(out.find_last_of(gGetSlash().c_str()));
+       out.erase(out.find_last_of(G_SLASH_STR));
        return out;
 }
 
@@ -241,11 +249,11 @@ string gStripExt(const string &s)
 /* -------------------------------------------------------------------------- */
 
 
-bool gIsProject(const char *path)
+bool gIsProject(const string &path)
 {
        /** FIXME - checks too weak */
 
-       if (gGetExt(path) == "gprj" && gDirExists(path))
+       if (gGetExt(path.c_str()) == "gprj" && gDirExists(path))
                return 1;
        return 0;
 }
@@ -286,18 +294,6 @@ string gGetProjectName(const char *path)
 }
 
 
-/* -------------------------------------------------------------------------- */
-
-
-string gGetSlash()
-{
-#if defined(_WIN32)
-       return "\\";
-#else
-       return "/";
-#endif
-}
-
 
 /* -------------------------------------------------------------------------- */
 
index c8da49375f17f3ff64dcd2d746d09afb9035945c..dd6ecd0e7c327068c691f9e5d616f68af900c44d 100644 (file)
@@ -42,25 +42,27 @@ using std::vector;
 
 
 bool gFileExists(const char *path);
+bool gFileExists(const string &path);
 
 bool gDirExists(const char *path);
 bool gDirExists(const string &path);
 
 bool gIsDir(const char *path);
+bool gIsDir(const string &path);
 
-bool gIsProject(const char *path);
+bool gIsProject(const string &path);
 
 bool gIsPatch(const char *path);
+bool gIsPatch(const string &path);
 
 bool gMkdir(const char *path);
 bool gMkdir(const string &path);
 
-string gBasename(const char *path);
 string gBasename(const string &s);
 
 string gReplace(string in, const string& search, const string& replace);
 
-string gDirname(const char *path);
+string gDirname(const string &s);
 
 string gTrim(const char *path);
 string gTrim(const string &s);
@@ -78,8 +80,6 @@ string gStripExt(const string &s);
 
 string gGetProjectName(const char *path); // TODO - useless!
 
-string gGetSlash();
-
 string gItoa(int i);
 
 void gSplit(string in, string sep, vector<string> *v);
diff --git a/tests/resources/test.wav b/tests/resources/test.wav
new file mode 100644 (file)
index 0000000..1e52d36
Binary files /dev/null and b/tests/resources/test.wav differ
index cf91ab9828dfe06bd2c71d12d72554981a3bbea8..930e7fae9e0eb0d7904c511ef0c7b1ad18e95a04 100644 (file)
@@ -1,5 +1,3 @@
-#ifdef RUN_TESTS_WITH_LOCAL_FILES
-
 #include "../src/core/wave.h"
 #include "catch.hpp"
 
@@ -17,10 +15,10 @@ TEST_CASE("Test Wave class")
 
   SECTION("test read & write")
   {
-    REQUIRE(w1.open("test.wav") == 1);
+    REQUIRE(w1.open("tests/resources/test.wav") == 1);
     REQUIRE(w1.readData() == 1);
-    REQUIRE(w1.rate() == 11025);
-    REQUIRE(w1.channels() == 2);
+    REQUIRE(w1.rate() == 44100);
+    REQUIRE(w1.channels() == 1);
     REQUIRE(w1.basename() == "test");
     REQUIRE(w1.extension() == "wav");
     REQUIRE(w1.writeData("test-write.wav") == true);
@@ -31,8 +29,8 @@ TEST_CASE("Test Wave class")
     Wave w2(w1);
     REQUIRE(w2.size == w1.size);
     REQUIRE(w2.isLogical == true);
-    //REQUIRE(w2.rate() == 11025);  // WHAT THE FUCK???
-    REQUIRE(w2.channels() == 2);
+    //REQUIRE(w2.rate() == 44100);  // WHAT THE FUCK???
+    REQUIRE(w2.channels() == 1);
     REQUIRE(w2.writeData("test-write.wav") == true);
   }
 
@@ -45,5 +43,3 @@ TEST_CASE("Test Wave class")
     REQUIRE(w3.writeData("test-write.wav") == true);
   }
 }
-
-#endif // #ifdef RUN_TESTS_WITH_LOCAL_FILES