editor: add the next and previous file buttons
This commit is contained in:
parent
dfe559b51e
commit
23f0ae6a13
3 changed files with 149 additions and 34 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue