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

Add a new UI based on Dear ImGui, allow more window settings #76

Merged
merged 44 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6832e7a
Added Dear ImGui submodule
kblaschke Apr 20, 2022
169a502
Added CMake file for Dear ImGui lib & demo application
kblaschke Apr 22, 2022
895d946
Implemented ImGui rendering class and an example window in ProjectMSD…
kblaschke Apr 22, 2022
a688254
Embed AnonymousPro font and use it for rendering the UI
kblaschke Apr 24, 2022
b3af30b
Add optional Freetype2 font rendering support
kblaschke Apr 24, 2022
254560e
Update font size on possible display/DPI change
kblaschke Apr 24, 2022
b59488a
Remove keyboard handlers for now, SDL text input interferes with Dear…
kblaschke Apr 24, 2022
29670a7
Added a simple settings window and a preset chooser dialog.
kblaschke Apr 24, 2022
7034039
Improved file chooser dialog, extracted some code into separate funct…
kblaschke Apr 24, 2022
38cbcbe
Moved GUI classes into a subdir and their own static library
kblaschke Apr 29, 2022
d3137e2
Add "Lock Preset" button
kblaschke Apr 29, 2022
4284155
Apply libprojectM API changes (ImGui)
kblaschke Jan 1, 2023
aaa9bb3
Restructure GUI classes.
kblaschke Jan 12, 2023
cb08f55
Allow adding any number of preset and texture paths in the configurat…
kblaschke Jan 26, 2023
87f6807
Add shortcuts for manual smooth transitions (via shift key)
kblaschke Jan 18, 2024
4a011f7
Install paths, config files.
kblaschke Mar 4, 2023
243b9f3
Update Dear ImGui to version 1.90.1
kblaschke Feb 1, 2024
1b46e13
Add macOS code to open default browser, move the OpenURL function int…
kblaschke Feb 1, 2024
77bb68b
Add OpenCollective sponsor link to help menu
kblaschke Feb 1, 2024
3ab6ba4
Hide mouse pointer when closing the UI.
kblaschke Mar 15, 2024
cded180
Also store Dear ImGui INI file in the app config dir
kblaschke Mar 19, 2024
ab65aeb
Remove "projectMSDL_UI.properties file
kblaschke Mar 20, 2024
52405a0
Remove FileChooser from main UI class
kblaschke Mar 20, 2024
636a6b6
Bring toast window to front once when shown
kblaschke Mar 21, 2024
f0bec56
Improve FileChooser
kblaschke Mar 20, 2024
5696e85
Clean up config management, add change events
kblaschke Mar 21, 2024
ccdb3fb
Added remaining settings.
kblaschke Mar 21, 2024
94926ad
Factored out code to make the Draw() method smaller.
kblaschke Mar 22, 2024
71b68fa
Fix brace placement in FileChooser.
kblaschke Mar 22, 2024
fce3b91
Add default window sizes
kblaschke Mar 22, 2024
c431ee5
Add about window
kblaschke Mar 22, 2024
ec2aeff
Use ### IDs for all ImGui windows.
kblaschke Mar 22, 2024
39dc6d2
Check projectM and playlist handles after creation
kblaschke Apr 7, 2024
746e34a
Remove playlist manager menu items for now.
kblaschke Apr 7, 2024
620310a
Add missing cmath include for macOS/Clang
kblaschke Apr 8, 2024
b92c85e
Add missing const qualifier
kblaschke Apr 8, 2024
48722d8
Link ApplicationServices framework on macOS
kblaschke Apr 8, 2024
cfc0e3e
Add vcpkg config/dependency files
kblaschke Apr 10, 2024
d30c3ca
Remove install dependencies step for Windows
kblaschke Apr 10, 2024
9f43570
Updated ReadMe with better build instructions
kblaschke Apr 10, 2024
6a7c002
Windows build fixes
kblaschke Apr 10, 2024
517c0c7
Fix SDL2 includes for ImGui on Windows/vcpkg
kblaschke Apr 10, 2024
cb6c2ff
Replace DPI scaling with a window/rendering size factor
kblaschke Apr 11, 2024
fc03b87
Initialize GLEW if libprojectM uses it.
kblaschke Apr 22, 2024
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
18 changes: 16 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,18 @@ jobs:
runs-on: windows-latest

steps:
- name: Install Build Dependencies
run: vcpkg --triplet=x64-windows-static install glew gtest sdl2 poco
- name: Setup MSVC dev command prompt
uses: TheMrMilchmann/setup-msvc-dev@v3
with:
arch: x64
toolset: 14.38.33130

- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');

- name: Checkout libprojectM Sources
uses: actions/checkout@v3
Expand All @@ -76,6 +86,8 @@ jobs:
submodules: recursive

- name: Build/Install libprojectM
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
run: |
mkdir cmake-build-libprojectm
cmake -G "Visual Studio 17 2022" -A "X64" -S "${{ github.workspace }}/projectm" -B "${{ github.workspace }}/cmake-build-libprojectm" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/install-libprojectm" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>" -DCMAKE_VERBOSE_MAKEFILE=YES -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=NO
Expand All @@ -89,6 +101,8 @@ jobs:
submodules: recursive

- name: Build projectMSDL
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
run: |
mkdir cmake-build-frontend-sdl2
cmake -G "Visual Studio 17 2022" -A "X64" -S "${{ github.workspace }}/frontend-sdl2" -B "${{ github.workspace }}/cmake-build-frontend-sdl2" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install-libprojectm" -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/install-frontend-sdl2" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>" -DCMAKE_VERBOSE_MAKEFILE=YES -DSDL2_LINKAGE=static -DBUILD_TESTING=YES
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "vendor/imgui"]
path = vendor/imgui
url = https://github.com/ocornut/imgui.git
61 changes: 58 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,64 @@ set(CMAKE_POSITION_INDEPENDENT_CODE YES)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

project(projectM-SDL
project(projectMSDL
LANGUAGES C CXX
VERSION 2.0.0
)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

# Default install layouts.
option(ENABLE_FLAT_PACKAGE "Creates a \"flat\" install layout with files and preset/texture dirs directly in the main dir." OFF)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT ENABLE_FLAT_PACKAGE)
include(GNUInstallDirs)

set(PROJECTMSDL_BIN_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING "Directory to install executables in, relative to the install prefix.")
set(PROJECTMSDL_LIB_DIR "${CMAKE_INSTALL_LIBDIR}" CACHE STRING "Directory to install additional libraries in, relative to the install prefix.")
set(PROJECTMSDL_DATA_DIR "${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}" CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.")
set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.")
set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.")

# Additional options for desktop integration
option(ENABLE_DESKTOP_ICON "Install a .desktop file and icons" ON)
set(PROJECTMSDL_DESKTOP_DIR "${CMAKE_INSTALL_DATAROOTDIR}/applications" CACHE STRING "Directory to install the .desktop file in, relative to the install prefix.")
set(PROJECTMSDL_ICONS_DIR "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor" CACHE STRING "Directory to install the icons in, relative to the install prefix.")

GNUInstallDirs_get_absolute_install_dir(_config_dir_abs_init PROJECTMSDL_CONFIG_DIR DATAROOTDIR)
set(DEFAULT_CONFIG_PATH "${_config_dir_abs_init}" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.")
set(DEFAULT_PRESETS_PATH "${_config_dir_abs_init}/presets" CACHE STRING "Default presets path in the configuration file.")
set(DEFAULT_TEXTURES_PATH "${_config_dir_abs_init}/textures" CACHE STRING "Default textures path in the configuration file.")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT ENABLE_FLAT_PACKAGE)
# Package as .app bundle on macOS
set(BUNDLE_BASE_DIR "projectM.app/Contents")
set(PROJECTMSDL_BIN_DIR "${BUNDLE_BASE_DIR}/MacOS" CACHE STRING "Directory to install executables in, relative to the install prefix.")
set(PROJECTMSDL_LIB_DIR "${BUNDLE_BASE_DIR}/PlugIns" CACHE STRING "Directory to install additional libraries in, relative to the install prefix.")
set(PROJECTMSDL_DATA_DIR "{BUNDLE_BASE_DIR}/Resources" CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.")
set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/Presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.")
set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/Textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.")

set(DEFAULT_CONFIG_PATH "\${application.dir}/../Resources" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.")
set(DEFAULT_PRESETS_PATH "\${application.dir}/../Resources/Presets" CACHE STRING "Default presets path in the configuration file.")
set(DEFAULT_TEXTURES_PATH "\${application.dir}/../Resources/Presets" CACHE STRING "Default textures path in the configuration file.")
else()
# Windows and others: use flat layout.
set(PROJECTMSDL_BIN_DIR "." CACHE STRING "Directory to install executables in, relative to the install prefix.")
set(PROJECTMSDL_LIB_DIR "." CACHE STRING "Directory to install additional libraries in, relative to the install prefix.")
set(PROJECTMSDL_DATA_DIR "." CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.")
set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.")
set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.")

set(DEFAULT_CONFIG_PATH "" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.")
set(DEFAULT_PRESETS_PATH "\${application.dir}/presets" CACHE STRING "Default presets path in the configuration file.")
set(DEFAULT_TEXTURES_PATH "\${application.dir}/textures" CACHE STRING "Default textures path in the configuration file.")
endif()

set(SDL2_LINKAGE "shared" CACHE STRING "Set to either shared or static to specify how libSDL2 should be linked. Defaults to shared.")
option(ENABLE_FREETYPE "Use the Freetype font rendering library instead of the built-in stb_truetype if available" ON)


set(DEFAULT_PRESETS_PATH "\${application.dir}/presets" CACHE STRING "Default presets path in the configuration file.")
set(DEFAULT_TEXTURES_PATH "\${application.dir}/textures" CACHE STRING "Default textures path in the configuration file.")
set(PRESET_DIRS "" CACHE STRING "List of paths with presets. Will be installed in \"presets\" ")
set(TEXTURE_DIRS "" CACHE STRING "List of paths with presets.")

if(NOT SDL2_LINKAGE STREQUAL "shared" AND NOT SDL2_LINKAGE STREQUAL "static")
message(FATAL_ERROR "Invalid libSDL2 linkage provided in SDL2_LINKAGE: \"${SDL2_LINKAGE}\".\n"
Expand All @@ -28,8 +75,13 @@ find_package(projectM4 REQUIRED COMPONENTS Playlist)
find_package(SDL2 REQUIRED)
find_package(Poco REQUIRED COMPONENTS JSON XML Util Foundation)

if(ENABLE_FREETYPE)
find_package(Freetype)
endif()

include(SDL2Target)
include(dependencies_check.cmake)
include(ImGui.cmake)

add_subdirectory(src)

Expand All @@ -43,3 +95,6 @@ include(packaging.cmake)
message(STATUS "SDL version: ${SDL2_VERSION}")
message(STATUS "Poco version: ${Poco_VERSION}")
message(STATUS "projectM version: ${projectM4_VERSION}")
if(Freetype_FOUND)
message(STATUS "Freetype version: ${FREETYPE_VERSION_STRING}")
endif()
62 changes: 62 additions & 0 deletions ImGui.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

add_library(ImGui STATIC
vendor/imgui/imgui.cpp
vendor/imgui/imgui.h
vendor/imgui/imgui_draw.cpp
vendor/imgui/imgui_tables.cpp
vendor/imgui/imgui_widgets.cpp
vendor/imgui/backends/imgui_impl_sdl2.cpp
vendor/imgui/backends/imgui_impl_sdl2.h
vendor/imgui/backends/imgui_impl_opengl3.cpp
vendor/imgui/backends/imgui_impl_opengl3.h
vendor/imgui/backends/imgui_impl_opengl3_loader.h
)

target_link_libraries(ImGui
PUBLIC
SDL2::SDL2$<$<STREQUAL:${SDL2_LINKAGE},static>:-static>
)

if(ENABLE_FREETYPE AND Freetype_FOUND)
target_sources(ImGui
PRIVATE
vendor/imgui/misc/freetype/imgui_freetype.cpp
vendor/imgui/misc/freetype/imgui_freetype.h
)

target_compile_definitions(ImGui
PUBLIC
IMGUI_ENABLE_FREETYPE
)

target_link_libraries(ImGui
PUBLIC
Freetype::Freetype
)
endif()

target_include_directories(ImGui
PUBLIC
${CMAKE_SOURCE_DIR}/vendor/imgui
${CMAKE_SOURCE_DIR}/vendor/imgui/backends
${SDL2_INCLUDE_DIRS}
)

# Build font embedding tool
add_executable(ImGuiBinaryToCompressedC EXCLUDE_FROM_ALL
vendor/imgui/misc/fonts/binary_to_compressed_c.cpp
)

# Add SDL2/OpenGL 3 Dear ImGui example application target for testing
add_executable(ImGuiDemo EXCLUDE_FROM_ALL
vendor/imgui/imgui_demo.cpp
vendor/imgui/examples/example_sdl2_opengl3/main.cpp
)

target_link_libraries(ImGuiDemo
PRIVATE
ImGui
SDL2::SDL2
SDL2::SDL2main
OpenGL::GL
)
140 changes: 107 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,71 +11,145 @@ present.

### Build and install libprojectM

First, [build](https://github.com/projectM-visualizer/projectm/wiki/Building-libprojectM)
and `sudo make install` [libprojectM](https://github.com/projectM-visualizer/projectm)
First, [build libprojectM](https://github.com/projectM-visualizer/projectm/wiki/Building-libprojectM) or get it via your
favorite dependency management/packaging tool. For testing, you can install libprojectM somewhere inside your
home/development directory using `CMAKE_INSTALL_PREFIX`, then pass the same install path to the frontend-sdl2 build
using `CMAKE_PREFIX_PATH`. Please refer
to [CMake's documentation](https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html) for details.

### Dependencies

(Assumes you have dependencies installed for libprojectM)
This project requires third-party libraries in addition to libprojectM's core library dependencies:

```shell
apt install libsdl2-dev libpoco-dev cmake # debian/ubuntu
brew install sdl2 # macOS
```
- SDL2 (version 2.0.16 or higher)
- POCO (recommended version 1.12 or higher, minimum is 1.9.x)
- Freetype 2 (optional, will provide better looking UI text)

**Important**: projectMSDL will _not compile_ against Poco versions from 1.10.0 up to 1.11.1, as these versions of Poco
include a serious issue that causes the application to crash. Either use Poco 1.9.x, or upgrade to 1.11.2 or higher.

### Build
Depending on your needs, you can either build them yourself or install them using your favorite package manager. Here
are some examples for the three major desktop platforms:

```shell
mkdir build
cd build
cmake ..
make
sudo apt install libsdl2-dev libpoco-dev libfreetype-dev cmake # Debian/Ubuntu Linux
brew install sdl2 poco freetype # macOS
vcpkg install sdl2 poco freetype # Windows, should be pulled in automatically via vcpkg.json
```

If all runs successfully, you should have an executable.
### Configure and build projectMSDL

#### Linux

[Note: 'make install' is unimplemented at the moment. Just copy the binary 'projectMSDL' to your choice of run-path. E.g.]
After cloning or updating the Git repository, always remember to update or initialize the submodules as well. this is
not required when building from a release tarball or ZIP.

```shell
cp src/projectMSDL ~/bin
git submodule --init update
```

Create a configuration file or projectMSDL will complain, a lot.
If all dependencies are in the CMake and/or the system search directories, you can configure and build the application
with these commands, executed from the source dir:

```shell
mkdir ~/.config/projectM
cp src/projectMSDL.properties ~/.config/projectM
mkdir cmake-build
cmake -S . -B cmake-build -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build --config Release
```

The default audio device (-1) may or may not be your actual default audio output. `projectMSDL -l` will list audio
devices; hopefully, one of them looks familiar - like "Monitor of ... digital stereo" or "Monitor of USB Audio
Device ..." (if you have one of those).
You can optionally add the `--parallel` argument with the number of CPU cores to use to the build command to speed up
the build.

If your dependencies are in different locations than the default search paths, or you're cross-compiling, you'll need to
add more options like `CMAKE_PREFIX_PATH`. Covering all CMake options is out of the scope of this document. Please read
the [Mastering CMake guide](https://cmake.org/cmake/help/book/mastering-cmake/index.html) and
the [CMake documentation](https://cmake.org/cmake/help/latest/) for more information.

### Run
The above command will use CMake's default build file generator for your current platform and build the project in
Release (optimized) configuration. If the build was successful, you should have an executable in the build directory. On
Windows, you may need to specify the correct Visual Studio generator and architecture manually.

### Install projectMSDL

While you can run projectMSDL directly from the build directory, it's recommended to install the project. This will copy
all required files, including a default configuration file, into the installation dir.

You can set the installation target path in the first CMake command which configures the build. The `install` target
will then copy everything under this directory:

```shell
mkdir cmake-build
cmake -S . -B cmake-build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/path/to/install/dir
cmake --build cmake-build --config Release --target install
```

### Run directly from the build dir

You should have a directory of visual presets you wish to use. You can fetch a giant trove of curated
presets [here](https://github.com/projectM-visualizer/presets-cream-of-the-crop).
presets [here](https://github.com/projectM-visualizer/presets-cream-of-the-crop). You will also need textures (images)
used in many presets. The projectM team has
assembled [a pack of textures](https://github.com/projectM-visualizer/presets-milkdrop-texture-pack), which covers the
needs of most presets.

If you want to run the executable from the build dir, you'll need to pass any non-default settings via arguments. You
can also create a user configuration file in your user's home directory. Depending on the platform, this will be:

- Windows: `%APPDATA%\projectM\projectMSDL.properties`
- Linux:
- If `XDG_CONFIG_HOME` env var is non-empty: `$XDG_CONFIG_HOME/projectM/projectMSDL.properties`
- Otherwise: `~/.config/projectM/projectMSDL.properties`
- macOS: `~/Library/Preferences/projectM/projectMSDL.properties`

You can copy the [config file template](src/resources/projectMSDL.properties.in) there and change anything in `@@`.

Depending on the build system, you'll find the projectM executable in `cmake-build/src/`, or a subdirectory with the
name of your build type (`Release`, `Debug` and so on).

Provide the presets path you wish to use when starting projectMSDL:
If you're not using a config file, provide the presets and texture paths you wish to use when starting projectMSDL:

```shell
src/projectMSDL --presetPath /path/to/presets-cream-of-the-crop
cmake-build/src/projectMSDL --presetPath /path/to/presets-cream-of-the-crop --texturePath /path/to/textures
```

Press F1 for help menu.
Press ESC to toggle the UI.

## Developing
## System-Specific CMake Examples

The following examples show how to configure and build projectMSDL with CMake on the different supported platforms.

### Windows

To generate a Visual Studio 2022 project for Win64 and build for Release, with then option to also compile a Debug build
from within the generated solution:

```shell
mkdir cmake-build
cmake -G "Visual Studio 17 2022" -A x64 -S . -B cmake-build -DCMAKE_CONFIGURATION_TYPES=Debug,Release
cmake --build cmake-build --config Release
```

### Linux

To generate a UNIX Makefile project build for Release:

```shell
mkdir cmake-build
cmake -G "Unix Makefile" -S . -B cmake-build -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build
```

To generate a Ninja project build for Release:

```shell
mkdir cmake-build
cmake -G "Ninja" -S . -B cmake-build -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build
```

This project uses cmake, which can generate project files for your favorite IDE.
### macOS

To generate an Xcode project:
To generate an Xcode project and build for Release:

```shell
make clean
cmake -G Xcode -S . -B build
mkdir cmake-build
cmake -G Xcode -S . -B cmake-build -DCMAKE_CONFIGURATION_TYPES=Debug,Release
cmake --build cmake-build --config Release
```
Loading
Loading