Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,18 +161,19 @@ target_compile_definitions(${PROJECT_NAME}
# static library. These source files can be of any kind (wav data, images, fonts, icons etc.).
# Conversion to binary-data will happen when your target is built.

# juce_add_binary_data(GuiAppData SOURCES ...)
juce_add_binary_data(client_controls
SOURCES
${CMAKE_SOURCE_DIR}/src/client/stability-controls.json
)

# `target_link_libraries` links libraries and JUCE modules to other libraries or executables. Here,
# we're linking our executable target to the `juce::juce_gui_extra` module. Inter-module
# dependencies are resolved automatically, so `juce_core`, `juce_events` and so on will also be
# linked automatically. If we'd generated a binary data target above, we would need to link to it
# here too. This is a standard CMake command.


target_link_libraries(${PROJECT_NAME}
PRIVATE
# GuiAppData # If we'd created a binary data target, we'd link to it here
juce::juce_gui_extra
juce::juce_audio_basics
juce::juce_audio_devices
Expand All @@ -185,10 +186,12 @@ target_link_libraries(${PROJECT_NAME}
juce::juce_events
juce::juce_gui_basics
juce::juce_gui_extra
client_controls
PUBLIC
juce::juce_recommended_config_flags
juce::juce_recommended_lto_flags
juce::juce_recommended_warning_flags)
juce::juce_recommended_warning_flags
)

# C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.36.32532\x64\Microsoft.VC143.CRT\msvcp140.dll
# C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.36.32532\x64\Microsoft.VC143.CRT\vcruntime140_1.dll
Expand Down
98 changes: 91 additions & 7 deletions src/Main.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include "MainComponent.h"
#include "AppSettings.h"
#include "MainComponent.h"
#include "windows/WelcomeWindow.h"

using namespace juce;

class GuiAppApplication : public JUCEApplication
class GuiAppApplication : public JUCEApplication, public FocusChangeListener
{
public:
GuiAppApplication()
Expand Down Expand Up @@ -51,6 +52,9 @@ class GuiAppApplication : public JUCEApplication
appJustLaunched = true;
originalCommandLine = commandLine;

clearLastFocusedWindow();
Desktop::getInstance().addFocusChangeListener(this);

String windowTitle = getApplicationName();

if (windowCounter > 1)
Expand All @@ -62,6 +66,33 @@ class GuiAppApplication : public JUCEApplication

mainWindow.reset(new HARPWindow(windowTitle));

bool forceShowWelcome = false;

bool showWelcome = true;

if (!forceShowWelcome)
{
if (AppSettings::containsKey("showWelcomePopup"))
showWelcome = AppSettings::getIntValue("showWelcomePopup", 1) == 1;
}

if (showWelcome)
{
MessageManager::callAsync([this]()
{
DialogWindow::LaunchOptions opts;
opts.dialogTitle = "Welcome";
opts.content.setOwned(new WelcomeWindow([this]()
{
if (auto* mainComp = dynamic_cast<MainComponent*>(mainWindow->getContentComponent()))
mainComp->showSettingsDialog();
}));
opts.content->setSize(480, 500);
opts.useNativeTitleBar = true;
opts.launchAsync();
});
}

StringArray args;

// Split command line arguments at spaces
Expand Down Expand Up @@ -154,6 +185,8 @@ class GuiAppApplication : public JUCEApplication
/// Application shutdown code
void shutdown() override
{
Desktop::getInstance().removeFocusChangeListener(this);

// Delete our window
mainWindow = nullptr;
}
Expand Down Expand Up @@ -202,6 +235,12 @@ class GuiAppApplication : public JUCEApplication

auto* app = dynamic_cast<GuiAppApplication*>(JUCEApplication::getInstance());

if (this == app->getLastFocusedWindowPtr())
{
// Clear last focused window pointer
app->clearLastFocusedWindow();
}

if (this == app->getMainWindowPtr())
{
// Check if other windows open
Expand Down Expand Up @@ -308,6 +347,7 @@ class GuiAppApplication : public JUCEApplication
};

HARPWindow* getMainWindowPtr() const { return mainWindow.get(); }
HARPWindow* getLastFocusedWindowPtr() const { return lastFocusedWindow; }

bool hasAdditionalWindows() const { return ! additionalWindows.isEmpty(); }

Expand All @@ -320,7 +360,7 @@ class GuiAppApplication : public JUCEApplication
// Remove from additional windows
additionalWindows.remove(0);

windowCounter--;
//windowCounter--; // TODO - leads to duplicate window numbers
}
}

Expand All @@ -333,7 +373,7 @@ class GuiAppApplication : public JUCEApplication
// Remove referenced window
additionalWindows.remove(i);

windowCounter--;
//windowCounter--; // TODO - leads to duplicate window numbers

break;
}
Expand Down Expand Up @@ -363,6 +403,33 @@ class GuiAppApplication : public JUCEApplication
debugFile.appendText(message + "\n", true, true);
}

void globalFocusChanged(Component* focusedComponent) override
{
if (focusedComponent == nullptr)
{
// Handle case where pointer was cleared prior to callback
return;
}

// Obtain reference to top-level component containing focused child
Component* topFocusedComponent = focusedComponent->getTopLevelComponent();

if (HARPWindow* focusedWindow = dynamic_cast<HARPWindow*>(topFocusedComponent))
{
if (lastFocusedWindow != focusedWindow)
{
// Update pointer to most recently focused HARP window
lastFocusedWindow = focusedWindow;

writeDebugLog(
"GuiAppApplication::globalFocusChanged: Last focused window updated to \""
+ focusedWindow->getName() + "\".");
}
}
}

void clearLastFocusedWindow() { lastFocusedWindow = nullptr; }

void tryOpenChoiceWindow(File inputMediaFile)
{
if (blockNewModalWindows)
Expand Down Expand Up @@ -401,7 +468,7 @@ class GuiAppApplication : public JUCEApplication
+ inputMediaFile.getFileName() + "\"?")
.withIconType(MessageBoxIconType::QuestionIcon)
.withButton("New Window")
.withButton("Existing Window")
.withButton("Current Window")
.withButton("Cancel");

/*
Expand Down Expand Up @@ -486,12 +553,27 @@ class GuiAppApplication : public JUCEApplication
}
case 1: // Current window
{
HARPWindow* windowForFileImport;

if (lastFocusedWindow != nullptr)
{
windowForFileImport = lastFocusedWindow;
}
else
{
writeDebugLog(
"GuiAppApplication::handleFileOpenChoice: No window currently focused. Importing file to main window.");

windowForFileImport = mainWindow.get();
}

if (auto* mainComp =
dynamic_cast<MainComponent*>(mainWindow->getContentComponent()))
dynamic_cast<MainComponent*>(windowForFileImport->getContentComponent()))
{
// Import file into current window
// Import file into most recently focused window
mainComp->importNewFile(inputMediaFile, true);
}

break;
}
}
Expand All @@ -500,6 +582,8 @@ class GuiAppApplication : public JUCEApplication
std::unique_ptr<HARPWindow> mainWindow;
Array<std::unique_ptr<HARPWindow>> additionalWindows;

HARPWindow* lastFocusedWindow;

ApplicationProperties applicationProperties;

int windowCounter = 0;
Expand Down
23 changes: 23 additions & 0 deletions src/MainComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,7 @@ class MainComponent : public Component,
"teamup-tech/text2midi-symbolic-music-generation",
"teamup-tech/demucs-source-separation",
"teamup-tech/solo-piano-audio-to-midi-transcription",
"teamup-tech/TRIA",
"teamup-tech/anticipatory-music-transformer",
"teamup-tech/vampnet-conditional-music-generation",
"teamup-tech/harmonic-percussive-separation",
Expand Down Expand Up @@ -1041,6 +1042,28 @@ class MainComponent : public Component,
return;
}

// Hook remote messages from Gradio/Stability clients into StatusBox
model->getClient().onRemoteMessage =
[this](RemoteMessageType type, const juce::String& msg)
{
juce::MessageManager::callAsync([this, type, msg]
{
// Forward messages into the status box UI
switch (type)
{
case RemoteMessageType::Info:
statusBox->appendRemoteMessage("info", msg);
break;
case RemoteMessageType::Warning:
statusBox->appendRemoteMessage("warning", msg);
break;
case RemoteMessageType::Error:
statusBox->appendRemoteMessage("error", msg);
break;
}
});
};

// Set setWantsKeyboardFocus to true for this component
// Doing that, everytime we click outside the modelPathTextBox,
// the focus will be taken away from the modelPathTextBox
Expand Down
9 changes: 9 additions & 0 deletions src/WebModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,15 @@ class WebModel : public Model
}

ModelStatus getStatus() { return status2; }

// forward log callback into the active client
void setLogCallback(Client::LogCallback callback)
{
if (loadedClient)
loadedClient->setLogCallback(callback);
if (tempClient)
tempClient->setLogCallback(callback);
}

void setStatus(ModelStatus status) { status2 = status; }

Expand Down
10 changes: 10 additions & 0 deletions src/client/Client.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@

using namespace juce;

enum class RemoteMessageType
{
Info,
Warning,
Error
};

class Client
{
public:
Expand All @@ -40,6 +47,9 @@ class Client
//OpResult queryToken(const String& token) const;
virtual OpResult validateToken(const String& newToken) const;

std::function<void(RemoteMessageType, const juce::String&)> onRemoteMessage =
[](RemoteMessageType, const juce::String&) {};

protected:
String getAuthorizationHeader(String t = "") const;
String getAcceptHeader() const;
Expand Down
Loading
Loading