editor: add the next and previous file buttons

This commit is contained in:
Jean Pierre Cimalando 2020-10-13 02:42:05 +02:00
parent dfe559b51e
commit 23f0ae6a13
3 changed files with 149 additions and 34 deletions

View file

@ -11,7 +11,7 @@ widget_class mainView {open
class Background
}
Fl_Group {} {
comment {theme=darkTheme}
comment {theme=darkTheme} open
xywh {0 0 800 110}
class LogicalGroup
} {
@ -44,16 +44,6 @@ widget_class mainView {open
xywh {185 5 380 100} box ROUNDED_BOX
class RoundedGroup
} {
Fl_Box {} {
label {File:}
xywh {200 13 40 30} labelsize 16
class Label
}
Fl_Box {} {
label {KS:}
xywh {200 45 40 30} labelsize 16
class Label
}
Fl_Box {} {
label {Separator 1}
xywh {195 41 360 5} box BORDER_BOX labeltype NO_LABEL
@ -66,12 +56,12 @@ widget_class mainView {open
}
Fl_Box sfzFileLabel_ {
label {DefaultInstrument.sfz}
xywh {265 12 230 30} labelsize 20
xywh {195 11 250 31} labelsize 20 align 20
class Label
}
Fl_Box {} {
label {Key switch}
xywh {265 44 230 30} labelsize 20
label {Key switch:}
xywh {195 44 250 30} labelsize 20 align 20
class Label
}
Fl_Box {} {
@ -81,12 +71,12 @@ widget_class mainView {open
}
Fl_Button {} {
comment {tag=kTagLoadSfzFile}
xywh {500 14 25 25} labelsize 24
xywh {505 14 25 25} labelsize 24
class LoadFileButton
}
Fl_Button {} {
comment {tag=kTagEditSfzFile}
xywh {525 14 25 25} labelsize 24
xywh {530 14 25 25} labelsize 24
class EditFileButton
}
Fl_Box infoVoicesLabel_ {
@ -111,6 +101,16 @@ widget_class mainView {open
xywh {500 76 50 25} labelsize 12 align 16
class Label
}
Fl_Button {} {
comment {tag=kTagNextSfzFile}
xywh {480 14 25 25} labelsize 24
class NextFileButton
}
Fl_Button {} {
comment {tag=kTagPreviousSfzFile}
xywh {455 14 25 25} labelsize 24
class PreviousFileButton
}
}
Fl_Group {} {open
xywh {570 5 225 100} box ROUNDED_BOX

View file

@ -11,8 +11,13 @@
#include "NativeHelpers.h"
#include <absl/strings/string_view.h>
#include <absl/strings/match.h>
#include <absl/strings/ascii.h>
#include <ghc/fs_std.hpp>
#include <array>
#include <algorithm>
#include <functional>
#include <type_traits>
#include <system_error>
#include <cstdarg>
#include <cstdio>
@ -46,6 +51,8 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
enum {
kTagLoadSfzFile,
kTagEditSfzFile,
kTagPreviousSfzFile,
kTagNextSfzFile,
kTagSetVolume,
kTagSetNumVoices,
kTagSetOversampling,
@ -101,9 +108,12 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
void chooseSfzFile();
void changeSfzFile(const std::string& filePath);
void changeToNextSfzFile(long offset);
void chooseScalaFile();
void changeScalaFile(const std::string& filePath);
static bool scanDirectoryFiles(const fs::path& dirPath, std::function<bool(const fs::path&)> filter, std::vector<fs::path>& fileNames);
static absl::string_view simplifiedFileName(absl::string_view path, absl::string_view removedSuffix, absl::string_view ifEmpty);
void updateSfzFileLabel(const std::string& filePath);
@ -377,6 +387,8 @@ void Editor::Impl::createFrameContents()
typedef STextButton HomeButton;
typedef STextButton SettingsButton;
typedef STextButton EditFileButton;
typedef STextButton PreviousFileButton;
typedef STextButton NextFileButton;
typedef SPiano Piano;
auto createLogicalGroup = [](const CRect& bounds, int, const char*, CHoriTxtAlign, int) {
@ -505,6 +517,12 @@ void Editor::Impl::createFrameContents()
auto createLoadFileButton = [&createGlyphButton](const CRect& bounds, int tag, const char*, CHoriTxtAlign, int fontsize) {
return createGlyphButton(u8"\ue1a3", bounds, tag, fontsize);
};
auto createPreviousFileButton = [&createGlyphButton](const CRect& bounds, int tag, const char*, CHoriTxtAlign, int fontsize) {
return createGlyphButton(u8"\ue0d9", bounds, tag, fontsize);
};
auto createNextFileButton = [&createGlyphButton](const CRect& bounds, int tag, const char*, CHoriTxtAlign, int fontsize) {
return createGlyphButton(u8"\ue0da", bounds, tag, fontsize);
};
auto createPiano = [](const CRect& bounds, int, const char*, CHoriTxtAlign, int) {
SPiano* piano = new SPiano(bounds);
return piano;
@ -669,6 +687,56 @@ void Editor::Impl::changeSfzFile(const std::string& filePath)
updateSfzFileLabel(filePath);
}
void Editor::Impl::changeToNextSfzFile(long offset)
{
if (currentSfzFile_.empty())
return;
const fs::path filePath = fs::u8path(currentSfzFile_);
const fs::path dirPath = filePath.parent_path();
// extract file names of regular files from the sfz directory
std::vector<fs::path> fileNames;
fileNames.reserve(64);
auto fileFilter = [](const fs::path &name) -> bool {
std::string ext = name.extension().u8string();
absl::AsciiStrToLower(&ext);
return ext == ".sfz";
};
if (!scanDirectoryFiles(dirPath, fileFilter, fileNames))
return;
// sort file names
const size_t size = fileNames.size();
if (size == 0)
return;
std::sort(fileNames.begin(), fileNames.end());
// find our current position in the file name list
size_t currentIndex = 0;
const fs::path currentFileName = filePath.filename();
while (currentIndex + 1 < size && fileNames[currentIndex] < currentFileName)
++currentIndex;
// advance to the next or previous item
typedef typename std::make_signed<size_t>::type signed_size_t;
size_t newIndex = static_cast<signed_size_t>(currentIndex) + offset;
if (static_cast<signed_size_t>(newIndex) < 0)
newIndex = static_cast<signed_size_t>(newIndex) %
static_cast<signed_size_t>(size) + size;
newIndex %= size;
if (newIndex != currentIndex) {
const fs::path newFilePath = dirPath / fileNames[newIndex];
changeSfzFile(newFilePath.u8string());
}
}
void Editor::Impl::chooseScalaFile()
{
SharedPointer<CNewFileSelector> fs = owned(CNewFileSelector::create(frame_));
@ -694,6 +762,39 @@ void Editor::Impl::changeScalaFile(const std::string& filePath)
updateScalaFileLabel(filePath);
}
bool Editor::Impl::scanDirectoryFiles(const fs::path& dirPath, std::function<bool(const fs::path&)> filter, std::vector<fs::path>& fileNames)
{
std::error_code ec;
fs::directory_iterator it { dirPath, ec };
if (ec)
return false;
fileNames.clear();
while (!ec && it != fs::directory_iterator()) {
const fs::directory_entry& ent = *it;
std::error_code fileEc;
const fs::file_status status = ent.status(fileEc);
if (fileEc)
continue;
if (status.type() == fs::file_type::regular) {
fs::path fileName = ent.path().filename();
if (!filter || filter(fileName))
fileNames.push_back(std::move(fileName));
}
it.increment(ec);
}
if (ec)
return false;
return true;
}
absl::string_view Editor::Impl::simplifiedFileName(absl::string_view path, absl::string_view removedSuffix, absl::string_view ifEmpty)
{
if (path.empty())
@ -892,6 +993,20 @@ void Editor::Impl::valueChanged(CControl* ctl)
openFileInExternalEditor(currentSfzFile_.c_str());
break;
case kTagPreviousSfzFile:
if (value != 1)
break;
Call::later([this]() { changeToNextSfzFile(-1); });
break;
case kTagNextSfzFile:
if (value != 1)
break;
Call::later([this]() { changeToNextSfzFile(+1); });
break;
case kTagLoadScalaFile:
if (value != 1)
break;

View file

@ -18,37 +18,37 @@ SettingsButton* const view__7 = createSettingsButton(CRect(107, 69, 132, 94), kT
view__3->addView(view__7);
RoundedGroup* const view__8 = createRoundedGroup(CRect(185, 5, 565, 105), -1, "", kCenterText, 14);
view__2->addView(view__8);
Label* const view__9 = createLabel(CRect(15, 8, 55, 38), -1, "File:", kCenterText, 16);
HLine* const view__9 = createHLine(CRect(10, 36, 370, 41), -1, "", kCenterText, 14);
view__8->addView(view__9);
Label* const view__10 = createLabel(CRect(15, 40, 55, 70), -1, "KS:", kCenterText, 16);
HLine* const view__10 = createHLine(CRect(10, 68, 370, 73), -1, "", kCenterText, 14);
view__8->addView(view__10);
HLine* const view__11 = createHLine(CRect(10, 36, 370, 41), -1, "", kCenterText, 14);
Label* const view__11 = createLabel(CRect(10, 6, 260, 37), -1, "DefaultInstrument.sfz", kLeftText, 20);
sfzFileLabel_ = view__11;
view__8->addView(view__11);
HLine* const view__12 = createHLine(CRect(10, 68, 370, 73), -1, "", kCenterText, 14);
Label* const view__12 = createLabel(CRect(10, 39, 260, 69), -1, "Key switch:", kLeftText, 20);
view__8->addView(view__12);
Label* const view__13 = createLabel(CRect(80, 7, 310, 37), -1, "DefaultInstrument.sfz", kCenterText, 20);
sfzFileLabel_ = view__13;
Label* const view__13 = createLabel(CRect(10, 71, 70, 96), -1, "Voices:", kRightText, 12);
view__8->addView(view__13);
Label* const view__14 = createLabel(CRect(80, 39, 310, 69), -1, "Key switch", kCenterText, 20);
LoadFileButton* const view__14 = createLoadFileButton(CRect(320, 9, 345, 34), kTagLoadSfzFile, "", kCenterText, 24);
view__8->addView(view__14);
Label* const view__15 = createLabel(CRect(10, 71, 70, 96), -1, "Voices:", kRightText, 12);
EditFileButton* const view__15 = createEditFileButton(CRect(345, 9, 370, 34), kTagEditSfzFile, "", kCenterText, 24);
view__8->addView(view__15);
LoadFileButton* const view__16 = createLoadFileButton(CRect(315, 9, 340, 34), kTagLoadSfzFile, "", kCenterText, 24);
Label* const view__16 = createLabel(CRect(75, 71, 125, 96), -1, "", kCenterText, 12);
infoVoicesLabel_ = view__16;
view__8->addView(view__16);
EditFileButton* const view__17 = createEditFileButton(CRect(340, 9, 365, 34), kTagEditSfzFile, "", kCenterText, 24);
Label* const view__17 = createLabel(CRect(130, 71, 190, 96), -1, "Max:", kRightText, 12);
view__8->addView(view__17);
Label* const view__18 = createLabel(CRect(75, 71, 125, 96), -1, "", kCenterText, 12);
infoVoicesLabel_ = view__18;
Label* const view__18 = createLabel(CRect(195, 71, 245, 96), -1, "", kCenterText, 12);
numVoicesLabel_ = view__18;
view__8->addView(view__18);
Label* const view__19 = createLabel(CRect(130, 71, 190, 96), -1, "Max:", kRightText, 12);
Label* const view__19 = createLabel(CRect(250, 71, 310, 96), -1, "Memory:", kRightText, 12);
view__8->addView(view__19);
Label* const view__20 = createLabel(CRect(195, 71, 245, 96), -1, "", kCenterText, 12);
numVoicesLabel_ = view__20;
Label* const view__20 = createLabel(CRect(315, 71, 365, 96), -1, "", kCenterText, 12);
memoryLabel_ = view__20;
view__8->addView(view__20);
Label* const view__21 = createLabel(CRect(250, 71, 310, 96), -1, "Memory:", kRightText, 12);
NextFileButton* const view__21 = createNextFileButton(CRect(295, 9, 320, 34), kTagNextSfzFile, "", kCenterText, 24);
view__8->addView(view__21);
Label* const view__22 = createLabel(CRect(315, 71, 365, 96), -1, "", kCenterText, 12);
memoryLabel_ = view__22;
PreviousFileButton* const view__22 = createPreviousFileButton(CRect(270, 9, 295, 34), kTagPreviousSfzFile, "", kCenterText, 24);
view__8->addView(view__22);
RoundedGroup* const view__23 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14);
view__2->addView(view__23);