User interface update
|
|
@ -3,8 +3,23 @@ include("cmake/Vstgui.cmake")
|
|||
|
||||
set(EDITOR_RESOURCES
|
||||
logo.png
|
||||
logo_text.png
|
||||
logo_text@2x.png
|
||||
icon_white.png
|
||||
icon_white@2x.png
|
||||
knob48.png
|
||||
knob48@2x.png
|
||||
Fonts/fluentui-system-regular-20.ttf
|
||||
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
|
||||
add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
||||
src/editor/EditIds.h
|
||||
|
|
@ -14,8 +29,53 @@ add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
|||
src/editor/EditorController.h
|
||||
src/editor/GUIComponents.h
|
||||
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_before.h)
|
||||
target_include_directories(sfizz_editor PUBLIC "src")
|
||||
target_link_libraries(sfizz_editor PRIVATE sfizz-vstgui)
|
||||
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 "${CMAKE_CURRENT_BINARY_DIR}/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()
|
||||
|
|
|
|||
|
|
@ -211,6 +211,8 @@ endif()
|
|||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
# higher C++ requirement on Windows
|
||||
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()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
|
|
|
|||
344
editor/layout/main.fl
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
# data file for the Fltk User Interface Designer (fluid)
|
||||
version 1.0305
|
||||
header_name {.h}
|
||||
code_name {.cxx}
|
||||
widget_class mainView {open
|
||||
xywh {410 523 800 475} type Double
|
||||
class LogicalGroup visible
|
||||
} {
|
||||
Fl_Group {} {
|
||||
comment {theme=darkTheme} open
|
||||
xywh {0 0 800 110}
|
||||
class LogicalGroup
|
||||
} {
|
||||
Fl_Group {} {open
|
||||
xywh {5 4 100 101} box ROUNDED_BOX align 0
|
||||
class RoundedGroup
|
||||
} {
|
||||
Fl_Box {} {
|
||||
comment {tag=kTagFirstChangePanel+kPanelGeneral}
|
||||
image {../resources/icon_white.png} xywh {7 6 96 96}
|
||||
class SfizzMainButton
|
||||
}
|
||||
}
|
||||
Fl_Group {} {open
|
||||
xywh {110 5 380 100} box ROUNDED_BOX
|
||||
class RoundedGroup
|
||||
} {
|
||||
Fl_Box {} {
|
||||
label {File:}
|
||||
xywh {125 15 40 25} labelsize 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {KS:}
|
||||
xywh {125 45 40 25} labelsize 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Separator 1}
|
||||
xywh {120 40 355 5} box BORDER_BOX labeltype NO_LABEL
|
||||
class HLine
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Separator 2}
|
||||
xywh {120 70 355 5} box BORDER_BOX labeltype NO_LABEL
|
||||
class HLine
|
||||
}
|
||||
Fl_Box sfzFileLabel_ {
|
||||
label {DefaultInstrument.sfz}
|
||||
xywh {190 15 230 25} labelsize 20
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Key switch}
|
||||
xywh {190 45 230 25} labelsize 20
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Voices:}
|
||||
xywh {120 75 60 25} labelsize 12 align 24
|
||||
class Label
|
||||
}
|
||||
Fl_Button {} {
|
||||
comment {tag=kTagLoadSfzFile}
|
||||
xywh {425 15 25 25} labelsize 24
|
||||
class LoadFileButton
|
||||
}
|
||||
Fl_Button {} {
|
||||
comment {tag=kTagEditSfzFile}
|
||||
xywh {450 15 25 25} labelsize 24
|
||||
class EditFileButton
|
||||
}
|
||||
Fl_Box infoVoicesLabel_ {
|
||||
xywh {185 75 50 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Max:}
|
||||
xywh {240 75 60 25} labelsize 12 align 24
|
||||
class Label
|
||||
}
|
||||
Fl_Box numVoicesLabel_ {
|
||||
xywh {305 75 50 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Memory:}
|
||||
xywh {360 75 60 25} labelsize 12 align 24
|
||||
class Label
|
||||
}
|
||||
Fl_Box memoryLabel_ {
|
||||
xywh {425 75 50 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
}
|
||||
Fl_Group {} {open
|
||||
xywh {495 5 100 100} box ROUNDED_BOX
|
||||
class RoundedGroup
|
||||
} {
|
||||
Fl_Light_Button {} {
|
||||
label SETUP
|
||||
comment {tag=kTagFirstChangePanel+kPanelSettings}
|
||||
xywh {510 42 70 25}
|
||||
class LightButton
|
||||
}
|
||||
Fl_Light_Button {} {
|
||||
label CC
|
||||
comment {tag=kTagFirstChangePanel+kPanelControls}
|
||||
xywh {510 15 70 25}
|
||||
class LightButton
|
||||
}
|
||||
Fl_Light_Button {} {
|
||||
label INFO
|
||||
comment {tag=kTagFirstChangePanel+kPanelInfo}
|
||||
xywh {510 69 70 25}
|
||||
class LightButton
|
||||
}
|
||||
}
|
||||
Fl_Group {} {open
|
||||
xywh {600 5 195 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 25} 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 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Box {} {
|
||||
xywh {745 20 35 70} box BORDER_BOX
|
||||
class VMeter
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Group {subPanels_[kPanelGeneral]} {
|
||||
xywh {5 110 790 285} hide
|
||||
class LogicalGroup
|
||||
} {
|
||||
Fl_Group {} {open
|
||||
xywh {5 110 120 285} box ROUNDED_BOX
|
||||
class RoundedGroup
|
||||
} {
|
||||
Fl_Box {} {
|
||||
label {Curves:}
|
||||
xywh {15 120 60 25} labelsize 12 align 20
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Masters:}
|
||||
xywh {15 145 60 25} labelsize 12 align 20
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Groups:}
|
||||
xywh {15 170 60 25} labelsize 12 align 20
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Regions:}
|
||||
xywh {15 195 60 25} labelsize 12 align 20
|
||||
class Label
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Samples:}
|
||||
xywh {15 220 60 25} labelsize 12 align 20
|
||||
class Label
|
||||
}
|
||||
Fl_Box infoCurvesLabel_ {
|
||||
label 0
|
||||
xywh {75 120 40 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box infoMastersLabel_ {
|
||||
label 0
|
||||
xywh {75 145 40 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box infoGroupsLabel_ {
|
||||
label 0
|
||||
xywh {75 170 40 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box infoRegionsLabel_ {
|
||||
label 0
|
||||
xywh {75 195 40 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
Fl_Box infoSamplesLabel_ {
|
||||
label 0
|
||||
xywh {75 220 40 25} labelsize 12 align 16
|
||||
class Label
|
||||
}
|
||||
}
|
||||
Fl_Group {} {open
|
||||
xywh {130 110 665 280}
|
||||
class LogicalGroup
|
||||
} {
|
||||
Fl_Box {} {
|
||||
image {../resources/logo_text.png} xywh {260 125 400 250}
|
||||
class SfizzLargePicture
|
||||
}
|
||||
}
|
||||
}
|
||||
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 110 790 285}
|
||||
class LogicalGroup
|
||||
} {
|
||||
Fl_Group {} {
|
||||
label Engine open selected
|
||||
xywh {260 125 280 110} box ROUNDED_BOX labelsize 12 align 17
|
||||
class TitleGroup
|
||||
} {
|
||||
Fl_Spinner numVoicesSlider_ {
|
||||
comment {tag=kTagSetNumVoices}
|
||||
xywh {285 185 60 25} labelsize 12 textsize 12
|
||||
class ValueMenu
|
||||
}
|
||||
Fl_Box {} {
|
||||
label Polyphony
|
||||
xywh {275 145 80 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Spinner oversamplingSlider_ {
|
||||
comment {tag=kTagSetOversampling}
|
||||
xywh {370 185 60 25} labelsize 12 textsize 12
|
||||
class ValueMenu
|
||||
}
|
||||
Fl_Box {} {
|
||||
label Oversampling
|
||||
xywh {360 145 80 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Preload size}
|
||||
xywh {445 145 80 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Spinner preloadSizeSlider_ {
|
||||
comment {tag=kTagSetPreloadSize}
|
||||
xywh {455 185 60 25} labelsize 12 textsize 12
|
||||
class ValueMenu
|
||||
}
|
||||
}
|
||||
Fl_Group {} {
|
||||
label Tuning open
|
||||
xywh {205 260 390 120} box ROUNDED_BOX labelsize 12 align 17
|
||||
class TitleGroup
|
||||
} {
|
||||
Fl_Box {} {
|
||||
label {Root key}
|
||||
xywh {330 280 80 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Spinner tuningFrequencySlider_ {
|
||||
comment {tag=kTagSetTuningFrequency}
|
||||
xywh {425 320 60 25} labelsize 12 textsize 12
|
||||
class ValueMenu
|
||||
}
|
||||
Fl_Box {} {
|
||||
label Frequency
|
||||
xywh {415 280 80 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Dial stretchedTuningSlider_ {
|
||||
comment {tag=kTagSetStretchedTuning}
|
||||
xywh {515 305 48 48} value 0.5
|
||||
class Knob48
|
||||
}
|
||||
Fl_Box {} {
|
||||
label Stretch
|
||||
xywh {500 280 80 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Scala file}
|
||||
xywh {225 280 100 25} labelsize 12
|
||||
class ValueLabel
|
||||
}
|
||||
Fl_Button scalaFileButton_ {
|
||||
label DefaultScale
|
||||
comment {tag=kTagLoadScalaFile}
|
||||
xywh {225 320 100 25} labelsize 12
|
||||
class ValueButton
|
||||
}
|
||||
Fl_Spinner scalaRootKeySlider_ {
|
||||
comment {tag=kTagSetScalaRootKey}
|
||||
xywh {340 320 35 25} labelsize 12 textsize 12
|
||||
class ValueMenu
|
||||
}
|
||||
Fl_Spinner scalaRootOctaveSlider_ {
|
||||
comment {tag=kTagSetScalaRootKey}
|
||||
xywh {375 320 30 25} labelsize 12 textsize 12
|
||||
class ValueMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Group {subPanels_[kPanelInfo]} {
|
||||
xywh {5 110 790 285} hide
|
||||
class LogicalGroup
|
||||
} {
|
||||
Fl_Group {} {open
|
||||
xywh {5 110 790 285} box ROUNDED_BOX
|
||||
class RoundedGroup
|
||||
} {
|
||||
Fl_Box {} {
|
||||
label {Informative text goes here}
|
||||
xywh {5 110 790 285} labelsize 40
|
||||
class Label
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Box {} {
|
||||
xywh {5 400 790 70}
|
||||
class Piano
|
||||
}
|
||||
}
|
||||
BIN
editor/resources/Fonts/fluentui-system-regular-20.ttf
Normal file
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: 11 KiB |
BIN
editor/resources/knob48@2x.png
Normal file
|
After Width: | Height: | Size: 107 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 |
|
|
@ -5,34 +5,422 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#include "GUIComponents.h"
|
||||
#include <cmath>
|
||||
|
||||
#include "utility/vstgui_before.h"
|
||||
#include "vstgui/lib/cdrawcontext.h"
|
||||
#include "vstgui/lib/cgraphicspath.h"
|
||||
#include "vstgui/lib/cframe.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);
|
||||
|
||||
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);
|
||||
CViewContainer::setBackgroundColor(CColor(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
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 handle = calculateHandleRect(getValueNormalized());
|
||||
|
||||
dc->setDrawMode(kAntiAliasing);
|
||||
|
||||
dc->setFrameColor(_frame);
|
||||
dc->drawRect(bounds, kDrawStroked);
|
||||
SharedPointer<CGraphicsPath> path = owned(dc->createGraphicsPath());
|
||||
path->addRoundRect(bounds, cornerRadius_);
|
||||
|
||||
dc->setFillColor(_fill);
|
||||
dc->drawRect(handle, kDrawFilled);
|
||||
dc->setFillColor(backgroundColor_);
|
||||
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->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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,22 +5,144 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#pragma once
|
||||
#include <bitset>
|
||||
|
||||
#include "utility/vstgui_before.h"
|
||||
#include "vstgui/lib/controls/cslider.h"
|
||||
#include "vstgui/lib/controls/cknob.h"
|
||||
#include "vstgui/lib/controls/ctextlabel.h"
|
||||
#include "vstgui/lib/controls/coptionmenu.h"
|
||||
#include "vstgui/lib/cviewcontainer.h"
|
||||
#include "vstgui/lib/ccolor.h"
|
||||
#include "vstgui/lib/dragging.h"
|
||||
#include "utility/vstgui_after.h"
|
||||
|
||||
using namespace VSTGUI;
|
||||
|
||||
class SimpleSlider : public CSliderBase {
|
||||
///
|
||||
class SBoxContainer : public CViewContainer {
|
||||
public:
|
||||
SimpleSlider(const CRect& bounds, IControlListener* listener, int32_t tag);
|
||||
void draw(CDrawContext* dc) override;
|
||||
explicit SBoxContainer(const CRect& size);
|
||||
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:
|
||||
CColor _frame = CColor(0x00, 0x00, 0x00);
|
||||
CColor _fill = CColor(0x00, 0x00, 0x00);
|
||||
std::string text_;
|
||||
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_;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
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
|
||||
167
editor/src/editor/layout/main.hpp
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/* 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;
|
||||
enterTheme(darkTheme);
|
||||
LogicalGroup* const view__1 = createLogicalGroup(CRect(0, 0, 800, 110), -1, "", kCenterText, 14);
|
||||
view__0->addView(view__1);
|
||||
RoundedGroup* const view__2 = createRoundedGroup(CRect(5, 4, 105, 105), -1, "", kCenterText, 14);
|
||||
view__1->addView(view__2);
|
||||
SfizzMainButton* const view__3 = createSfizzMainButton(CRect(2, 2, 98, 98), kTagFirstChangePanel+kPanelGeneral, "", kCenterText, 14);
|
||||
view__2->addView(view__3);
|
||||
RoundedGroup* const view__4 = createRoundedGroup(CRect(110, 5, 490, 105), -1, "", kCenterText, 14);
|
||||
view__1->addView(view__4);
|
||||
Label* const view__5 = createLabel(CRect(15, 10, 55, 35), -1, "File:", kCenterText, 16);
|
||||
view__4->addView(view__5);
|
||||
Label* const view__6 = createLabel(CRect(15, 40, 55, 65), -1, "KS:", kCenterText, 16);
|
||||
view__4->addView(view__6);
|
||||
HLine* const view__7 = createHLine(CRect(10, 35, 365, 40), -1, "", kCenterText, 14);
|
||||
view__4->addView(view__7);
|
||||
HLine* const view__8 = createHLine(CRect(10, 65, 365, 70), -1, "", kCenterText, 14);
|
||||
view__4->addView(view__8);
|
||||
Label* const view__9 = createLabel(CRect(80, 10, 310, 35), -1, "DefaultInstrument.sfz", kCenterText, 20);
|
||||
sfzFileLabel_ = view__9;
|
||||
view__4->addView(view__9);
|
||||
Label* const view__10 = createLabel(CRect(80, 40, 310, 65), -1, "Key switch", kCenterText, 20);
|
||||
view__4->addView(view__10);
|
||||
Label* const view__11 = createLabel(CRect(10, 70, 70, 95), -1, "Voices:", kRightText, 12);
|
||||
view__4->addView(view__11);
|
||||
LoadFileButton* const view__12 = createLoadFileButton(CRect(315, 10, 340, 35), kTagLoadSfzFile, "", kCenterText, 24);
|
||||
view__4->addView(view__12);
|
||||
EditFileButton* const view__13 = createEditFileButton(CRect(340, 10, 365, 35), kTagEditSfzFile, "", kCenterText, 24);
|
||||
view__4->addView(view__13);
|
||||
Label* const view__14 = createLabel(CRect(75, 70, 125, 95), -1, "", kCenterText, 12);
|
||||
infoVoicesLabel_ = view__14;
|
||||
view__4->addView(view__14);
|
||||
Label* const view__15 = createLabel(CRect(130, 70, 190, 95), -1, "Max:", kRightText, 12);
|
||||
view__4->addView(view__15);
|
||||
Label* const view__16 = createLabel(CRect(195, 70, 245, 95), -1, "", kCenterText, 12);
|
||||
numVoicesLabel_ = view__16;
|
||||
view__4->addView(view__16);
|
||||
Label* const view__17 = createLabel(CRect(250, 70, 310, 95), -1, "Memory:", kRightText, 12);
|
||||
view__4->addView(view__17);
|
||||
Label* const view__18 = createLabel(CRect(315, 70, 365, 95), -1, "", kCenterText, 12);
|
||||
memoryLabel_ = view__18;
|
||||
view__4->addView(view__18);
|
||||
RoundedGroup* const view__19 = createRoundedGroup(CRect(495, 5, 595, 105), -1, "", kCenterText, 14);
|
||||
view__1->addView(view__19);
|
||||
LightButton* const view__20 = createLightButton(CRect(15, 37, 85, 62), kTagFirstChangePanel+kPanelSettings, "SETUP", kCenterText, 14);
|
||||
view__19->addView(view__20);
|
||||
LightButton* const view__21 = createLightButton(CRect(15, 10, 85, 35), kTagFirstChangePanel+kPanelControls, "CC", kCenterText, 14);
|
||||
view__19->addView(view__21);
|
||||
LightButton* const view__22 = createLightButton(CRect(15, 64, 85, 89), kTagFirstChangePanel+kPanelInfo, "INFO", kCenterText, 14);
|
||||
view__19->addView(view__22);
|
||||
RoundedGroup* const view__23 = createRoundedGroup(CRect(600, 5, 795, 105), -1, "", kCenterText, 14);
|
||||
view__1->addView(view__23);
|
||||
Knob48* const view__24 = createKnob48(CRect(15, 15, 63, 63), -1, "", kCenterText, 14);
|
||||
view__23->addView(view__24);
|
||||
view__24->setVisible(false);
|
||||
ValueLabel* const view__25 = createValueLabel(CRect(10, 65, 70, 90), -1, "Center", kCenterText, 12);
|
||||
view__23->addView(view__25);
|
||||
view__25->setVisible(false);
|
||||
Knob48* const view__26 = createKnob48(CRect(80, 15, 128, 63), kTagSetVolume, "", kCenterText, 14);
|
||||
volumeSlider_ = view__26;
|
||||
view__23->addView(view__26);
|
||||
ValueLabel* const view__27 = createValueLabel(CRect(75, 65, 135, 90), -1, "0.0 dB", kCenterText, 12);
|
||||
volumeLabel_ = view__27;
|
||||
view__23->addView(view__27);
|
||||
VMeter* const view__28 = createVMeter(CRect(145, 15, 180, 85), -1, "", kCenterText, 14);
|
||||
view__23->addView(view__28);
|
||||
enterTheme(defaultTheme);
|
||||
LogicalGroup* const view__29 = createLogicalGroup(CRect(5, 110, 795, 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, 120, 285), -1, "", kCenterText, 14);
|
||||
view__29->addView(view__30);
|
||||
Label* const view__31 = createLabel(CRect(10, 10, 70, 35), -1, "Curves:", kLeftText, 12);
|
||||
view__30->addView(view__31);
|
||||
Label* const view__32 = createLabel(CRect(10, 35, 70, 60), -1, "Masters:", kLeftText, 12);
|
||||
view__30->addView(view__32);
|
||||
Label* const view__33 = createLabel(CRect(10, 60, 70, 85), -1, "Groups:", kLeftText, 12);
|
||||
view__30->addView(view__33);
|
||||
Label* const view__34 = createLabel(CRect(10, 85, 70, 110), -1, "Regions:", kLeftText, 12);
|
||||
view__30->addView(view__34);
|
||||
Label* const view__35 = createLabel(CRect(10, 110, 70, 135), -1, "Samples:", kLeftText, 12);
|
||||
view__30->addView(view__35);
|
||||
Label* const view__36 = createLabel(CRect(70, 10, 110, 35), -1, "0", kCenterText, 12);
|
||||
infoCurvesLabel_ = view__36;
|
||||
view__30->addView(view__36);
|
||||
Label* const view__37 = createLabel(CRect(70, 35, 110, 60), -1, "0", kCenterText, 12);
|
||||
infoMastersLabel_ = view__37;
|
||||
view__30->addView(view__37);
|
||||
Label* const view__38 = createLabel(CRect(70, 60, 110, 85), -1, "0", kCenterText, 12);
|
||||
infoGroupsLabel_ = view__38;
|
||||
view__30->addView(view__38);
|
||||
Label* const view__39 = createLabel(CRect(70, 85, 110, 110), -1, "0", kCenterText, 12);
|
||||
infoRegionsLabel_ = view__39;
|
||||
view__30->addView(view__39);
|
||||
Label* const view__40 = createLabel(CRect(70, 110, 110, 135), -1, "0", kCenterText, 12);
|
||||
infoSamplesLabel_ = view__40;
|
||||
view__30->addView(view__40);
|
||||
LogicalGroup* const view__41 = createLogicalGroup(CRect(125, 0, 790, 280), -1, "", kCenterText, 14);
|
||||
view__29->addView(view__41);
|
||||
SfizzLargePicture* const view__42 = createSfizzLargePicture(CRect(130, 15, 530, 265), -1, "", kCenterText, 14);
|
||||
view__41->addView(view__42);
|
||||
LogicalGroup* const view__43 = createLogicalGroup(CRect(5, 110, 795, 395), -1, "", kCenterText, 14);
|
||||
subPanels_[kPanelControls] = view__43;
|
||||
view__0->addView(view__43);
|
||||
view__43->setVisible(false);
|
||||
RoundedGroup* const view__44 = createRoundedGroup(CRect(0, 0, 790, 285), -1, "", kCenterText, 14);
|
||||
view__43->addView(view__44);
|
||||
Label* const view__45 = createLabel(CRect(0, 0, 790, 285), -1, "Controls not available", kCenterText, 40);
|
||||
view__44->addView(view__45);
|
||||
LogicalGroup* const view__46 = createLogicalGroup(CRect(5, 110, 795, 395), -1, "", kCenterText, 14);
|
||||
subPanels_[kPanelSettings] = view__46;
|
||||
view__0->addView(view__46);
|
||||
TitleGroup* const view__47 = createTitleGroup(CRect(255, 15, 535, 125), -1, "Engine", kCenterText, 12);
|
||||
view__46->addView(view__47);
|
||||
ValueMenu* const view__48 = createValueMenu(CRect(25, 60, 85, 85), kTagSetNumVoices, "", kCenterText, 12);
|
||||
numVoicesSlider_ = view__48;
|
||||
view__47->addView(view__48);
|
||||
ValueLabel* const view__49 = createValueLabel(CRect(15, 20, 95, 45), -1, "Polyphony", kCenterText, 12);
|
||||
view__47->addView(view__49);
|
||||
ValueMenu* const view__50 = createValueMenu(CRect(110, 60, 170, 85), kTagSetOversampling, "", kCenterText, 12);
|
||||
oversamplingSlider_ = view__50;
|
||||
view__47->addView(view__50);
|
||||
ValueLabel* const view__51 = createValueLabel(CRect(100, 20, 180, 45), -1, "Oversampling", kCenterText, 12);
|
||||
view__47->addView(view__51);
|
||||
ValueLabel* const view__52 = createValueLabel(CRect(185, 20, 265, 45), -1, "Preload size", kCenterText, 12);
|
||||
view__47->addView(view__52);
|
||||
ValueMenu* const view__53 = createValueMenu(CRect(195, 60, 255, 85), kTagSetPreloadSize, "", kCenterText, 12);
|
||||
preloadSizeSlider_ = view__53;
|
||||
view__47->addView(view__53);
|
||||
TitleGroup* const view__54 = createTitleGroup(CRect(200, 150, 590, 270), -1, "Tuning", kCenterText, 12);
|
||||
view__46->addView(view__54);
|
||||
ValueLabel* const view__55 = createValueLabel(CRect(125, 20, 205, 45), -1, "Root key", kCenterText, 12);
|
||||
view__54->addView(view__55);
|
||||
ValueMenu* const view__56 = createValueMenu(CRect(220, 60, 280, 85), kTagSetTuningFrequency, "", kCenterText, 12);
|
||||
tuningFrequencySlider_ = view__56;
|
||||
view__54->addView(view__56);
|
||||
ValueLabel* const view__57 = createValueLabel(CRect(210, 20, 290, 45), -1, "Frequency", kCenterText, 12);
|
||||
view__54->addView(view__57);
|
||||
Knob48* const view__58 = createKnob48(CRect(310, 45, 358, 93), kTagSetStretchedTuning, "", kCenterText, 14);
|
||||
stretchedTuningSlider_ = view__58;
|
||||
view__54->addView(view__58);
|
||||
ValueLabel* const view__59 = createValueLabel(CRect(295, 20, 375, 45), -1, "Stretch", kCenterText, 12);
|
||||
view__54->addView(view__59);
|
||||
ValueLabel* const view__60 = createValueLabel(CRect(20, 20, 120, 45), -1, "Scala file", kCenterText, 12);
|
||||
view__54->addView(view__60);
|
||||
ValueButton* const view__61 = createValueButton(CRect(20, 60, 120, 85), kTagLoadScalaFile, "DefaultScale", kCenterText, 12);
|
||||
scalaFileButton_ = view__61;
|
||||
view__54->addView(view__61);
|
||||
ValueMenu* const view__62 = createValueMenu(CRect(135, 60, 170, 85), kTagSetScalaRootKey, "", kCenterText, 12);
|
||||
scalaRootKeySlider_ = view__62;
|
||||
view__54->addView(view__62);
|
||||
ValueMenu* const view__63 = createValueMenu(CRect(170, 60, 200, 85), kTagSetScalaRootKey, "", kCenterText, 12);
|
||||
scalaRootOctaveSlider_ = view__63;
|
||||
view__54->addView(view__63);
|
||||
LogicalGroup* const view__64 = createLogicalGroup(CRect(5, 110, 795, 395), -1, "", kCenterText, 14);
|
||||
subPanels_[kPanelInfo] = view__64;
|
||||
view__0->addView(view__64);
|
||||
view__64->setVisible(false);
|
||||
RoundedGroup* const view__65 = createRoundedGroup(CRect(0, 0, 790, 285), -1, "", kCenterText, 14);
|
||||
view__64->addView(view__65);
|
||||
Label* const view__66 = createLabel(CRect(0, 0, 790, 285), -1, "Informative text goes here", kCenterText, 40);
|
||||
view__65->addView(view__66);
|
||||
Piano* const view__67 = createPiano(CRect(5, 400, 795, 470), -1, "", kCenterText, 14);
|
||||
view__0->addView(view__67);
|
||||
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)
|
||||
execute_process (
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||
foreach(res ${EDITOR_RESOURCES})
|
||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources/${res}"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||
endforeach()
|
||||
copy_editor_resources(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources"
|
||||
"${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||
endif()
|
||||
|
||||
# Installation
|
||||
|
|
|
|||
|
|
@ -50,9 +50,7 @@ Name: "vst3"; Description: "VST3 plugin"; Types: full custom;
|
|||
[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_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\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\Contents\Resources\*"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
||||
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_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.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\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\gpl-3.0.txt"; Components: main; DestDir: "{app}"
|
||||
;Source: "setup\vc_redist.x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall
|
||||
|
|
|
|||
|
|
@ -68,10 +68,9 @@ endif()
|
|||
# Create the bundle (see "VST 3 Locations / Format")
|
||||
execute_process (
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||
foreach(res ${EDITOR_RESOURCES})
|
||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources/${res}"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||
endforeach()
|
||||
copy_editor_resources(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources"
|
||||
"${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||
if(WIN32)
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
SUFFIX ".vst3"
|
||||
|
|
|
|||