Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIDescription light and dark theme #231

Merged
merged 12 commits into from Sep 21, 2021
172 changes: 137 additions & 35 deletions vstgui/tests/uidescriptioneditorapp/source/app.cpp
Expand Up @@ -6,8 +6,8 @@
#include "vstgui/lib/ccolor.h"
#include "vstgui/lib/cframe.h"
#include "vstgui/lib/malloc.h"
#include "vstgui/lib/platform/iplatformframe.h"
#include "vstgui/lib/platform/common/genericoptionmenu.h"
#include "vstgui/lib/platform/iplatformframe.h"
#include "vstgui/standalone/include/helpers/appdelegate.h"
#include "vstgui/standalone/include/helpers/menubuilder.h"
#include "vstgui/standalone/include/helpers/uidesc/modelbinding.h"
Expand All @@ -17,13 +17,13 @@
#include "vstgui/standalone/include/iapplication.h"
#include "vstgui/standalone/include/icommand.h"
#include "vstgui/uidescription/cstream.h"
#include "vstgui/uidescription/detail/uijsonpersistence.h"
#include "vstgui/uidescription/detail/uixmlpersistence.h"
#include "vstgui/uidescription/editing/uieditcontroller.h"
#include "vstgui/uidescription/editing/uieditmenucontroller.h"
#include "vstgui/uidescription/editing/uiundomanager.h"
#include "vstgui/uidescription/uidescription.h"
#include "vstgui/uidescription/uicontentprovider.h"
#include "vstgui/uidescription/detail/uijsonpersistence.h"
#include "vstgui/uidescription/detail/uixmlpersistence.h"
#include "vstgui/uidescription/uidescription.h"
#include <chrono>

//------------------------------------------------------------------------
Expand All @@ -34,24 +34,41 @@ using namespace Application;

#if VSTGUI_LIVE_EDITING
//------------------------------------------------------------------------
static void makeAndOpenWindow ();
static void makeAndOpenWindow (bool darkTheme);

static const IdStringPtr RunJSONXMLBenchmark = "Run JSON/XML Benchmark";
static constexpr IdStringPtr RunJSONXMLBenchmark = "Run JSON/XML Benchmark";
static const Command BenchmarkCommand {CommandGroup::File, RunJSONXMLBenchmark};

static constexpr IdStringPtr CommandNameLightTheme = "Light Theme";
static constexpr IdStringPtr CommandNameDarkTheme = "Dark Theme";
static constexpr IdStringPtr CommandCategoryTheme = "Theme";
static const Command CommandLightTheme {CommandCategoryTheme, CommandNameLightTheme};
static const Command CommandDarkTheme {CommandCategoryTheme, CommandNameDarkTheme};

//------------------------------------------------------------------------
class Controller : public WindowControllerAdapter, public ICommandHandler
{
public:
Controller ()
Controller (bool darkTheme = false) : useDarkTheme (darkTheme)
{
descPath = __FILE__;
unixfyPath (descPath);
removeLastPathComponent (descPath);
removeLastPathComponent (descPath);
removeLastPathComponent (descPath);
removeLastPathComponent (descPath);
descPath += "/uidescription/editing/uidescriptioneditor.uidesc";
IApplication::instance ().registerCommand (Commands::SaveDocument, 's');
IApplication::instance ().registerCommand (Commands::RevertDocument, 0);
IApplication::instance ().registerCommand (CommandLightTheme, 0);
IApplication::instance ().registerCommand (CommandDarkTheme, 0);
#if VSTGUI_ENABLE_XML_PARSER
IApplication::instance ().registerCommand (BenchmarkCommand, 0);
#endif

std::string basePath = __FILE__;
unixfyPath (basePath);
removeLastPathComponent (basePath);
removeLastPathComponent (basePath);
removeLastPathComponent (basePath);
removeLastPathComponent (basePath);
basePath += "/uidescription/editing/";
descPath = basePath + "uidescriptioneditor.uidesc";
lightResPath = basePath + "uidescriptioneditor_res_light.uidesc";
darkResPath = basePath + "uidescriptioneditor_res_dark.uidesc";
}

bool init ()
Expand All @@ -64,19 +81,46 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
return false;
}
uidesc->setFilePath (descPath.data ());
lightResDesc = makeOwned<UIDescription> (lightResPath.data ());
if (!lightResDesc->parse ())
{
// TODO: show alert about error
IApplication::instance ().quit ();
return false;
}
darkResDesc = makeOwned<UIDescription> (darkResPath.data ());
if (!darkResDesc->parse ())
{
darkResDesc = nullptr;
}

if (useDarkTheme && darkResDesc)
{
uidesc->setSharedResources (darkResDesc);
}
else
{
uidesc->setSharedResources (lightResDesc);
}
editController = makeOwned<UIEditController> (uidesc);

IApplication::instance ().registerCommand (Commands::SaveDocument, 's');
IApplication::instance ().registerCommand (Commands::RevertDocument, 0);
#if VSTGUI_ENABLE_XML_PARSER
IApplication::instance ().registerCommand (BenchmarkCommand, 0);
#endif
return true;
}

bool save ()
{
return uidesc->save (descPath.data (), UIDescription::kWriteImagesIntoUIDescFile);
if (uidesc->save (descPath.data (), UIDescription::kWriteImagesIntoUIDescFile))
{
if (useDarkTheme && darkResDesc)
{
darkResDesc->save (darkResPath.data (), UIDescription::kWriteImagesIntoUIDescFile);
}
else if (lightResDesc)
{
lightResDesc->save (lightResPath.data (),
UIDescription::kWriteImagesIntoUIDescFile);
}
}
}

void beforeShow (IWindow& window) override
Expand All @@ -86,6 +130,7 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
r.setSize (window.getSize ());
auto frame = makeOwned<CFrame> (r, nullptr);
frame->enableTooltips (true);
editController->setDarkTheme (useDarkTheme);
if (auto view = editController->createEditView ())
{
editController->remember (); // view will forget it too
Expand All @@ -105,7 +150,14 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
}
}

bool canClose (const IWindow& window) override
enum class SaveChanges
{
Save,
Cancel,
DontSave,
};

SaveChanges askSaveChanges ()
{
if (win && !editController->getUndoManager ()->isSavePosition ())
{
Expand All @@ -121,15 +173,35 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
case AlertResult::DefaultButton:
{
save ();
return true;
return SaveChanges::Save;
}
case AlertResult::SecondButton: return false;
default: return true;
case AlertResult::SecondButton: return SaveChanges::Cancel;
default: break;
}
}
return SaveChanges::DontSave;
}

bool checkSaveChanges ()
{
switch (askSaveChanges ())
{
case SaveChanges::Save:
{
save ();
return true;
}
case SaveChanges::Cancel: return false;
default: return true;
}
return true;
}

bool canClose (const IWindow& window) override
{
return checkSaveChanges ();
}

void onClosed (const IWindow& window) override
{
if (IApplication::instance ().getWindows ().empty ())
Expand All @@ -146,11 +218,25 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
return editController->getUndoManager ()->canRedo ();
if (command == Commands::RevertDocument)
return !editController->getUndoManager ()->isSavePosition ();
if (command == CommandLightTheme && lightResDesc)
return uidesc->getSharedResources () != lightResDesc;
if (command == CommandDarkTheme && darkResDesc)
return uidesc->getSharedResources () != darkResDesc;
if (command == BenchmarkCommand)
return true;
return false;
}

void reopenWindow ()
{
makeAndOpenWindow (useDarkTheme);
if (auto window = win)
{
win = nullptr;
window->close ();
}
}

bool handleCommand (const Command& command) override
{
if (command == Commands::SaveDocument)
Expand All @@ -161,12 +247,24 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
return editController->getMenuController ()->handleCommand ("Edit", "Redo");
if (command == Commands::RevertDocument)
{
makeAndOpenWindow ();
if (auto window = win)
{
win = nullptr;
window->close ();
}
reopenWindow ();
return true;
}
if (command == CommandLightTheme)
{
if (!checkSaveChanges ())
return true;
useDarkTheme = false;
reopenWindow ();
return true;
}
if (command == CommandDarkTheme)
{
if (!checkSaveChanges ())
return true;
useDarkTheme = true;
reopenWindow ();
return true;
}
if (command == BenchmarkCommand)
{
Expand Down Expand Up @@ -209,7 +307,7 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
jsonData.rewind ();

InputStreamContentProvider xmlContentProvider (xmlData);

auto xmlStartTime = std::chrono::high_resolution_clock::now ();
for (auto i = 0u; i < iterations; ++i)
{
Expand Down Expand Up @@ -244,15 +342,20 @@ class Controller : public WindowControllerAdapter, public ICommandHandler
}

std::string descPath;
std::string lightResPath;
std::string darkResPath;
SharedPointer<UIDescription> uidesc;
SharedPointer<UIDescription> lightResDesc;
SharedPointer<UIDescription> darkResDesc;
SharedPointer<UIEditController> editController;
IWindow* win {nullptr};
bool useDarkTheme {false};
};

//------------------------------------------------------------------------
void makeAndOpenWindow ()
void makeAndOpenWindow (bool darkTheme)
{
auto controller = std::make_shared<Controller> ();
auto controller = std::make_shared<Controller> (darkTheme);
if (controller->init ())
{
WindowConfiguration config;
Expand Down Expand Up @@ -306,15 +409,14 @@ class UIDescriptionEditorApp : public DelegateAdapter, public MenuBuilderAdapter
void finishLaunching () override
{
#if VSTGUI_LIVE_EDITING
makeAndOpenWindow ();
makeAndOpenWindow (false);
#else
IApplication::instance ().quit ();
AlertBoxConfig config;
config.headline = "UIDescriptionEditorApp only works in Debug mode";
IApplication::instance ().showAlertBox (config);
#endif
}

};

static Init gAppDelegate (std::make_unique<UIDescriptionEditorApp> ());
Expand Down
9 changes: 9 additions & 0 deletions vstgui/uidescription/editing/createuidescdata.sh
@@ -1,8 +1,17 @@
#!/bin/bash
echo `pwd`
mkdir -p "$1"

rm -f "$1/editoruidesc.h"
echo -n "constexpr auto editorUIDesc = R\"====(" >> "$1/editoruidesc.h"
cat uidescriptioneditor.uidesc >> "$1/editoruidesc.h"
echo ")====\";" >> "$1/editoruidesc.h"

echo -n "constexpr auto editorUILightDesc = R\"====(" >> "$1/editoruidesc.h"
cat uidescriptioneditor_res_light.uidesc >> "$1/editoruidesc.h"
echo ")====\";" >> "$1/editoruidesc.h"

echo -n "constexpr auto editorUIDarkDesc = R\"====(" >> "$1/editoruidesc.h"
cat uidescriptioneditor_res_dark.uidesc >> "$1/editoruidesc.h"
echo ")====\";" >> "$1/editoruidesc.h"

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.