From e2d90ba3e3c54ea1004b858dc64dbefdc978b4de Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Wed, 24 Dec 2025 21:45:51 +0100 Subject: [PATCH 1/2] Don't allow creating a new project with the same name in the same place Allow creating a project with the same name in a different path Pass currentDirectory to NewProjectDialog Path field added to NewProjectDialog When randomising a project name, re run randomizer if name already in use Adresses https://github.com/djdiskmachine/LittleGPTracker/issues/175 --- .../Views/ModalDialogs/NewProjectDialog.cpp | 40 +++--- .../Views/ModalDialogs/NewProjectDialog.h | 24 ++-- .../ModalDialogs/SelectProjectDialog.cpp | 128 +++++++++--------- 3 files changed, 100 insertions(+), 92 deletions(-) diff --git a/sources/Application/Views/ModalDialogs/NewProjectDialog.cpp b/sources/Application/Views/ModalDialogs/NewProjectDialog.cpp index 3be2afcc..132a63ca 100644 --- a/sources/Application/Views/ModalDialogs/NewProjectDialog.cpp +++ b/sources/Application/Views/ModalDialogs/NewProjectDialog.cpp @@ -2,18 +2,15 @@ #include "NewProjectDialog.h" #include "Application/Utils/RandomNames.h" -static char *buttonText[BUTTONS_LENGTH] = { - (char *)"Regen", - (char *)"Ok", - (char *)"Cancel" -} ; +static char *buttonText[BUTTONS_LENGTH] = {(char *)"Random", (char *)"Ok", + (char *)"Cancel"}; #define DIALOG_WIDTH 20 -NewProjectDialog::NewProjectDialog(View &view):ModalView(view) {} +NewProjectDialog::NewProjectDialog(View &view, Path currentPath) + : ModalView(view), currentPath_(currentPath) {} -NewProjectDialog::~NewProjectDialog() { -} +NewProjectDialog::~NewProjectDialog() {} void NewProjectDialog::DrawView() { @@ -49,10 +46,11 @@ void NewProjectDialog::DrawView() { props.invert_=(selected_==i+1) ; DrawString(x,4,text,props) ; } -}; + View::EnableNotification(); +} -void NewProjectDialog::OnPlayerUpdate(PlayerEventType ,unsigned int currentTick) { -}; +void NewProjectDialog::OnPlayerUpdate(PlayerEventType, + unsigned int currentTick) {}; void NewProjectDialog::OnFocus() { selected_=currentChar_=0; @@ -71,7 +69,7 @@ void NewProjectDialog::ProcessButtonMask(unsigned short mask,bool pressed) { // A modifier if (mask & EPBM_A) { if (mask == EPBM_A) { - std::string randomName = getRandomName(); + std::string randomName = ""; switch (selected_) { case 0: if (name_[currentChar_] == ' ') { @@ -80,14 +78,22 @@ void NewProjectDialog::ProcessButtonMask(unsigned short mask,bool pressed) { isDirty_ = true; break; case 1: - std::fill(name_ + randomName.length(), - name_ + sizeof(name_) / sizeof(name_[0]), ' '); - strncpy(name_, randomName.c_str(), randomName.length()); - lastChar_ = currentChar_ = randomName.length() - 1; + do { + randomName = getRandomName(); + std::fill(name_ + randomName.length(), + name_ + sizeof(name_) / sizeof(name_[0]), ' '); + strncpy(name_, randomName.c_str(), randomName.length()); + lastChar_ = currentChar_ = randomName.length() - 1; + } while (currentPath_.Descend(GetName()).Exists()); isDirty_ = true; break; case 2: - EndModal(1); + if (currentPath_.Descend(GetName()).Exists()) { + std::string res("Name " + std::string(name_) + " busy"); + View::SetNotification(res.c_str(), -6); + } else { + EndModal(1); + } break; case 3: EndModal(0); diff --git a/sources/Application/Views/ModalDialogs/NewProjectDialog.h b/sources/Application/Views/ModalDialogs/NewProjectDialog.h index ba1aa9c7..457f8692 100644 --- a/sources/Application/Views/ModalDialogs/NewProjectDialog.h +++ b/sources/Application/Views/ModalDialogs/NewProjectDialog.h @@ -9,20 +9,22 @@ class NewProjectDialog:public ModalView { public: - NewProjectDialog(View &view) ; - virtual ~NewProjectDialog() ; + NewProjectDialog(View &view, Path currentPath = ""); + virtual ~NewProjectDialog(); - virtual void DrawView() ; - virtual void OnPlayerUpdate(PlayerEventType ,unsigned int currentTick) ; - virtual void OnFocus() ; - virtual void ProcessButtonMask(unsigned short mask,bool pressed) ; + virtual void DrawView(); + virtual void OnPlayerUpdate(PlayerEventType, unsigned int currentTick); + virtual void OnFocus(); + virtual void ProcessButtonMask(unsigned short mask, bool pressed); + + std::string GetName(); - std::string GetName() ; private: - int selected_ ; - int lastChar_ ; - char name_[MAX_NAME_LENGTH+1] ; - int currentChar_ ; + Path currentPath_; + int selected_; + int lastChar_; + char name_[MAX_NAME_LENGTH + 1]; + int currentChar_; } ; #endif diff --git a/sources/Application/Views/ModalDialogs/SelectProjectDialog.cpp b/sources/Application/Views/ModalDialogs/SelectProjectDialog.cpp index 218050f4..7c0dc506 100644 --- a/sources/Application/Views/ModalDialogs/SelectProjectDialog.cpp +++ b/sources/Application/Views/ModalDialogs/SelectProjectDialog.cpp @@ -9,11 +9,7 @@ #define LIST_SIZE 20 #define LIST_WIDTH 32 -static char *buttonText[3]= { - "Load", - "New", - "Exit" -} ; +static char *buttonText[3] = {"Load", "New", "Exit"}; Path SelectProjectDialog::lastFolder_("root:") ; int SelectProjectDialog::lastProject_ = 0 ; @@ -25,12 +21,11 @@ static void NewProjectCallback(View &v,ModalView &dialog) { std::string selected=npd.GetName() ; SelectProjectDialog &spd=(SelectProjectDialog&)v ; Result result = spd.OnNewProject(selected) ; - if (result.Failed()) - { - Trace::Error(result.GetDescription().c_str()); + if (result.Failed()) { + Trace::Error(result.GetDescription().c_str()); + } } - } -} ; +}; SelectProjectDialog::SelectProjectDialog(View &view):ModalView(view),content_(true) { } @@ -45,16 +40,17 @@ void SelectProjectDialog::DrawView() { GUITextProperties props ; SetColor(CD_NORMAL) ; + View::EnableNotification(); -// Draw projects + // Draw projects - int x=1 ; - int y=1 ; + int x = 1; + int y = 1; - if (currentProject_=topIndex_+LIST_SIZE) { + if (currentProject_ < topIndex_) { + topIndex_ = currentProject_; + }; + if (currentProject_>=topIndex_+LIST_SIZE) { topIndex_=currentProject_-LIST_SIZE+1 ; } ; @@ -113,12 +109,11 @@ void SelectProjectDialog::DrawView() { x=offset*(i+1)-strlen(text)/2 ; props.invert_=(i==selected_)?true:false ; DrawString(x,y,text,props) ; - } - + } }; -void SelectProjectDialog::OnPlayerUpdate(PlayerEventType ,unsigned int currentTick) { -}; +void SelectProjectDialog::OnPlayerUpdate(PlayerEventType, + unsigned int currentTick) {}; void SelectProjectDialog::OnFocus() { @@ -129,29 +124,30 @@ void SelectProjectDialog::OnFocus() { void SelectProjectDialog::ProcessButtonMask(unsigned short mask,bool pressed) { if (!pressed) return ; - - if (mask&EPBM_B) { - if (mask&EPBM_UP) warpToNextProject(-LIST_SIZE) ; - if (mask&EPBM_DOWN) warpToNextProject(LIST_SIZE) ; - } else { - - // A modifier - if (mask&EPBM_A) { - switch(selected_) { + + if (mask&EPBM_B) { + if (mask & EPBM_UP) + warpToNextProject(-LIST_SIZE); + if (mask&EPBM_DOWN) warpToNextProject(LIST_SIZE) ; + } else { + + // A modifier + if (mask & EPBM_A) { + switch (selected_) { case 0: // load { - //locate folder user had selected when they hit a - int count=0 ; - Path *current=0 ; - - IteratorPtr it(content_.GetIterator()) ; - for(it->Begin();!it->IsDone();it->Next()) { - if (count==currentProject_) { - current=&it->CurrentItem() ; - break ; - } - count++ ; - } + // locate folder user had selected when they hit a + int count = 0; + Path *current = 0; + + IteratorPtr it(content_.GetIterator()); + for (it->Begin(); !it->IsDone(); it->Next()) { + if (count == currentProject_) { + current = &it->CurrentItem(); + break; + } + count++; + } //check if folder is a project, indicated by 'lgpt' being the first 4 characters of the folder name std::string name = current->GetName() ; @@ -178,20 +174,21 @@ void SelectProjectDialog::ProcessButtonMask(unsigned short mask,bool pressed) { } case 1: // new { - NewProjectDialog *npd=new NewProjectDialog(*this) ; - DoModal(npd,NewProjectCallback) ; + NewProjectDialog *npd = + new NewProjectDialog(*this, currentPath_); + DoModal(npd,NewProjectCallback) ; break ; - } - case 2: // Exit ; - EndModal(0) ; + } + case 2: // Exit ; + EndModal(0) ; break ; } - } else { + } else { - // R Modifier + // R Modifier - if (mask&EPBM_R) { - } else { + if (mask & EPBM_R) { + } else { // No modifier if (mask==EPBM_UP) warpToNextProject(-1) ; if (mask==EPBM_DOWN) warpToNextProject(1) ; @@ -204,16 +201,16 @@ void SelectProjectDialog::ProcessButtonMask(unsigned short mask,bool pressed) { selected_=(selected_+1)%3 ; isDirty_=true ; } - } - } - } + } + } + } }; void SelectProjectDialog::warpToNextProject(int amount) { - int offset=currentProject_-topIndex_ ; - int size=content_.Size() ; - currentProject_+=amount ; + int offset = currentProject_ - topIndex_; + int size = content_.Size(); + currentProject_+=amount ; if (currentProject_<0) currentProject_+=size ; if (currentProject_>=size) currentProject_-=size ; @@ -223,8 +220,7 @@ void SelectProjectDialog::warpToNextProject(int amount) { topIndex_=0 ; } ; } - isDirty_=true ; - + isDirty_ = true; } Path SelectProjectDialog::GetSelection() { @@ -233,8 +229,14 @@ Path SelectProjectDialog::GetSelection() { Result SelectProjectDialog::OnNewProject(std::string &name) { - Path path = currentPath_.Descend(name); - Trace::Log("TMP","creating project at %s",path.GetPath().c_str()); + Path path = currentPath_.Descend(name); + if (path.Exists()) { + Trace::Log("SelectProjectDialog:OnNewProj","path already exists %s", path.GetPath().c_str()); + std::string res("Name " + name + " busy"); + View::SetNotification(res.c_str(), 0); + return Result(res); + } + Trace::Log("TMP","creating project at %s",path.GetPath().c_str()); selection_ = path ; Result result = FileSystem::GetInstance()->MakeDir(path.GetPath().c_str()) ; RETURN_IF_FAILED(result, ("Failed to create project dir for '%s", path.GetPath().c_str())); @@ -289,7 +291,5 @@ void SelectProjectDialog::setCurrentFolder(Path &path) { //reset & redraw screen topIndex_=0 ; currentProject_=0 ; - isDirty_=true ; + isDirty_ = true; } - - From 0c999828b2c52890bdc335e72d9a9bb5a3096546 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Wed, 24 Dec 2025 22:00:03 +0100 Subject: [PATCH 2/2] Update CHANGELOG Bump build number Update docs Requires https://github.com/djdiskmachine/LittleGPTracker/pull/214 --- CHANGELOG | 3 ++- docs/wiki/What-is-LittlePiggyTracker.md | 3 ++- sources/Application/Model/Project.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9f625a3b..4e6ba592 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,11 @@ -1.6.0-bacon0 +1.6.0-bacon1 Contributions: drbscl Add 64 bit soundfont support (#211) Fixes: Add 64 bit soundfont support (#211) + Skip randomly generated project name if a directory with that name already exists (#175) 1.5.0-bacon3 Contributions: diff --git a/docs/wiki/What-is-LittlePiggyTracker.md b/docs/wiki/What-is-LittlePiggyTracker.md index 13641f55..a3adff3b 100644 --- a/docs/wiki/What-is-LittlePiggyTracker.md +++ b/docs/wiki/What-is-LittlePiggyTracker.md @@ -51,7 +51,8 @@ After that you can copy additional wavs to the lgptRoot/lgptProject/samples dire ## New project -When creating a new project, use the regen button to generate a random name. Generate a new name with Regen or edit it manually selecting characters with A and pressing up/down +When creating a new project, use the Random button to generate a random name. Generate a new name with Random or edit it manually selecting characters with A and pressing up/down +Attempting to create a project with the same name in the same location produces a notification that this operation is denied ## Multiple Projects diff --git a/sources/Application/Model/Project.h b/sources/Application/Model/Project.h index 4a5d813f..3a3c6d68 100644 --- a/sources/Application/Model/Project.h +++ b/sources/Application/Model/Project.h @@ -20,7 +20,7 @@ #define PROJECT_NUMBER "1" #define PROJECT_RELEASE "6" -#define BUILD_COUNT "0-bacon0" +#define BUILD_COUNT "0-bacon1" #define MAX_TAP 3