Merge pull request #404 from jpcima/editor-cleanup
User interface update
|
|
@ -1,5 +1,5 @@
|
||||||
version: build-{build}
|
version: build-{build}
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2019
|
||||||
configuration: Release
|
configuration: Release
|
||||||
platform:
|
platform:
|
||||||
- Win32
|
- Win32
|
||||||
|
|
@ -22,7 +22,7 @@ before_build:
|
||||||
- cmd: git submodule update --init
|
- cmd: git submodule update --init
|
||||||
- cmd: mkdir CMakeBuild
|
- cmd: mkdir CMakeBuild
|
||||||
- cmd: cd CMakeBuild
|
- cmd: cd CMakeBuild
|
||||||
- cmd: cmake .. -G"Visual Studio 15 2017" -A"%platform%" -DSFIZZ_JACK=OFF -DSFIZZ_BENCHMARKS=OFF -DSFIZZ_TESTS=OFF -DSFIZZ_LV2=ON -DSFIZZ_VST=ON -DCMAKE_BUILD_TYPE=Release -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake
|
- cmd: cmake .. -G"Visual Studio 16 2019" -A"%platform%" -DSFIZZ_JACK=OFF -DSFIZZ_BENCHMARKS=OFF -DSFIZZ_TESTS=OFF -DSFIZZ_LV2=ON -DSFIZZ_VST=ON -DCMAKE_BUILD_TYPE=Release -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cmd: cmake --build . --config Release -j
|
- cmd: cmake --build . --config Release -j
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,28 @@ include("cmake/Vstgui.cmake")
|
||||||
|
|
||||||
set(EDITOR_RESOURCES
|
set(EDITOR_RESOURCES
|
||||||
logo.png
|
logo.png
|
||||||
|
logo_text.png
|
||||||
|
logo_text_white.png
|
||||||
|
logo_text@2x.png
|
||||||
|
logo_text_white@2x.png
|
||||||
|
background.png
|
||||||
|
background@2x.png
|
||||||
|
icon_white.png
|
||||||
|
icon_white@2x.png
|
||||||
|
knob48.png
|
||||||
|
knob48@2x.png
|
||||||
|
Fonts/fluentui-system-regular-20.ttf
|
||||||
|
Fonts/Roboto-Regular.ttf
|
||||||
PARENT_SCOPE)
|
PARENT_SCOPE)
|
||||||
|
|
||||||
|
function(copy_editor_resources SOURCE_DIR DESTINATION_DIR)
|
||||||
|
foreach(res ${EDITOR_RESOURCES})
|
||||||
|
get_filename_component(_dir "${res}" DIRECTORY)
|
||||||
|
file(MAKE_DIRECTORY "${DESTINATION_DIR}/${_dir}")
|
||||||
|
file(COPY "${SOURCE_DIR}/${res}" DESTINATION "${DESTINATION_DIR}/${_dir}")
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# editor
|
# editor
|
||||||
add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
||||||
src/editor/EditIds.h
|
src/editor/EditIds.h
|
||||||
|
|
@ -14,8 +34,53 @@ add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
||||||
src/editor/EditorController.h
|
src/editor/EditorController.h
|
||||||
src/editor/GUIComponents.h
|
src/editor/GUIComponents.h
|
||||||
src/editor/GUIComponents.cpp
|
src/editor/GUIComponents.cpp
|
||||||
|
src/editor/NativeHelpers.h
|
||||||
|
src/editor/NativeHelpers.cpp
|
||||||
|
src/editor/layout/main.hpp
|
||||||
src/editor/utility/vstgui_after.h
|
src/editor/utility/vstgui_after.h
|
||||||
src/editor/utility/vstgui_before.h)
|
src/editor/utility/vstgui_before.h)
|
||||||
target_include_directories(sfizz_editor PUBLIC "src")
|
target_include_directories(sfizz_editor PUBLIC "src")
|
||||||
target_link_libraries(sfizz_editor PRIVATE sfizz-vstgui)
|
target_link_libraries(sfizz_editor PRIVATE sfizz-vstgui)
|
||||||
target_link_libraries(sfizz_editor PUBLIC absl::strings)
|
target_link_libraries(sfizz_editor PUBLIC absl::strings)
|
||||||
|
if(APPLE)
|
||||||
|
find_library(APPLE_APPKIT_LIBRARY "AppKit")
|
||||||
|
find_library(APPLE_CORESERVICES_LIBRARY "CoreServices")
|
||||||
|
find_library(APPLE_FOUNDATION_LIBRARY "Foundation")
|
||||||
|
target_sources(sfizz_editor PRIVATE
|
||||||
|
src/editor/NativeHelpers.mm)
|
||||||
|
target_link_libraries(sfizz_editor PRIVATE
|
||||||
|
"${APPLE_APPKIT_LIBRARY}"
|
||||||
|
"${APPLE_CORESERVICES_LIBRARY}"
|
||||||
|
"${APPLE_FOUNDATION_LIBRARY}")
|
||||||
|
target_compile_options(sfizz_editor PRIVATE "-fobjc-arc")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
if(WIN32)
|
||||||
|
#
|
||||||
|
elseif(APPLE)
|
||||||
|
#
|
||||||
|
else()
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(sfizz-gio "gio-2.0" REQUIRED)
|
||||||
|
target_include_directories(sfizz_editor PRIVATE ${sfizz-gio_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(sfizz_editor PRIVATE ${sfizz-gio_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
target_include_directories(sfizz_editor PRIVATE "../src/external") # ghc::filesystem
|
||||||
|
|
||||||
|
# layout tool
|
||||||
|
if(NOT CMAKE_CROSSCOMPILING)
|
||||||
|
add_executable(layout-maker
|
||||||
|
"tools/layout-maker/sources/layout.h"
|
||||||
|
"tools/layout-maker/sources/reader.cpp"
|
||||||
|
"tools/layout-maker/sources/reader.h"
|
||||||
|
"tools/layout-maker/sources/main.cpp")
|
||||||
|
target_link_libraries(layout-maker PRIVATE absl::strings)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/editor/layout/main.hpp"
|
||||||
|
COMMAND "$<TARGET_FILE:layout-maker>"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/layout/main.fl"
|
||||||
|
> "${CMAKE_CURRENT_SOURCE_DIR}/src/editor/layout/main.hpp"
|
||||||
|
DEPENDS layout-maker "${CMAKE_CURRENT_SOURCE_DIR}/layout/main.fl")
|
||||||
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,8 @@ endif()
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
# higher C++ requirement on Windows
|
# higher C++ requirement on Windows
|
||||||
set_property(TARGET sfizz-vstgui PROPERTY CXX_STANDARD 14)
|
set_property(TARGET sfizz-vstgui PROPERTY CXX_STANDARD 14)
|
||||||
|
# Windows 10 RS2 DDI for custom fonts
|
||||||
|
target_compile_definitions(sfizz-vstgui PRIVATE "NTDDI_VERSION=0x0A000003")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
|
|
|
||||||
2
editor/external/vstgui4
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7316f9fb2891b9f0e2a408cfbf4ec35aeec268bd
|
Subproject commit 104172476111a255a87d9853a4b6502071130b9d
|
||||||
316
editor/layout/main.fl
Normal file
|
|
@ -0,0 +1,316 @@
|
||||||
|
# data file for the Fltk User Interface Designer (fluid)
|
||||||
|
version 1.0305
|
||||||
|
header_name {.h}
|
||||||
|
code_name {.cxx}
|
||||||
|
widget_class mainView {open
|
||||||
|
xywh {572 266 800 475} type Double
|
||||||
|
class LogicalGroup visible
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
image {../resources/background.png} xywh {190 110 600 280}
|
||||||
|
class Background
|
||||||
|
}
|
||||||
|
Fl_Group {} {
|
||||||
|
comment {theme=darkTheme}
|
||||||
|
xywh {0 0 800 110}
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {5 4 175 101} box ROUNDED_BOX align 0
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelGeneral}
|
||||||
|
image {../resources/logo_text_white.png} xywh {35 9 120 60}
|
||||||
|
class SfizzMainButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelGeneral}
|
||||||
|
xywh {49 73 25 25} labelsize 24
|
||||||
|
class HomeButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelControls}
|
||||||
|
xywh {81 73 25 25} labelsize 24
|
||||||
|
class CCButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelSettings}
|
||||||
|
xywh {112 73 25 25} labelsize 24
|
||||||
|
class SettingsButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {} {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
|
||||||
|
class HLine
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Separator 2}
|
||||||
|
xywh {195 73 360 5} box BORDER_BOX labeltype NO_LABEL
|
||||||
|
class HLine
|
||||||
|
}
|
||||||
|
Fl_Box sfzFileLabel_ {
|
||||||
|
label {DefaultInstrument.sfz}
|
||||||
|
xywh {265 12 230 30} labelsize 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Key switch}
|
||||||
|
xywh {265 44 230 30} labelsize 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Voices:}
|
||||||
|
xywh {195 76 60 25} labelsize 12 align 24
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagLoadSfzFile}
|
||||||
|
xywh {500 14 25 25} labelsize 24
|
||||||
|
class LoadFileButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagEditSfzFile}
|
||||||
|
xywh {525 14 25 25} labelsize 24
|
||||||
|
class EditFileButton
|
||||||
|
}
|
||||||
|
Fl_Box infoVoicesLabel_ {
|
||||||
|
xywh {260 76 50 25} labelsize 12 align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Max:}
|
||||||
|
xywh {315 76 60 25} labelsize 12 align 24
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box numVoicesLabel_ {
|
||||||
|
xywh {380 76 50 25} labelsize 12 align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Memory:}
|
||||||
|
xywh {435 76 60 25} labelsize 12 align 24
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box memoryLabel_ {
|
||||||
|
xywh {500 76 50 25} labelsize 12 align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {570 5 225 100} box ROUNDED_BOX
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Dial {} {
|
||||||
|
xywh {615 20 48 48} value 0.5 hide
|
||||||
|
class Knob48
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Center
|
||||||
|
xywh {610 70 60 5} labelsize 12 hide
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Dial volumeSlider_ {
|
||||||
|
comment {tag=kTagSetVolume}
|
||||||
|
xywh {680 20 48 48} value 0.5
|
||||||
|
class Knob48
|
||||||
|
}
|
||||||
|
Fl_Box volumeLabel_ {
|
||||||
|
label {0.0 dB}
|
||||||
|
xywh {675 70 60 22} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
xywh {745 20 35 55} box BORDER_BOX
|
||||||
|
class VMeter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {subPanels_[kPanelGeneral]} {
|
||||||
|
xywh {5 110 791 285} hide
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {5 110 175 280} box ROUNDED_BOX
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Curves:}
|
||||||
|
xywh {20 120 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Masters:}
|
||||||
|
xywh {20 145 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Groups:}
|
||||||
|
xywh {20 170 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Regions:}
|
||||||
|
xywh {20 195 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Samples:}
|
||||||
|
xywh {20 220 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoCurvesLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 120 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoMastersLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 145 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoGroupsLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 170 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoRegionsLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 195 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoSamplesLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 220 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {subPanels_[kPanelControls]} {
|
||||||
|
xywh {5 110 790 285} hide
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {5 110 790 285} box ROUNDED_BOX
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Controls not available}
|
||||||
|
xywh {5 110 790 285} labelsize 40
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {subPanels_[kPanelSettings]} {open
|
||||||
|
xywh {5 109 790 286}
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {
|
||||||
|
label Engine open selected
|
||||||
|
xywh {260 135 280 100} box ROUNDED_BOX labelsize 12 align 17
|
||||||
|
class TitleGroup
|
||||||
|
} {
|
||||||
|
Fl_Spinner numVoicesSlider_ {
|
||||||
|
comment {tag=kTagSetNumVoices}
|
||||||
|
xywh {285 195 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Polyphony
|
||||||
|
xywh {275 155 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Spinner oversamplingSlider_ {
|
||||||
|
comment {tag=kTagSetOversampling}
|
||||||
|
xywh {370 195 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Oversampling
|
||||||
|
xywh {360 155 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Preload size}
|
||||||
|
xywh {445 155 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Spinner preloadSizeSlider_ {
|
||||||
|
comment {tag=kTagSetPreloadSize}
|
||||||
|
xywh {455 195 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {} {
|
||||||
|
label Tuning open
|
||||||
|
xywh {205 270 390 100} box ROUNDED_BOX labelsize 12 align 17
|
||||||
|
class TitleGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Root key}
|
||||||
|
xywh {330 290 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Spinner tuningFrequencySlider_ {
|
||||||
|
comment {tag=kTagSetTuningFrequency}
|
||||||
|
xywh {425 330 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Frequency
|
||||||
|
xywh {415 290 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Dial stretchedTuningSlider_ {
|
||||||
|
comment {tag=kTagSetStretchedTuning}
|
||||||
|
xywh {515 315 48 48} value 0.5
|
||||||
|
class Knob48
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Stretch
|
||||||
|
xywh {500 290 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Scala file}
|
||||||
|
xywh {225 290 100 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Button scalaFileButton_ {
|
||||||
|
label DefaultScale
|
||||||
|
comment {tag=kTagLoadScalaFile}
|
||||||
|
xywh {225 330 100 25} labelsize 12
|
||||||
|
class ValueButton
|
||||||
|
}
|
||||||
|
Fl_Spinner scalaRootKeySlider_ {
|
||||||
|
comment {tag=kTagSetScalaRootKey}
|
||||||
|
xywh {340 330 35 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Spinner scalaRootOctaveSlider_ {
|
||||||
|
comment {tag=kTagSetScalaRootKey}
|
||||||
|
xywh {375 330 30 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
xywh {5 400 790 70}
|
||||||
|
class Piano
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
editor/resources/Fonts/Roboto-Regular.ttf
Normal file
BIN
editor/resources/Fonts/fluentui-system-regular-20.ttf
Normal file
BIN
editor/resources/background.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
editor/resources/background@2x.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
editor/resources/icon_white.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
253
editor/resources/icon_white.svg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
editor/resources/icon_white@2x.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
editor/resources/knob.knob
Normal file
BIN
editor/resources/knob48.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
editor/resources/knob48@2x.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
editor/resources/logo_text.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
252
editor/resources/logo_text.svg
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="192"
|
||||||
|
inkscape:export-xdpi="192"
|
||||||
|
inkscape:export-filename="/home/jpc/documents/projects/sfizz/editor/resources/logo_text@2x.png"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
sodipodi:docname="logo_text.svg"
|
||||||
|
id="svg8"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 105.83333 66.145836"
|
||||||
|
height="250"
|
||||||
|
width="400">
|
||||||
|
<title
|
||||||
|
id="title1469">sfizz logo</title>
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient1445"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop1441"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#646464;stop-opacity:1" />
|
||||||
|
<stop
|
||||||
|
id="stop1443"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect1150"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
unit="mm"
|
||||||
|
method="auto"
|
||||||
|
mode="C"
|
||||||
|
radius="1"
|
||||||
|
chamfer_steps="2"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
hide_knots="false"
|
||||||
|
only_selected="false"
|
||||||
|
apply_with_radius="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
use_knot_distance="true"
|
||||||
|
flexible="false"
|
||||||
|
chamfer_steps="2"
|
||||||
|
radius="1"
|
||||||
|
mode="C"
|
||||||
|
method="auto"
|
||||||
|
unit="mm"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect1136"
|
||||||
|
effect="fillet_chamfer" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
hide_knots="false"
|
||||||
|
only_selected="false"
|
||||||
|
apply_with_radius="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
use_knot_distance="true"
|
||||||
|
flexible="false"
|
||||||
|
chamfer_steps="2"
|
||||||
|
radius="1"
|
||||||
|
mode="C"
|
||||||
|
method="auto"
|
||||||
|
unit="mm"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect968"
|
||||||
|
effect="fillet_chamfer" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect921"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
unit="mm"
|
||||||
|
method="auto"
|
||||||
|
mode="C"
|
||||||
|
radius="1"
|
||||||
|
chamfer_steps="2"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
hide_knots="false"
|
||||||
|
only_selected="false"
|
||||||
|
apply_with_radius="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
use_knot_distance="true"
|
||||||
|
flexible="false"
|
||||||
|
chamfer_steps="2"
|
||||||
|
radius="1"
|
||||||
|
mode="C"
|
||||||
|
method="auto"
|
||||||
|
unit="mm"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect1183"
|
||||||
|
effect="fillet_chamfer" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
end_linecap_type="zerowidth"
|
||||||
|
scale_width="1"
|
||||||
|
miter_limit="4"
|
||||||
|
linejoin_type="round"
|
||||||
|
start_linecap_type="zerowidth"
|
||||||
|
interpolator_beta="0.2"
|
||||||
|
interpolator_type="CubicBezierFit"
|
||||||
|
sort_points="true"
|
||||||
|
offset_points="0.19099662,0.36320029 | 0.41721681,0.40988822 | 0.9095762,0.070646707"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect1172"
|
||||||
|
effect="powerstroke" />
|
||||||
|
<clipPath
|
||||||
|
id="clipPath917"
|
||||||
|
clipPathUnits="userSpaceOnUse">
|
||||||
|
<rect
|
||||||
|
y="68.872978"
|
||||||
|
x="24.792475"
|
||||||
|
height="25.252825"
|
||||||
|
width="39.659527"
|
||||||
|
id="rect919"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:2;stroke-linecap:round;paint-order:markers stroke fill" />
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y2="231.60674"
|
||||||
|
x2="539.22601"
|
||||||
|
y1="190.42654"
|
||||||
|
x1="539.22601"
|
||||||
|
id="linearGradient1447"
|
||||||
|
xlink:href="#linearGradient1445"
|
||||||
|
inkscape:collect="always"
|
||||||
|
gradientTransform="translate(34.589224,10.333824)" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
fit-margin-bottom="10"
|
||||||
|
fit-margin-right="10"
|
||||||
|
fit-margin-left="10"
|
||||||
|
fit-margin-top="10"
|
||||||
|
inkscape:snap-bbox-midpoints="true"
|
||||||
|
inkscape:snap-center="true"
|
||||||
|
inkscape:snap-bbox-edge-midpoints="true"
|
||||||
|
inkscape:bbox-paths="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1008"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
showguides="false"
|
||||||
|
inkscape:snap-global="false"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="53.822531"
|
||||||
|
inkscape:cx="17.632385"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base"
|
||||||
|
units="px">
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide899"
|
||||||
|
orientation="1,0"
|
||||||
|
position="-452.4563,176.31198" />
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide901"
|
||||||
|
orientation="0,-1"
|
||||||
|
position="-351.71366,154.32488" />
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide1008"
|
||||||
|
orientation="1,0"
|
||||||
|
position="-536.98274,156.82863" />
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide1185"
|
||||||
|
orientation="1,0"
|
||||||
|
position="-351.75629,154.33106" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title>sfizz logo</dc:title>
|
||||||
|
<dc:date>2020-05-16</dc:date>
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Tobiasz 'unfa' Karoń</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:rights>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>CC-0</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:rights>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-495.92008,-191.91875)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
|
<path
|
||||||
|
id="path1439"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:34.8154px;line-height:1.25;font-family:ABeeZee;-inkscape-font-specification:ABeeZee;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient1447);fill-opacity:1;stroke:none;stroke-width:0.264584"
|
||||||
|
d="m 569.95053,215.93967 h 13.61282 v 2.40226 l -9.9572,12.91651 h 10.13128 v 2.78523 h -13.99579 v -2.47189 l 9.99202,-12.91651 h -9.78313 z m -16.4328,0 h 13.61282 v 2.40226 l -9.9572,12.91651 h 10.13128 v 2.78523 h -13.99579 v -2.47189 l 9.99202,-12.91651 h -9.78313 z m -6.38378,18.104 h -3.13338 l 3.1682,-18.104 h 3.13339 z m 2.33264,-21.20257 c -0.64989,0 -1.14891,-0.18568 -1.49707,-0.55705 -0.32494,-0.39457 -0.48741,-0.84717 -0.48741,-1.3578 0,-0.74273 0.2321,-1.33459 0.69631,-1.77559 0.4642,-0.46421 1.04446,-0.69631 1.74077,-0.69631 0.64989,0 1.1373,0.19729 1.46224,0.59187 0.34815,0.37136 0.52223,0.81235 0.52223,1.32298 0,0.74273 -0.2321,1.34619 -0.6963,1.8104 -0.46421,0.441 -1.04446,0.6615 -1.74077,0.6615 z m -12.24537,3.76006 h 5.36157 l -0.48741,2.7156 h -5.36157 l -3.06376,17.23362 c -0.18568,1.02125 -0.4526,1.88003 -0.80075,2.57634 -0.34815,0.71952 -0.76594,1.29978 -1.25336,1.74077 -0.48741,0.44099 -1.04446,0.75433 -1.67114,0.94002 -0.62667,0.20889 -1.29977,0.31334 -2.01929,0.31334 -0.76594,0 -1.46225,-0.10445 -2.08892,-0.31334 -0.64989,-0.20889 -1.21854,-0.49902 -1.70596,-0.87039 l 1.25336,-2.57634 c 0.32494,0.32495 0.70791,0.58026 1.1489,0.76594 0.41779,0.18568 0.8936,0.27852 1.42744,0.27852 0.62667,0 1.16051,-0.2205 1.6015,-0.66149 0.46421,-0.44099 0.78915,-1.14891 0.97484,-2.12374 l 3.06375,-17.30325 h -2.78523 l 0.48741,-2.7156 h 2.78524 l 0.52223,-2.78523 c 0.39457,-2.13535 1.14891,-3.65562 2.263,-4.56082 1.11409,-0.92841 2.54152,-1.39262 4.28229,-1.39262 0.95162,0 1.83361,0.12766 2.64597,0.38297 0.81236,0.23211 1.54348,0.52224 2.19337,0.87039 l -1.21854,2.64597 c -0.53383,-0.27853 -1.09088,-0.53384 -1.67114,-0.76594 -0.55704,-0.23211 -1.21853,-0.34816 -1.98447,-0.34816 -0.85878,0 -1.5899,0.25531 -2.19337,0.76594 -0.60347,0.48742 -0.99804,1.25336 -1.18373,2.29782 z m -21.96217,13.36911 c 0.60347,0.53384 1.3578,0.96323 2.263,1.28817 0.92841,0.32495 1.91485,0.48742 2.95931,0.48742 1.29977,0 2.2746,-0.20889 2.92449,-0.62668 0.6731,-0.44099 1.00965,-0.99804 1.00965,-1.67114 0,-0.34815 -0.0696,-0.6731 -0.20889,-0.97483 -0.11605,-0.30173 -0.34816,-0.59186 -0.69631,-0.87039 -0.32495,-0.27852 -0.77755,-0.54544 -1.3578,-0.80075 -0.58026,-0.27852 -1.33459,-0.58025 -2.263,-0.9052 -1.71756,-0.58026 -2.99413,-1.26496 -3.8297,-2.05411 -0.83557,-0.81236 -1.25335,-1.92645 -1.25335,-3.34228 0,-0.69631 0.15087,-1.34619 0.4526,-1.94966 0.32495,-0.60347 0.77755,-1.1257 1.3578,-1.56669 0.60347,-0.46421 1.32299,-0.82397 2.15856,-1.07928 0.85878,-0.25531 1.83361,-0.38297 2.92449,-0.38297 1.18372,0 2.21658,0.12766 3.09857,0.38297 0.9052,0.2321 1.71756,0.53383 2.43708,0.9052 l -0.87039,2.57634 c -0.62667,-0.37137 -1.34619,-0.6731 -2.15855,-0.9052 -0.78915,-0.2321 -1.67114,-0.34815 -2.64597,-0.34815 -1.20693,0 -2.12374,0.24371 -2.75042,0.73112 -0.62668,0.48741 -0.94002,1.02125 -0.94002,1.60151 0,0.27852 0.0464,0.53383 0.13927,0.76594 0.11605,0.2321 0.31333,0.4526 0.59186,0.66149 0.27852,0.20889 0.64988,0.41779 1.11409,0.62668 0.46421,0.20889 1.04446,0.42938 1.74077,0.66149 1.13731,0.39457 2.10053,0.80075 2.88968,1.21854 0.78915,0.39457 1.42743,0.83557 1.91485,1.32298 0.48741,0.48742 0.83557,1.02126 1.04446,1.60151 0.20889,0.55705 0.31334,1.18372 0.31334,1.88003 0,0.81236 -0.17408,1.54348 -0.52223,2.19337 -0.34816,0.64989 -0.83558,1.20693 -1.46225,1.67114 -0.62668,0.44099 -1.39262,0.77754 -2.29782,1.00965 -0.88199,0.25531 -1.86842,0.38297 -2.95931,0.38297 -1.39261,0 -2.63436,-0.17408 -3.72524,-0.52223 -1.09089,-0.34815 -1.99609,-0.80075 -2.71561,-1.3578 z"
|
||||||
|
sodipodi:nodetypes="cccccccccccccccccccccccccccscscscscsccccccscsccccsccccccccsccccscccccscscccccscccsccccssscssccccssccsscc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 12 KiB |
BIN
editor/resources/logo_text@2x.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
editor/resources/logo_text_white.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
editor/resources/logo_text_white@2x.png
Normal file
|
After Width: | Height: | Size: 4 KiB |
|
|
@ -5,34 +5,456 @@
|
||||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
#include "GUIComponents.h"
|
#include "GUIComponents.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "utility/vstgui_before.h"
|
#include "utility/vstgui_before.h"
|
||||||
#include "vstgui/lib/cdrawcontext.h"
|
#include "vstgui/lib/cdrawcontext.h"
|
||||||
|
#include "vstgui/lib/cgraphicspath.h"
|
||||||
|
#include "vstgui/lib/cframe.h"
|
||||||
#include "utility/vstgui_after.h"
|
#include "utility/vstgui_after.h"
|
||||||
|
|
||||||
SimpleSlider::SimpleSlider(const CRect& bounds, IControlListener* listener, int32_t tag)
|
///
|
||||||
: CSliderBase(bounds, listener, tag)
|
SBoxContainer::SBoxContainer(const CRect& size)
|
||||||
|
: CViewContainer(size)
|
||||||
{
|
{
|
||||||
setStyle(kHorizontal|kLeft);
|
CViewContainer::setBackgroundColor(CColor(0, 0, 0, 0));
|
||||||
|
|
||||||
CPoint offsetHandle(2.0, 2.0);
|
|
||||||
setOffsetHandle(offsetHandle);
|
|
||||||
|
|
||||||
CCoord handleSize = 20.0;
|
|
||||||
setHandleSizePrivate(handleSize, bounds.bottom - bounds.top - 2 * offsetHandle.y);
|
|
||||||
setHandleRangePrivate(bounds.right - bounds.left - handleSize - 2 * offsetHandle.x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleSlider::draw(CDrawContext* dc)
|
void SBoxContainer::setCornerRadius(CCoord radius)
|
||||||
|
{
|
||||||
|
cornerRadius_ = radius;
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBoxContainer::setBackgroundColor(const CColor& color)
|
||||||
|
{
|
||||||
|
backgroundColor_ = color;
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
CColor SBoxContainer::getBackgroundColor() const
|
||||||
|
{
|
||||||
|
return backgroundColor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBoxContainer::drawRect(CDrawContext* dc, const CRect& updateRect)
|
||||||
{
|
{
|
||||||
CRect bounds = getViewSize();
|
CRect bounds = getViewSize();
|
||||||
CRect handle = calculateHandleRect(getValueNormalized());
|
|
||||||
|
|
||||||
dc->setDrawMode(kAntiAliasing);
|
dc->setDrawMode(kAntiAliasing);
|
||||||
|
|
||||||
dc->setFrameColor(_frame);
|
SharedPointer<CGraphicsPath> path = owned(dc->createGraphicsPath());
|
||||||
dc->drawRect(bounds, kDrawStroked);
|
path->addRoundRect(bounds, cornerRadius_);
|
||||||
|
|
||||||
dc->setFillColor(_fill);
|
dc->setFillColor(backgroundColor_);
|
||||||
dc->drawRect(handle, kDrawFilled);
|
dc->drawGraphicsPath(path.get(), CDrawContext::kPathFilled);
|
||||||
|
|
||||||
|
CViewContainer::drawRect(dc, updateRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
STitleContainer::STitleContainer(const CRect& size, UTF8StringPtr text)
|
||||||
|
: SBoxContainer(size), text_(text ? text : ""), titleFont_(kNormalFont)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::setTitleFont(CFontRef font)
|
||||||
|
{
|
||||||
|
titleFont_ = font;
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::setTitleFontColor(CColor color)
|
||||||
|
{
|
||||||
|
titleFontColor_ = color;
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::setTitleBackgroundColor(CColor color)
|
||||||
|
{
|
||||||
|
titleBackgroundColor_ = color;
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::drawRect(CDrawContext* dc, const CRect& updateRect)
|
||||||
|
{
|
||||||
|
SBoxContainer::drawRect(dc, updateRect);
|
||||||
|
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
CCoord cornerRadius = cornerRadius_;
|
||||||
|
|
||||||
|
dc->setDrawMode(kAntiAliasing);
|
||||||
|
|
||||||
|
CCoord fontHeight = titleFont_->getSize();
|
||||||
|
CCoord titleHeight = fontHeight + 8.0;
|
||||||
|
|
||||||
|
CRect titleBounds = bounds;
|
||||||
|
titleBounds.bottom = titleBounds.top + titleHeight;
|
||||||
|
|
||||||
|
SharedPointer<CGraphicsPath> path = owned(dc->createGraphicsPath());
|
||||||
|
path->beginSubpath(titleBounds.getBottomRight());
|
||||||
|
path->addLine(titleBounds.getBottomLeft());
|
||||||
|
path->addArc(CRect(titleBounds.left, titleBounds.top, titleBounds.left + 2.0 * cornerRadius, titleBounds.top + 2.0 * cornerRadius), 180., 270., true);
|
||||||
|
path->addArc(CRect(titleBounds.right - 2.0 * cornerRadius, titleBounds.top, titleBounds.right, titleBounds.top + 2.0 * cornerRadius), 270., 360., true);
|
||||||
|
path->closeSubpath();
|
||||||
|
|
||||||
|
dc->setFillColor(titleBackgroundColor_);
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathFilled);
|
||||||
|
|
||||||
|
dc->setFont(titleFont_);
|
||||||
|
dc->setFontColor(titleFontColor_);
|
||||||
|
dc->drawString(text_.c_str(), titleBounds, kCenterText);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void SFileDropTarget::setFileDropFunction(FileDropFunction f)
|
||||||
|
{
|
||||||
|
dropFunction_ = std::move(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
DragOperation SFileDropTarget::onDragEnter(DragEventData data)
|
||||||
|
{
|
||||||
|
op_ = isFileDrop(data.drag) ?
|
||||||
|
DragOperation::Copy : DragOperation::None;
|
||||||
|
return op_;
|
||||||
|
}
|
||||||
|
|
||||||
|
DragOperation SFileDropTarget::onDragMove(DragEventData data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
return op_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SFileDropTarget::onDragLeave(DragEventData data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
op_ = DragOperation::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SFileDropTarget::onDrop(DragEventData data)
|
||||||
|
{
|
||||||
|
if (op_ != DragOperation::Copy || !isFileDrop(data.drag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
IDataPackage::Type type;
|
||||||
|
const void* bytes;
|
||||||
|
uint32_t size = data.drag->getData(0, bytes, type);
|
||||||
|
std::string path(reinterpret_cast<const char*>(bytes), size);
|
||||||
|
|
||||||
|
if (dropFunction_)
|
||||||
|
dropFunction_(path);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SFileDropTarget::isFileDrop(IDataPackage* package)
|
||||||
|
{
|
||||||
|
return package->getCount() == 1 &&
|
||||||
|
package->getDataType(0) == IDataPackage::kFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
SPiano::SPiano(const CRect& bounds)
|
||||||
|
: CView(bounds), font_(kNormalFont)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::setFont(CFontRef font)
|
||||||
|
{
|
||||||
|
font_ = font;
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::clearKeyRanges()
|
||||||
|
{
|
||||||
|
keyInRange_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::addKeyRange(int start, int end)
|
||||||
|
{
|
||||||
|
start = std::min(127, std::max(0, start));
|
||||||
|
end = std::min(127, std::max(0, end));
|
||||||
|
|
||||||
|
for (int x = start; x <= end; ++x)
|
||||||
|
keyInRange_.set(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoord SPiano::getKeyWidth()
|
||||||
|
{
|
||||||
|
return 6.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoord SPiano::getKeySwitchesHeight()
|
||||||
|
{
|
||||||
|
return 20.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoord SPiano::getKeyRangesHeight()
|
||||||
|
{
|
||||||
|
return 11.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoord SPiano::getKeysHeight() const
|
||||||
|
{
|
||||||
|
return getHeight() -
|
||||||
|
(getKeySwitchesHeight() + getKeyRangesHeight() + getOctavesHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoord SPiano::getOctavesHeight() const
|
||||||
|
{
|
||||||
|
return font_->getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::getZoneDimensions(
|
||||||
|
CRect* pKeySwitches,
|
||||||
|
CRect* pKeyboard,
|
||||||
|
CRect* pKeyRanges,
|
||||||
|
CRect* pOctaves)
|
||||||
|
{
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
|
||||||
|
CRect keySwitches(bounds);
|
||||||
|
keySwitches.setHeight(getKeySwitchesHeight());
|
||||||
|
|
||||||
|
CRect keyboard(bounds);
|
||||||
|
keyboard.top = keySwitches.bottom;
|
||||||
|
keyboard.setHeight(getKeysHeight());
|
||||||
|
|
||||||
|
CRect keyRanges(bounds);
|
||||||
|
keyRanges.top = keyboard.bottom;
|
||||||
|
keyRanges.setHeight(getKeyRangesHeight());
|
||||||
|
|
||||||
|
CRect octaves(bounds);
|
||||||
|
octaves.top = keyRanges.bottom;
|
||||||
|
octaves.setHeight(getOctavesHeight());
|
||||||
|
|
||||||
|
// apply some paddings
|
||||||
|
keySwitches.extend(-2.0, -2.0);
|
||||||
|
keyboard.extend(-2.0, -2.0);
|
||||||
|
keyRanges.extend(-2.0, -4.0);
|
||||||
|
octaves.extend(-2.0, -2.0);
|
||||||
|
|
||||||
|
// offsets for centered keyboard
|
||||||
|
CCoord keyWidth = getKeyWidth();
|
||||||
|
CCoord offset = std::round((keyboard.getWidth() - (128.0 * keyWidth)) * 0.5);
|
||||||
|
if (offset > 0) {
|
||||||
|
keySwitches.extend(-offset, 0.0);
|
||||||
|
keyboard.extend(-offset, 0.0);
|
||||||
|
keyRanges.extend(-offset, 0.0);
|
||||||
|
octaves.extend(-offset, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (pKeySwitches)
|
||||||
|
*pKeySwitches = keySwitches;
|
||||||
|
if (pKeyboard)
|
||||||
|
*pKeyboard = keyboard;
|
||||||
|
if (pKeyRanges)
|
||||||
|
*pKeyRanges = keyRanges;
|
||||||
|
if (pOctaves)
|
||||||
|
*pOctaves = octaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::draw(CDrawContext* dc)
|
||||||
|
{
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
|
||||||
|
dc->setDrawMode(kAntiAliasing);
|
||||||
|
|
||||||
|
SharedPointer<CGraphicsPath> path;
|
||||||
|
|
||||||
|
path = owned(dc->createGraphicsPath());
|
||||||
|
path->addRoundRect(bounds, 5.0);
|
||||||
|
dc->setFillColor(CColor(0xca, 0xca, 0xca));
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathFilled);
|
||||||
|
|
||||||
|
//
|
||||||
|
CRect rectKeySwitches;
|
||||||
|
CRect rectKeyboard;
|
||||||
|
CRect rectKeyRanges;
|
||||||
|
CRect rectOctaves;
|
||||||
|
getZoneDimensions(&rectKeySwitches, &rectKeyboard, &rectKeyRanges, &rectOctaves);
|
||||||
|
|
||||||
|
//
|
||||||
|
path = owned(dc->createGraphicsPath());
|
||||||
|
path->addRoundRect(rectKeyboard, 1.0);
|
||||||
|
dc->setFillColor(CColor(0xff, 0xff, 0xff));
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathFilled);
|
||||||
|
|
||||||
|
CCoord keyWidth = getKeyWidth();
|
||||||
|
for (int key = 0; key < 128; ++key) {
|
||||||
|
CCoord keyX = rectKeyboard.left + key * keyWidth;
|
||||||
|
int key12 = key % 12;
|
||||||
|
if (key12 == 1 || key12 == 3 ||
|
||||||
|
key12 == 6 || key12 == 8 || key12 == 10)
|
||||||
|
{
|
||||||
|
CRect blackRect(keyX, rectKeyboard.top + 2, keyX + keyWidth, rectKeyboard.bottom - 2);
|
||||||
|
path = owned(dc->createGraphicsPath());
|
||||||
|
path->addRoundRect(blackRect, 1.0);
|
||||||
|
dc->setFillColor(CColor(0x02, 0x02, 0x02));
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathFilled);
|
||||||
|
}
|
||||||
|
if (key != 0 && key12 == 0) {
|
||||||
|
dc->setLineWidth(1.5);
|
||||||
|
dc->setFrameColor(CColor(0x63, 0x63, 0x63));
|
||||||
|
dc->drawLine(CPoint(keyX, rectKeyboard.top), CPoint(keyX, rectKeyboard.bottom));
|
||||||
|
}
|
||||||
|
if (key12 == 5) {
|
||||||
|
CCoord pad = rectKeyboard.getHeight() * 0.4;
|
||||||
|
dc->setLineWidth(1.0);
|
||||||
|
dc->setFrameColor(CColor(0x63, 0x63, 0x63));
|
||||||
|
dc->drawLine(CPoint(keyX, rectKeyboard.top + pad), CPoint(keyX, rectKeyboard.bottom - pad));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
for (int rangeStart = 0; rangeStart < 128;)
|
||||||
|
{
|
||||||
|
if (!keyInRange_[rangeStart]) {
|
||||||
|
++rangeStart;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int rangeEnd = rangeStart;
|
||||||
|
while (rangeEnd + 1 < 128 && keyInRange_[rangeEnd + 1])
|
||||||
|
++rangeEnd;
|
||||||
|
|
||||||
|
CCoord rangeStartX = rectKeyRanges.left + rangeStart * keyWidth;
|
||||||
|
CCoord rangeEndX = rectKeyRanges.left + (rangeEnd + 1.0) * keyWidth;
|
||||||
|
CRect rectRange(rangeStartX, rectKeyRanges.top, rangeEndX, rectKeyRanges.bottom);
|
||||||
|
|
||||||
|
path = owned(dc->createGraphicsPath());
|
||||||
|
path->addRoundRect(rectRange, 2.0);
|
||||||
|
dc->setFillColor(CColor(0x0f, 0x0f, 0x0f));
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathFilled);
|
||||||
|
|
||||||
|
rangeStart = rangeEnd + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
for (int key = 0; key < 128; ++key) {
|
||||||
|
CCoord keyX = rectOctaves.left + key * keyWidth;
|
||||||
|
int key12 = key % 12;
|
||||||
|
if (key12 == 0) {
|
||||||
|
CRect textRect(keyX, rectOctaves.top, keyX + 12 * keyWidth, rectOctaves.bottom);
|
||||||
|
dc->setFont(font_);
|
||||||
|
dc->setFontColor(CColor(0x63, 0x63, 0x63));
|
||||||
|
dc->drawString(std::to_string(key / 12 - 1).c_str(), textRect, kLeftText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
SValueMenu::SValueMenu(const CRect& bounds, IControlListener* listener, int32_t tag)
|
||||||
|
: CParamDisplay(bounds), menuListener_(owned(new MenuListener(*this)))
|
||||||
|
{
|
||||||
|
setListener(listener);
|
||||||
|
setTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SValueMenu::addEntry(CMenuItem* item, float value, int32_t index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > getNbEntries()) {
|
||||||
|
menuItems_.emplace_back(owned(item));
|
||||||
|
menuItemValues_.emplace_back(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menuItems_.insert(menuItems_.begin() + index, owned(item));
|
||||||
|
menuItemValues_.insert(menuItemValues_.begin() + index, value);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SValueMenu::addEntry(const UTF8String& title, float value, int32_t index, int32_t itemFlags)
|
||||||
|
{
|
||||||
|
if (title == "-")
|
||||||
|
return addSeparator(index);
|
||||||
|
CMenuItem* item = new CMenuItem(title, nullptr, 0, nullptr, itemFlags);
|
||||||
|
return addEntry(item, value, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SValueMenu::addSeparator(int32_t index)
|
||||||
|
{
|
||||||
|
CMenuItem* item = new CMenuItem("", nullptr, 0, nullptr, CMenuItem::kSeparator);
|
||||||
|
return addEntry(item, 0.0f, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t SValueMenu::getNbEntries() const
|
||||||
|
{
|
||||||
|
return static_cast<int32_t>(menuItems_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SValueMenu::onMouseDown(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
(void)where;
|
||||||
|
|
||||||
|
if (buttons & (kLButton|kRButton|kApple)) {
|
||||||
|
CFrame* frame = getFrame();
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
|
||||||
|
CPoint frameWhere = bounds.getBottomLeft();
|
||||||
|
this->localToFrame(frameWhere);
|
||||||
|
|
||||||
|
auto self = shared(this);
|
||||||
|
frame->doAfterEventProcessing([self, frameWhere]() {
|
||||||
|
if (CFrame* frame = self->getFrame()) {
|
||||||
|
SharedPointer<COptionMenu> menu = owned(new COptionMenu(CRect(), self->menuListener_, -1, nullptr, nullptr, COptionMenu::kPopupStyle));
|
||||||
|
for (const SharedPointer<CMenuItem>& item : self->menuItems_) {
|
||||||
|
menu->addEntry(item);
|
||||||
|
item->remember(); // above call does not increment refcount
|
||||||
|
}
|
||||||
|
menu->setFont(self->getFont());
|
||||||
|
menu->setFontColor(self->getFontColor());
|
||||||
|
menu->setBackColor(self->getBackColor());
|
||||||
|
menu->popup(frame, frameWhere + CPoint(0.0, 1.0));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kMouseEventNotHandled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SValueMenu::onItemClicked(int32_t index)
|
||||||
|
{
|
||||||
|
float oldValue = getValue();
|
||||||
|
setValue(menuItemValues_[index]);
|
||||||
|
if (getValue() != oldValue)
|
||||||
|
valueChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STextButton::setHoverColor (const CColor& color)
|
||||||
|
{
|
||||||
|
hoverColor_ = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void STextButton::draw(CDrawContext* context)
|
||||||
|
{
|
||||||
|
CColor backupColor = textColor;
|
||||||
|
if (hovered) {
|
||||||
|
textColor = hoverColor_; // textColor is protected
|
||||||
|
}
|
||||||
|
CTextButton::draw(context);
|
||||||
|
if (hovered)
|
||||||
|
textColor = backupColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CMouseEventResult STextButton::onMouseEntered (CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
hovered = true;
|
||||||
|
setDirty();
|
||||||
|
return CTextButton::onMouseEntered(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult STextButton::onMouseExited (CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
hovered = false;
|
||||||
|
setDirty();
|
||||||
|
return CTextButton::onMouseExited(where, buttons);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,160 @@
|
||||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#include "utility/vstgui_before.h"
|
#include "utility/vstgui_before.h"
|
||||||
#include "vstgui/lib/controls/cslider.h"
|
#include "vstgui/lib/controls/cslider.h"
|
||||||
|
#include "vstgui/lib/controls/cknob.h"
|
||||||
|
#include "vstgui/lib/controls/ctextlabel.h"
|
||||||
|
#include "vstgui/lib/controls/cbuttons.h"
|
||||||
|
#include "vstgui/lib/controls/coptionmenu.h"
|
||||||
|
#include "vstgui/lib/cviewcontainer.h"
|
||||||
#include "vstgui/lib/ccolor.h"
|
#include "vstgui/lib/ccolor.h"
|
||||||
|
#include "vstgui/lib/dragging.h"
|
||||||
#include "utility/vstgui_after.h"
|
#include "utility/vstgui_after.h"
|
||||||
|
|
||||||
using namespace VSTGUI;
|
using namespace VSTGUI;
|
||||||
|
|
||||||
class SimpleSlider : public CSliderBase {
|
///
|
||||||
|
class SBoxContainer : public CViewContainer {
|
||||||
public:
|
public:
|
||||||
SimpleSlider(const CRect& bounds, IControlListener* listener, int32_t tag);
|
explicit SBoxContainer(const CRect& size);
|
||||||
void draw(CDrawContext* dc) override;
|
virtual ~SBoxContainer() {}
|
||||||
|
void setCornerRadius(CCoord radius);
|
||||||
|
void setBackgroundColor(const CColor& color) override;
|
||||||
|
CColor getBackgroundColor() const override;
|
||||||
|
|
||||||
CLASS_METHODS(SimpleSlider, CSliderBase)
|
protected:
|
||||||
|
void drawRect(CDrawContext* dc, const CRect& updateRect) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CCoord cornerRadius_ = 0.0;
|
||||||
|
CColor backgroundColor_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class STitleContainer : public SBoxContainer {
|
||||||
|
public:
|
||||||
|
explicit STitleContainer(const CRect& size, UTF8StringPtr text = nullptr);
|
||||||
|
~STitleContainer() {}
|
||||||
|
|
||||||
|
void setTitleFont(CFontRef font);
|
||||||
|
CFontRef getTitleFont() { return titleFont_; }
|
||||||
|
|
||||||
|
void setTitleFontColor(CColor color);
|
||||||
|
CColor getTitleFontColor() const { return titleFontColor_; }
|
||||||
|
void setTitleBackgroundColor(CColor color);
|
||||||
|
CColor getTitleBackgroundColor() const { return titleBackgroundColor_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawRect(CDrawContext* dc, const CRect& updateRect) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CColor _frame = CColor(0x00, 0x00, 0x00);
|
std::string text_;
|
||||||
CColor _fill = CColor(0x00, 0x00, 0x00);
|
CColor titleFontColor_;
|
||||||
|
CColor titleBackgroundColor_;
|
||||||
|
SharedPointer<CFontDesc> titleFont_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class SFileDropTarget : public IDropTarget,
|
||||||
|
public NonAtomicReferenceCounted {
|
||||||
|
public:
|
||||||
|
typedef std::function<void(const std::string&)> FileDropFunction;
|
||||||
|
void setFileDropFunction(FileDropFunction f);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DragOperation onDragEnter(DragEventData data) override;
|
||||||
|
DragOperation onDragMove(DragEventData data) override;
|
||||||
|
void onDragLeave(DragEventData data) override;
|
||||||
|
bool onDrop(DragEventData data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool isFileDrop(IDataPackage* package);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DragOperation op_ = DragOperation::None;
|
||||||
|
FileDropFunction dropFunction_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class SPiano : public CView {
|
||||||
|
public:
|
||||||
|
explicit SPiano(const CRect& bounds);
|
||||||
|
CFontRef getFont() const { return font_; }
|
||||||
|
void setFont(CFontRef font);
|
||||||
|
|
||||||
|
void clearKeyRanges();
|
||||||
|
void addKeyRange(int start, int end);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static CCoord getKeyWidth();
|
||||||
|
static CCoord getKeySwitchesHeight();
|
||||||
|
static CCoord getKeyRangesHeight();
|
||||||
|
CCoord getKeysHeight() const;
|
||||||
|
CCoord getOctavesHeight() const;
|
||||||
|
|
||||||
|
void getZoneDimensions(
|
||||||
|
CRect* pKeySwitches,
|
||||||
|
CRect* pKeyboard,
|
||||||
|
CRect* pKeyRanges,
|
||||||
|
CRect* pOctaves);
|
||||||
|
|
||||||
|
void draw(CDrawContext* dc) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SharedPointer<CFontDesc> font_;
|
||||||
|
std::bitset<128> keyInRange_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class SValueMenu : public CParamDisplay {
|
||||||
|
public:
|
||||||
|
explicit SValueMenu(const CRect& bounds, IControlListener* listener, int32_t tag);
|
||||||
|
CMenuItem* addEntry(CMenuItem* item, float value, int32_t index = -1);
|
||||||
|
CMenuItem* addEntry(const UTF8String& title, float value, int32_t index = -1, int32_t itemFlags = CMenuItem::kNoFlags);
|
||||||
|
CMenuItem* addSeparator(int32_t index = -1);
|
||||||
|
int32_t getNbEntries() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class MenuListener;
|
||||||
|
|
||||||
|
//
|
||||||
|
void onItemClicked(int32_t index);
|
||||||
|
|
||||||
|
//
|
||||||
|
CMenuItemList menuItems_;
|
||||||
|
std::vector<float> menuItemValues_;
|
||||||
|
SharedPointer<MenuListener> menuListener_;
|
||||||
|
|
||||||
|
//
|
||||||
|
class MenuListener : public IControlListener, public NonAtomicReferenceCounted {
|
||||||
|
public:
|
||||||
|
explicit MenuListener(SValueMenu& menu) : menu_(menu) {}
|
||||||
|
void valueChanged(CControl* control) override
|
||||||
|
{
|
||||||
|
menu_.onItemClicked(static_cast<int32_t>(control->getValue()));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SValueMenu& menu_;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class STextButton: public CTextButton {
|
||||||
|
public:
|
||||||
|
STextButton(const CRect& size, IControlListener* listener = nullptr, int32_t tag = -1, UTF8StringPtr title = nullptr)
|
||||||
|
: CTextButton(size, listener, tag, title) {}
|
||||||
|
|
||||||
|
void setHoverColor(const CColor& color);
|
||||||
|
CMouseEventResult onMouseEntered (CPoint& where, const CButtonState& buttons) override;
|
||||||
|
CMouseEventResult onMouseExited (CPoint& where, const CButtonState& buttons) override;
|
||||||
|
void draw(CDrawContext* context) override;
|
||||||
|
private:
|
||||||
|
CColor hoverColor_;
|
||||||
|
bool hovered { false };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
50
editor/src/editor/NativeHelpers.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "NativeHelpers.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include "ghc/fs_std.hpp"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *filename)
|
||||||
|
{
|
||||||
|
std::wstring path = fs::u8path(filename).wstring();
|
||||||
|
|
||||||
|
SHELLEXECUTEINFOW info;
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
|
||||||
|
info.cbSize = sizeof(info);
|
||||||
|
info.fMask = SEE_MASK_CLASSNAME;
|
||||||
|
info.lpVerb = L"open";
|
||||||
|
info.lpFile = path.c_str();
|
||||||
|
info.lpClass = L"txtfile";
|
||||||
|
info.nShow = SW_SHOW;
|
||||||
|
|
||||||
|
return ShellExecuteExW(&info);
|
||||||
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
// implemented in NativeHelpers.mm
|
||||||
|
#else
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *filename)
|
||||||
|
{
|
||||||
|
GAppInfo* appinfo = g_app_info_get_default_for_type("text/plain", FALSE);
|
||||||
|
if (!appinfo)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
GList* files = nullptr;
|
||||||
|
GFile* file = g_file_new_for_path(filename);
|
||||||
|
files = g_list_append(files, file);
|
||||||
|
gboolean success = g_app_info_launch(appinfo, files, nullptr, nullptr);
|
||||||
|
g_object_unref(file);
|
||||||
|
g_list_free(files);
|
||||||
|
g_object_unref(appinfo);
|
||||||
|
return success == TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
9
editor/src/editor/NativeHelpers.h
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *filename);
|
||||||
30
editor/src/editor/NativeHelpers.mm
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "NativeHelpers.h"
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#import <CoreServices/CoreServices.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *fileNameUTF8)
|
||||||
|
{
|
||||||
|
BOOL wasOpened = NO;
|
||||||
|
|
||||||
|
NSURL* applicationURL = (__bridge_transfer NSURL*)LSCopyDefaultApplicationURLForContentType(
|
||||||
|
kUTTypePlainText, kLSRolesEditor, nil);
|
||||||
|
if (!applicationURL)
|
||||||
|
return false;
|
||||||
|
if ([applicationURL isFileURL]) {
|
||||||
|
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
|
||||||
|
NSString* fileName = [NSString stringWithUTF8String:fileNameUTF8];
|
||||||
|
wasOpened = [workspace openFile:fileName withApplication:[applicationURL path]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return wasOpened == YES;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
155
editor/src/editor/layout/main.hpp
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
/* This file is generated by the layout maker tool. */
|
||||||
|
LogicalGroup* const view__0 = createLogicalGroup(CRect(0, 0, 800, 475), -1, "", kCenterText, 14);
|
||||||
|
mainView = view__0;
|
||||||
|
Background* const view__1 = createBackground(CRect(190, 110, 790, 390), -1, "", kCenterText, 14);
|
||||||
|
view__0->addView(view__1);
|
||||||
|
enterTheme(darkTheme);
|
||||||
|
LogicalGroup* const view__2 = createLogicalGroup(CRect(0, 0, 800, 110), -1, "", kCenterText, 14);
|
||||||
|
view__0->addView(view__2);
|
||||||
|
RoundedGroup* const view__3 = createRoundedGroup(CRect(5, 4, 180, 105), -1, "", kCenterText, 14);
|
||||||
|
view__2->addView(view__3);
|
||||||
|
SfizzMainButton* const view__4 = createSfizzMainButton(CRect(30, 5, 150, 65), kTagFirstChangePanel+kPanelGeneral, "", kCenterText, 14);
|
||||||
|
view__3->addView(view__4);
|
||||||
|
HomeButton* const view__5 = createHomeButton(CRect(44, 69, 69, 94), kTagFirstChangePanel+kPanelGeneral, "", kCenterText, 24);
|
||||||
|
view__3->addView(view__5);
|
||||||
|
CCButton* const view__6 = createCCButton(CRect(76, 69, 101, 94), kTagFirstChangePanel+kPanelControls, "", kCenterText, 24);
|
||||||
|
view__3->addView(view__6);
|
||||||
|
SettingsButton* const view__7 = createSettingsButton(CRect(107, 69, 132, 94), kTagFirstChangePanel+kPanelSettings, "", kCenterText, 24);
|
||||||
|
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);
|
||||||
|
view__8->addView(view__9);
|
||||||
|
Label* const view__10 = createLabel(CRect(15, 40, 55, 70), -1, "KS:", kCenterText, 16);
|
||||||
|
view__8->addView(view__10);
|
||||||
|
HLine* const view__11 = createHLine(CRect(10, 36, 370, 41), -1, "", kCenterText, 14);
|
||||||
|
view__8->addView(view__11);
|
||||||
|
HLine* const view__12 = createHLine(CRect(10, 68, 370, 73), -1, "", kCenterText, 14);
|
||||||
|
view__8->addView(view__12);
|
||||||
|
Label* const view__13 = createLabel(CRect(80, 7, 310, 37), -1, "DefaultInstrument.sfz", kCenterText, 20);
|
||||||
|
sfzFileLabel_ = view__13;
|
||||||
|
view__8->addView(view__13);
|
||||||
|
Label* const view__14 = createLabel(CRect(80, 39, 310, 69), -1, "Key switch", kCenterText, 20);
|
||||||
|
view__8->addView(view__14);
|
||||||
|
Label* const view__15 = createLabel(CRect(10, 71, 70, 96), -1, "Voices:", kRightText, 12);
|
||||||
|
view__8->addView(view__15);
|
||||||
|
LoadFileButton* const view__16 = createLoadFileButton(CRect(315, 9, 340, 34), kTagLoadSfzFile, "", kCenterText, 24);
|
||||||
|
view__8->addView(view__16);
|
||||||
|
EditFileButton* const view__17 = createEditFileButton(CRect(340, 9, 365, 34), kTagEditSfzFile, "", kCenterText, 24);
|
||||||
|
view__8->addView(view__17);
|
||||||
|
Label* const view__18 = createLabel(CRect(75, 71, 125, 96), -1, "", kCenterText, 12);
|
||||||
|
infoVoicesLabel_ = view__18;
|
||||||
|
view__8->addView(view__18);
|
||||||
|
Label* const view__19 = createLabel(CRect(130, 71, 190, 96), -1, "Max:", kRightText, 12);
|
||||||
|
view__8->addView(view__19);
|
||||||
|
Label* const view__20 = createLabel(CRect(195, 71, 245, 96), -1, "", kCenterText, 12);
|
||||||
|
numVoicesLabel_ = view__20;
|
||||||
|
view__8->addView(view__20);
|
||||||
|
Label* const view__21 = createLabel(CRect(250, 71, 310, 96), -1, "Memory:", kRightText, 12);
|
||||||
|
view__8->addView(view__21);
|
||||||
|
Label* const view__22 = createLabel(CRect(315, 71, 365, 96), -1, "", kCenterText, 12);
|
||||||
|
memoryLabel_ = view__22;
|
||||||
|
view__8->addView(view__22);
|
||||||
|
RoundedGroup* const view__23 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14);
|
||||||
|
view__2->addView(view__23);
|
||||||
|
Knob48* const view__24 = createKnob48(CRect(45, 15, 93, 63), -1, "", kCenterText, 14);
|
||||||
|
view__23->addView(view__24);
|
||||||
|
view__24->setVisible(false);
|
||||||
|
ValueLabel* const view__25 = createValueLabel(CRect(40, 65, 100, 70), -1, "Center", kCenterText, 12);
|
||||||
|
view__23->addView(view__25);
|
||||||
|
view__25->setVisible(false);
|
||||||
|
Knob48* const view__26 = createKnob48(CRect(110, 15, 158, 63), kTagSetVolume, "", kCenterText, 14);
|
||||||
|
volumeSlider_ = view__26;
|
||||||
|
view__23->addView(view__26);
|
||||||
|
ValueLabel* const view__27 = createValueLabel(CRect(105, 65, 165, 87), -1, "0.0 dB", kCenterText, 12);
|
||||||
|
volumeLabel_ = view__27;
|
||||||
|
view__23->addView(view__27);
|
||||||
|
VMeter* const view__28 = createVMeter(CRect(175, 15, 210, 70), -1, "", kCenterText, 14);
|
||||||
|
view__23->addView(view__28);
|
||||||
|
enterTheme(defaultTheme);
|
||||||
|
LogicalGroup* const view__29 = createLogicalGroup(CRect(5, 110, 796, 395), -1, "", kCenterText, 14);
|
||||||
|
subPanels_[kPanelGeneral] = view__29;
|
||||||
|
view__0->addView(view__29);
|
||||||
|
view__29->setVisible(false);
|
||||||
|
RoundedGroup* const view__30 = createRoundedGroup(CRect(0, 0, 175, 280), -1, "", kCenterText, 14);
|
||||||
|
view__29->addView(view__30);
|
||||||
|
Label* const view__31 = createLabel(CRect(15, 10, 75, 35), -1, "Curves:", kLeftText, 14);
|
||||||
|
view__30->addView(view__31);
|
||||||
|
Label* const view__32 = createLabel(CRect(15, 35, 75, 60), -1, "Masters:", kLeftText, 14);
|
||||||
|
view__30->addView(view__32);
|
||||||
|
Label* const view__33 = createLabel(CRect(15, 60, 75, 85), -1, "Groups:", kLeftText, 14);
|
||||||
|
view__30->addView(view__33);
|
||||||
|
Label* const view__34 = createLabel(CRect(15, 85, 75, 110), -1, "Regions:", kLeftText, 14);
|
||||||
|
view__30->addView(view__34);
|
||||||
|
Label* const view__35 = createLabel(CRect(15, 110, 75, 135), -1, "Samples:", kLeftText, 14);
|
||||||
|
view__30->addView(view__35);
|
||||||
|
Label* const view__36 = createLabel(CRect(115, 10, 155, 35), -1, "0", kCenterText, 14);
|
||||||
|
infoCurvesLabel_ = view__36;
|
||||||
|
view__30->addView(view__36);
|
||||||
|
Label* const view__37 = createLabel(CRect(115, 35, 155, 60), -1, "0", kCenterText, 14);
|
||||||
|
infoMastersLabel_ = view__37;
|
||||||
|
view__30->addView(view__37);
|
||||||
|
Label* const view__38 = createLabel(CRect(115, 60, 155, 85), -1, "0", kCenterText, 14);
|
||||||
|
infoGroupsLabel_ = view__38;
|
||||||
|
view__30->addView(view__38);
|
||||||
|
Label* const view__39 = createLabel(CRect(115, 85, 155, 110), -1, "0", kCenterText, 14);
|
||||||
|
infoRegionsLabel_ = view__39;
|
||||||
|
view__30->addView(view__39);
|
||||||
|
Label* const view__40 = createLabel(CRect(115, 110, 155, 135), -1, "0", kCenterText, 14);
|
||||||
|
infoSamplesLabel_ = view__40;
|
||||||
|
view__30->addView(view__40);
|
||||||
|
LogicalGroup* const view__41 = createLogicalGroup(CRect(5, 110, 795, 395), -1, "", kCenterText, 14);
|
||||||
|
subPanels_[kPanelControls] = view__41;
|
||||||
|
view__0->addView(view__41);
|
||||||
|
view__41->setVisible(false);
|
||||||
|
RoundedGroup* const view__42 = createRoundedGroup(CRect(0, 0, 790, 285), -1, "", kCenterText, 14);
|
||||||
|
view__41->addView(view__42);
|
||||||
|
Label* const view__43 = createLabel(CRect(0, 0, 790, 285), -1, "Controls not available", kCenterText, 40);
|
||||||
|
view__42->addView(view__43);
|
||||||
|
LogicalGroup* const view__44 = createLogicalGroup(CRect(5, 109, 795, 395), -1, "", kCenterText, 14);
|
||||||
|
subPanels_[kPanelSettings] = view__44;
|
||||||
|
view__0->addView(view__44);
|
||||||
|
TitleGroup* const view__45 = createTitleGroup(CRect(255, 26, 535, 126), -1, "Engine", kCenterText, 12);
|
||||||
|
view__44->addView(view__45);
|
||||||
|
ValueMenu* const view__46 = createValueMenu(CRect(25, 60, 85, 85), kTagSetNumVoices, "", kCenterText, 12);
|
||||||
|
numVoicesSlider_ = view__46;
|
||||||
|
view__45->addView(view__46);
|
||||||
|
ValueLabel* const view__47 = createValueLabel(CRect(15, 20, 95, 45), -1, "Polyphony", kCenterText, 12);
|
||||||
|
view__45->addView(view__47);
|
||||||
|
ValueMenu* const view__48 = createValueMenu(CRect(110, 60, 170, 85), kTagSetOversampling, "", kCenterText, 12);
|
||||||
|
oversamplingSlider_ = view__48;
|
||||||
|
view__45->addView(view__48);
|
||||||
|
ValueLabel* const view__49 = createValueLabel(CRect(100, 20, 180, 45), -1, "Oversampling", kCenterText, 12);
|
||||||
|
view__45->addView(view__49);
|
||||||
|
ValueLabel* const view__50 = createValueLabel(CRect(185, 20, 265, 45), -1, "Preload size", kCenterText, 12);
|
||||||
|
view__45->addView(view__50);
|
||||||
|
ValueMenu* const view__51 = createValueMenu(CRect(195, 60, 255, 85), kTagSetPreloadSize, "", kCenterText, 12);
|
||||||
|
preloadSizeSlider_ = view__51;
|
||||||
|
view__45->addView(view__51);
|
||||||
|
TitleGroup* const view__52 = createTitleGroup(CRect(200, 161, 590, 261), -1, "Tuning", kCenterText, 12);
|
||||||
|
view__44->addView(view__52);
|
||||||
|
ValueLabel* const view__53 = createValueLabel(CRect(125, 20, 205, 45), -1, "Root key", kCenterText, 12);
|
||||||
|
view__52->addView(view__53);
|
||||||
|
ValueMenu* const view__54 = createValueMenu(CRect(220, 60, 280, 85), kTagSetTuningFrequency, "", kCenterText, 12);
|
||||||
|
tuningFrequencySlider_ = view__54;
|
||||||
|
view__52->addView(view__54);
|
||||||
|
ValueLabel* const view__55 = createValueLabel(CRect(210, 20, 290, 45), -1, "Frequency", kCenterText, 12);
|
||||||
|
view__52->addView(view__55);
|
||||||
|
Knob48* const view__56 = createKnob48(CRect(310, 45, 358, 93), kTagSetStretchedTuning, "", kCenterText, 14);
|
||||||
|
stretchedTuningSlider_ = view__56;
|
||||||
|
view__52->addView(view__56);
|
||||||
|
ValueLabel* const view__57 = createValueLabel(CRect(295, 20, 375, 45), -1, "Stretch", kCenterText, 12);
|
||||||
|
view__52->addView(view__57);
|
||||||
|
ValueLabel* const view__58 = createValueLabel(CRect(20, 20, 120, 45), -1, "Scala file", kCenterText, 12);
|
||||||
|
view__52->addView(view__58);
|
||||||
|
ValueButton* const view__59 = createValueButton(CRect(20, 60, 120, 85), kTagLoadScalaFile, "DefaultScale", kCenterText, 12);
|
||||||
|
scalaFileButton_ = view__59;
|
||||||
|
view__52->addView(view__59);
|
||||||
|
ValueMenu* const view__60 = createValueMenu(CRect(135, 60, 170, 85), kTagSetScalaRootKey, "", kCenterText, 12);
|
||||||
|
scalaRootKeySlider_ = view__60;
|
||||||
|
view__52->addView(view__60);
|
||||||
|
ValueMenu* const view__61 = createValueMenu(CRect(170, 60, 200, 85), kTagSetScalaRootKey, "", kCenterText, 12);
|
||||||
|
scalaRootOctaveSlider_ = view__61;
|
||||||
|
view__52->addView(view__61);
|
||||||
|
Piano* const view__62 = createPiano(CRect(5, 400, 795, 470), -1, "", kCenterText, 14);
|
||||||
|
view__0->addView(view__62);
|
||||||
23
editor/tools/layout-maker/LICENSE
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
2
editor/tools/layout-maker/README
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
This purpose of this tool is to accept UI designs make with Fluid, the FLTK
|
||||||
|
design editor, and convert these designs to music plugin interfaces.
|
||||||
42
editor/tools/layout-maker/sources/layout.h
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct LayoutImage {
|
||||||
|
std::string filepath;
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int w = 0;
|
||||||
|
int h = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LayoutItem {
|
||||||
|
std::string id;
|
||||||
|
std::string classname;
|
||||||
|
std::string label;
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int w = 0;
|
||||||
|
int h = 0;
|
||||||
|
std::string box;
|
||||||
|
std::string down_box;
|
||||||
|
int labelfont = 0;
|
||||||
|
int labelsize = 14;
|
||||||
|
std::string labeltype;
|
||||||
|
int textsize = 14;
|
||||||
|
int align = 0;
|
||||||
|
double value = 0;
|
||||||
|
double minimum = 0;
|
||||||
|
double maximum = 0;
|
||||||
|
double step = 0;
|
||||||
|
std::string type;
|
||||||
|
std::string callback;
|
||||||
|
LayoutImage image;
|
||||||
|
bool hidden = false;
|
||||||
|
std::string comment;
|
||||||
|
std::vector<LayoutItem> items;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Layout {
|
||||||
|
std::vector<LayoutItem> items;
|
||||||
|
};
|
||||||
136
editor/tools/layout-maker/sources/main.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
#include "layout.h"
|
||||||
|
#include "reader.h"
|
||||||
|
#include <absl/strings/ascii.h>
|
||||||
|
#include <absl/strings/string_view.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
///
|
||||||
|
typedef std::unordered_map<std::string, std::string> Metadata;
|
||||||
|
|
||||||
|
static Metadata metadata_from_comment(absl::string_view comment)
|
||||||
|
{
|
||||||
|
Metadata md;
|
||||||
|
|
||||||
|
while (!comment.empty()) {
|
||||||
|
absl::string_view line;
|
||||||
|
|
||||||
|
size_t pos = comment.find_first_of("\r\n");
|
||||||
|
if (pos != comment.npos) {
|
||||||
|
line = comment.substr(0, pos);
|
||||||
|
comment.remove_prefix(pos + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
line = comment;
|
||||||
|
comment = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
line = absl::StripAsciiWhitespace(line);
|
||||||
|
if (line.empty() || line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string key, value;
|
||||||
|
pos = line.find_first_of('=');
|
||||||
|
if (pos != comment.npos) {
|
||||||
|
key = std::string(line.substr(0, pos));
|
||||||
|
value = std::string(line.substr(pos + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
key = std::string(line);
|
||||||
|
|
||||||
|
md.emplace(std::move(key), std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return md;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
static void codegen_item(int& idCounter, int parentId, int parentX, int parentY, const LayoutItem& item, absl::string_view oldTheme)
|
||||||
|
{
|
||||||
|
const Metadata md = metadata_from_comment(item.comment);
|
||||||
|
|
||||||
|
absl::string_view tag = "-1";
|
||||||
|
absl::string_view newTheme;
|
||||||
|
|
||||||
|
Metadata::const_iterator it;
|
||||||
|
it = md.find("tag");
|
||||||
|
if (it != md.end())
|
||||||
|
tag = it->second;
|
||||||
|
it = md.find("theme");
|
||||||
|
if (it != md.end())
|
||||||
|
newTheme = it->second;
|
||||||
|
|
||||||
|
absl::string_view currentTheme = newTheme.empty() ? oldTheme : newTheme;
|
||||||
|
|
||||||
|
int id = idCounter++;
|
||||||
|
int myX = item.x;
|
||||||
|
int myY = item.y;
|
||||||
|
if (parentId == -1) {
|
||||||
|
myX = 0;
|
||||||
|
myY = 0;
|
||||||
|
}
|
||||||
|
int relX = myX - parentX;
|
||||||
|
int relY = myY - parentY;
|
||||||
|
|
||||||
|
//std::cout << "// Begin " << id << " " << item.classname << " {" << item.label << "}" << "\n";
|
||||||
|
|
||||||
|
if (!newTheme.empty())
|
||||||
|
std::cout << "enterTheme(" << newTheme << ");\n";
|
||||||
|
|
||||||
|
absl::string_view label;
|
||||||
|
if (!item.label.empty() && item.labeltype != "NO_LABEL")
|
||||||
|
label = item.label;
|
||||||
|
|
||||||
|
absl::string_view align = "kCenterText";
|
||||||
|
if (item.align & 4)
|
||||||
|
align = "kLeftText";
|
||||||
|
else if (item.align & 8)
|
||||||
|
align = "kRightText";
|
||||||
|
|
||||||
|
std::cout << item.classname << "* const view__" << id << " = create" << item.classname << "(CRect(" << relX << ", " << relY << ", " << (relX + item.w) << ", " << (relY + item.h) << "), " << tag << ", \"" << label << "\", " << align << ", " << item.labelsize << ");\n";
|
||||||
|
|
||||||
|
if (!item.id.empty())
|
||||||
|
std::cout << item.id << " = view__" << id << ";\n";
|
||||||
|
|
||||||
|
if (parentId != -1)
|
||||||
|
std::cout << "view__" << parentId << "->addView(view__" << id << ");\n";
|
||||||
|
|
||||||
|
if (item.hidden)
|
||||||
|
std::cout << "view__" << id << "->setVisible(false);\n";
|
||||||
|
|
||||||
|
for (const LayoutItem& subItem : item.items)
|
||||||
|
codegen_item(idCounter, id, myX, myY, subItem, currentTheme);
|
||||||
|
|
||||||
|
if (!newTheme.empty())
|
||||||
|
std::cout << "enterTheme(" << oldTheme << ");\n";
|
||||||
|
|
||||||
|
//std::cout << "// End " << id << " " << item.classname << " {" << item.label << "}" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void codegen_layout(const LayoutItem& item)
|
||||||
|
{
|
||||||
|
int idCounter = 0;
|
||||||
|
codegen_item(idCounter, -1, 0, 0, item, "defaultTheme");
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cerr << "Please indicate a fluid design file.\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout layout = read_file_layout(argv[1]);
|
||||||
|
|
||||||
|
if (layout.items.size() != 1) {
|
||||||
|
std::cerr << "There must be exactly 1 top level component.";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "/* This file is generated by the layout maker tool. */\n";
|
||||||
|
|
||||||
|
codegen_layout(layout.items[0]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
359
editor/tools/layout-maker/sources/reader.cpp
Normal file
|
|
@ -0,0 +1,359 @@
|
||||||
|
#include "reader.h"
|
||||||
|
#include <absl/strings/string_view.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
typedef std::vector<std::string> TokenList;
|
||||||
|
static bool read_file_tokens(const char *filename, TokenList &tokens);
|
||||||
|
static Layout read_tokens_layout(TokenList::iterator &tok_it, TokenList::iterator tok_end);
|
||||||
|
|
||||||
|
Layout read_file_layout(const char *filename)
|
||||||
|
{
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
if (!read_file_tokens(filename, tokens))
|
||||||
|
throw std::runtime_error("Cannot read fluid design file.");
|
||||||
|
|
||||||
|
TokenList::iterator tok_it = tokens.begin();
|
||||||
|
TokenList::iterator tok_end = tokens.end();
|
||||||
|
return read_tokens_layout(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string consume_next_token(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
if (tok_it == tok_end)
|
||||||
|
throw file_format_error("Premature end of tokens");
|
||||||
|
return *tok_it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool try_consume_next_token(const char *text, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
if (tok_it == tok_end)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (*tok_it != text)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
++tok_it;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ensure_next_token(const char *text, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
std::string tok = consume_next_token(tok_it, tok_end);
|
||||||
|
if (tok != text)
|
||||||
|
throw file_format_error("Unexpected token: " + tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string consume_enclosed_string(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
unsigned depth = 1;
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
for (;;) {
|
||||||
|
std::string part = consume_next_token(tok_it, tok_end);
|
||||||
|
if (part == "}") {
|
||||||
|
if (--depth == 0)
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
else if (part == "{")
|
||||||
|
++depth;
|
||||||
|
if (!text.empty())
|
||||||
|
text.push_back(' ');
|
||||||
|
text.append(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string consume_any_string(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
if (tok_it != tok_end && *tok_it == "{")
|
||||||
|
return consume_enclosed_string(tok_it, tok_end);
|
||||||
|
else
|
||||||
|
return consume_next_token(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int consume_int_token(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
std::string text = consume_next_token(tok_it, tok_end);
|
||||||
|
return std::stoi(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int consume_real_token(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
std::string text = consume_next_token(tok_it, tok_end);
|
||||||
|
return std::stod(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void consume_image_properties(LayoutImage &image, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
for (bool have = true; have;) {
|
||||||
|
if (try_consume_next_token("xywh", tok_it, tok_end)) {
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
image.x = consume_int_token(tok_it, tok_end);
|
||||||
|
image.y = consume_int_token(tok_it, tok_end);
|
||||||
|
image.w = consume_int_token(tok_it, tok_end);
|
||||||
|
image.h = consume_int_token(tok_it, tok_end);
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
have = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void consume_layout_item_properties(LayoutItem &item, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
// {
|
||||||
|
// ensure_next_token("{", tok_it, tok_end);
|
||||||
|
// for (std::string text; (text = consume_next_token(tok_it, tok_end)) != "}";) {
|
||||||
|
// if (text == "open" || text == "selected")
|
||||||
|
// ; // skip
|
||||||
|
// else if (text == "label")
|
||||||
|
// item.label = consume_any_string(tok_it, tok_end);
|
||||||
|
// else if (text == "xywh") {
|
||||||
|
// ensure_next_token("{", tok_it, tok_end);
|
||||||
|
// item.x = consume_int_token(tok_it, tok_end);
|
||||||
|
// item.y = consume_int_token(tok_it, tok_end);
|
||||||
|
// item.w = consume_int_token(tok_it, tok_end);
|
||||||
|
// item.h = consume_int_token(tok_it, tok_end);
|
||||||
|
// ensure_next_token("}", tok_it, tok_end);
|
||||||
|
// }
|
||||||
|
// else if (text == "box")
|
||||||
|
// item.box = consume_next_token(tok_it, tok_end);
|
||||||
|
// else if (text == "labelfont")
|
||||||
|
// item.labelfont = consume_int_token(tok_it, tok_end);
|
||||||
|
// else if (text == "labelsize")
|
||||||
|
// item.labelsize = consume_int_token(tok_it, tok_end);
|
||||||
|
// else if (text == "labeltype")
|
||||||
|
// item.labeltype = consume_any_string(tok_it, tok_end);
|
||||||
|
// else if (text == "align")
|
||||||
|
// item.align = consume_int_token(tok_it, tok_end);
|
||||||
|
// else if (text == "type")
|
||||||
|
// item.type = consume_any_string(tok_it, tok_end);
|
||||||
|
// else if (text == "callback")
|
||||||
|
// item.callback = consume_any_string(tok_it, tok_end);
|
||||||
|
// else if (text == "class")
|
||||||
|
// item.classname = consume_any_string(tok_it, tok_end);
|
||||||
|
// else if (text == "minimum")
|
||||||
|
// item.minimum = consume_real_token(tok_it, tok_end);
|
||||||
|
// else if (text == "maximum")
|
||||||
|
// item.maximum = consume_real_token(tok_it, tok_end);
|
||||||
|
// else if (text == "step")
|
||||||
|
// item.step = consume_real_token(tok_it, tok_end);
|
||||||
|
// else if (text == "image") {
|
||||||
|
// item.image.filepath = consume_any_string(tok_it, tok_end);
|
||||||
|
// consume_image_properties(item.image, tok_it, tok_end);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
static void consume_layout_item_properties(LayoutItem &item, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
for (bool have = true; have;) {
|
||||||
|
if (try_consume_next_token("open", tok_it, tok_end))
|
||||||
|
; // skip
|
||||||
|
else if (try_consume_next_token("selected", tok_it, tok_end))
|
||||||
|
; // skip
|
||||||
|
else if (try_consume_next_token("label", tok_it, tok_end))
|
||||||
|
item.label = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("xywh", tok_it, tok_end)) {
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
item.x = consume_int_token(tok_it, tok_end);
|
||||||
|
item.y = consume_int_token(tok_it, tok_end);
|
||||||
|
item.w = consume_int_token(tok_it, tok_end);
|
||||||
|
item.h = consume_int_token(tok_it, tok_end);
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (try_consume_next_token("box", tok_it, tok_end))
|
||||||
|
item.box = consume_next_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("down_box", tok_it, tok_end))
|
||||||
|
item.down_box = consume_next_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("labelfont", tok_it, tok_end))
|
||||||
|
item.labelfont = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("labelsize", tok_it, tok_end))
|
||||||
|
item.labelsize = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("labeltype", tok_it, tok_end))
|
||||||
|
item.labeltype = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("textsize", tok_it, tok_end))
|
||||||
|
item.textsize = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("align", tok_it, tok_end))
|
||||||
|
item.align = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("type", tok_it, tok_end))
|
||||||
|
item.type = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("callback", tok_it, tok_end))
|
||||||
|
item.callback = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("class", tok_it, tok_end))
|
||||||
|
item.classname = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("value", tok_it, tok_end))
|
||||||
|
item.value = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("minimum", tok_it, tok_end))
|
||||||
|
item.minimum = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("maximum", tok_it, tok_end))
|
||||||
|
item.maximum = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("step", tok_it, tok_end))
|
||||||
|
item.step = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("image", tok_it, tok_end))
|
||||||
|
item.image.filepath = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("hide", tok_it, tok_end))
|
||||||
|
item.hidden = true;
|
||||||
|
else if (try_consume_next_token("visible", tok_it, tok_end))
|
||||||
|
/* skip */;
|
||||||
|
else if (try_consume_next_token("comment", tok_it, tok_end))
|
||||||
|
item.comment = consume_any_string(tok_it, tok_end);
|
||||||
|
else
|
||||||
|
have = false;
|
||||||
|
}
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LayoutItem consume_layout_item(const std::string &classname, TokenList::iterator &tok_it, TokenList::iterator tok_end, bool anonymous = false)
|
||||||
|
{
|
||||||
|
LayoutItem item;
|
||||||
|
item.classname = classname;
|
||||||
|
if (!anonymous)
|
||||||
|
item.id = consume_any_string(tok_it, tok_end);
|
||||||
|
consume_layout_item_properties(item, tok_it, tok_end);
|
||||||
|
if (tok_it != tok_end && *tok_it == "{") {
|
||||||
|
consume_next_token(tok_it, tok_end);
|
||||||
|
for (std::string text; (text = consume_next_token(tok_it, tok_end)) != "}";) {
|
||||||
|
if (text == "decl") {
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (text == "Function") {
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
item.items.push_back(consume_layout_item(text, tok_it, tok_end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Layout read_tokens_layout(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
Layout layout;
|
||||||
|
|
||||||
|
std::string version_name;
|
||||||
|
std::string header_name;
|
||||||
|
std::string code_name;
|
||||||
|
|
||||||
|
while (tok_it != tok_end) {
|
||||||
|
std::string key = consume_next_token(tok_it, tok_end);
|
||||||
|
|
||||||
|
if (key == "version")
|
||||||
|
version_name = consume_next_token(tok_it, tok_end);
|
||||||
|
else if (key == "header_name") {
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
header_name = consume_next_token(tok_it, tok_end);
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (key == "code_name") {
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
code_name = consume_next_token(tok_it, tok_end);
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (key == "decl") {
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (key == "widget_class") {
|
||||||
|
key = consume_next_token(tok_it, tok_end);
|
||||||
|
layout.items.push_back(consume_layout_item(key, tok_it, tok_end, true));
|
||||||
|
layout.items.back().id = key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
layout.items.push_back(consume_layout_item(key, tok_it, tok_end));
|
||||||
|
}
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class tokenizer {
|
||||||
|
public:
|
||||||
|
tokenizer(
|
||||||
|
absl::string_view text,
|
||||||
|
absl::string_view dropped_delims,
|
||||||
|
absl::string_view kept_delims);
|
||||||
|
|
||||||
|
absl::string_view next();
|
||||||
|
|
||||||
|
private:
|
||||||
|
absl::string_view text_;
|
||||||
|
absl::string_view dropped_delims_;
|
||||||
|
absl::string_view kept_delims_;
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenizer::tokenizer(
|
||||||
|
absl::string_view text,
|
||||||
|
absl::string_view dropped_delims,
|
||||||
|
absl::string_view kept_delims)
|
||||||
|
: text_(text), dropped_delims_(dropped_delims), kept_delims_(kept_delims)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::string_view tokenizer::next()
|
||||||
|
{
|
||||||
|
auto is_dropped = [this](char c) -> bool {
|
||||||
|
return dropped_delims_.find(c) != dropped_delims_.npos;
|
||||||
|
};
|
||||||
|
auto is_kept = [this](char c) -> bool {
|
||||||
|
return kept_delims_.find(c) != kept_delims_.npos;
|
||||||
|
};
|
||||||
|
auto is_delim = [this](char c) -> bool {
|
||||||
|
return dropped_delims_.find(c) != dropped_delims_.npos ||
|
||||||
|
kept_delims_.find(c) != kept_delims_.npos;
|
||||||
|
};
|
||||||
|
|
||||||
|
absl::string_view text = text_;
|
||||||
|
|
||||||
|
while (!text.empty() && is_dropped(text[0]))
|
||||||
|
text.remove_prefix(1);
|
||||||
|
|
||||||
|
if (text.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
size_t pos;
|
||||||
|
{
|
||||||
|
auto it = std::find_if(text.begin(), text.end(), is_delim);
|
||||||
|
if (it == text.end())
|
||||||
|
pos = text.size();
|
||||||
|
else {
|
||||||
|
pos = std::distance(text.begin(), it);
|
||||||
|
pos += is_kept(text[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::string_view token = text.substr(0, pos);
|
||||||
|
text_ = text.substr(pos);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
static bool read_file_tokens(const char *filename, TokenList &tokens)
|
||||||
|
{
|
||||||
|
std::ifstream stream(filename);
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
while (std::getline(stream, line)) {
|
||||||
|
if (!line.empty() && line[0] != '#') {
|
||||||
|
text.append(line);
|
||||||
|
text.push_back('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream.bad())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tokenizer tok(text, " \t\r\n", "{}");
|
||||||
|
absl::string_view token;
|
||||||
|
while (!(token = tok.next()).empty())
|
||||||
|
tokens.emplace_back(token);
|
||||||
|
|
||||||
|
return !stream.bad();
|
||||||
|
}
|
||||||
13
editor/tools/layout-maker/sources/reader.h
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "layout.h"
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
Layout read_file_layout(const char *filename);
|
||||||
|
|
||||||
|
///
|
||||||
|
struct file_format_error : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
explicit file_format_error(const std::string &reason = "Format error")
|
||||||
|
: runtime_error(reason) {}
|
||||||
|
};
|
||||||
|
|
@ -98,10 +98,9 @@ endforeach()
|
||||||
if (SFIZZ_LV2_UI)
|
if (SFIZZ_LV2_UI)
|
||||||
execute_process (
|
execute_process (
|
||||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/Contents/Resources")
|
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||||
foreach(res ${EDITOR_RESOURCES})
|
copy_editor_resources(
|
||||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources/${res}"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources"
|
||||||
DESTINATION "${PROJECT_BINARY_DIR}/Contents/Resources")
|
"${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||||
endforeach()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,7 @@ Name: "vst3"; Description: "VST3 plugin"; Types: full custom;
|
||||||
[Files]
|
[Files]
|
||||||
Source: "sfizz.lv2\Contents\Binary\sfizz.dll"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Binary"; Flags: ignoreversion
|
Source: "sfizz.lv2\Contents\Binary\sfizz.dll"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Binary"; Flags: ignoreversion
|
||||||
Source: "sfizz.lv2\Contents\Binary\sfizz_ui.dll"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Binary"; Flags: ignoreversion
|
Source: "sfizz.lv2\Contents\Binary\sfizz_ui.dll"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Binary"; Flags: ignoreversion
|
||||||
Source: "sfizz.lv2\Contents\Resources\DefaultInstrument.sfz"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
Source: "sfizz.lv2\Contents\Resources\*"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
||||||
Source: "sfizz.lv2\Contents\Resources\DefaultScale.scl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
|
||||||
Source: "sfizz.lv2\Contents\Resources\logo.png"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
|
||||||
Source: "sfizz.lv2\manifest.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
Source: "sfizz.lv2\manifest.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
||||||
Source: "sfizz.lv2\sfizz.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
Source: "sfizz.lv2\sfizz.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
||||||
Source: "sfizz.lv2\sfizz_ui.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
Source: "sfizz.lv2\sfizz_ui.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
||||||
|
|
@ -60,7 +58,7 @@ Source: "sfizz.lv2\lgpl-3.0.txt"; Components: main; DestDir: "{app}"
|
||||||
Source: "sfizz.lv2\LICENSE.md"; Components: main; DestDir: "{app}"
|
Source: "sfizz.lv2\LICENSE.md"; Components: main; DestDir: "{app}"
|
||||||
Source: "sfizz.vst3\desktop.ini"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3"
|
Source: "sfizz.vst3\desktop.ini"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3"
|
||||||
Source: "sfizz.vst3\Contents\@VST3_PACKAGE_ARCHITECTURE@-win\sfizz.vst3"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3\Contents\@VST3_PACKAGE_ARCHITECTURE@-win"; Flags: ignoreversion
|
Source: "sfizz.vst3\Contents\@VST3_PACKAGE_ARCHITECTURE@-win\sfizz.vst3"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3\Contents\@VST3_PACKAGE_ARCHITECTURE@-win"; Flags: ignoreversion
|
||||||
Source: "sfizz.vst3\Contents\Resources\logo.png"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3\Contents\Resources"
|
Source: "sfizz.vst3\Contents\Resources\*"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3\Contents\Resources"
|
||||||
Source: "sfizz.vst3\Plugin.ico"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3"
|
Source: "sfizz.vst3\Plugin.ico"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3"
|
||||||
Source: "sfizz.vst3\gpl-3.0.txt"; Components: main; DestDir: "{app}"
|
Source: "sfizz.vst3\gpl-3.0.txt"; Components: main; DestDir: "{app}"
|
||||||
;Source: "setup\vc_redist.x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall
|
;Source: "setup\vc_redist.x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,9 @@ endif()
|
||||||
# Create the bundle (see "VST 3 Locations / Format")
|
# Create the bundle (see "VST 3 Locations / Format")
|
||||||
execute_process (
|
execute_process (
|
||||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||||
foreach(res ${EDITOR_RESOURCES})
|
copy_editor_resources(
|
||||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources/${res}"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources"
|
||||||
DESTINATION "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
"${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||||
endforeach()
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||||
SUFFIX ".vst3"
|
SUFFIX ".vst3"
|
||||||
|
|
|
||||||