1# ************************************************************************
2# FAUST Architecture File
3# Copyright (C) 2021 GRAME, Centre National de Creation Musicale
4# ---------------------------------------------------------------------
5
6# This is sample code. This file is provided as an example of minimal
7# FAUST architecture file. Redistribution and use in source and binary
8# forms, with or without modification, in part or in full are permitted.
9# In particular you can create a derived work of this FAUST architecture
10# and distribute that work under terms of your choice.
11
12# This sample code is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15# ************************************************************************
16
17# Architectures files
18include("/usr/local/share/faust/julia/dsp/dsp.jl")
19include("/usr/local/share/faust/julia/gui/UI.jl")
20
21# PathBuilder
22mutable struct PathBuilder
23    controlsLevel::Array{String}
24end
25
26function pushLabel!(builder::PathBuilder, label::String)
27    push!(builder.controlsLevel, label)
28end
29
30function popLabel!(builder::PathBuilder)
31    deleteat!(builder.controlsLevel, lastindex(builder.controlsLevel))
32end
33
34function buildPath(builder::PathBuilder, label::String)
35    path = join(builder.controlsLevel, "/")
36    res = "/$path/$label"
37    for c in [' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')']
38        res = replace(res, c => '_')
39    end
40    res
41end
42
43# UIZone with for sliders, nentries and bargraph
44struct UIZone
45    field::Symbol
46    init::FAUSTFLOAT
47    min::FAUSTFLOAT
48    max::FAUSTFLOAT
49    step::FAUSTFLOAT
50end
51
52# MapUI to keep [path,Symbol] and [label,Symbol] maps
53mutable struct MapUI <: UI
54    MapUI(dsp::dsp) = begin
55        map_ui = new()
56        map_ui.dsp = dsp
57        map_ui.label_paths = Dict{String,UIZone}()
58        map_ui.osc_paths = Dict{String,UIZone}()
59        map_ui.path_builder = PathBuilder([])
60        map_ui.root = String("")
61        map_ui
62	end
63    dsp::dsp
64    path_builder::PathBuilder
65    label_paths::Dict{String,UIZone}
66    osc_paths::Dict{String,UIZone}
67    root::String
68end
69
70# -- widget's layouts
71function openTabBox!(ui_interface::MapUI, label::String)
72    if (ui_interface.root == "") ui_interface.root = label end
73    pushLabel!(ui_interface.path_builder, label)
74end
75function openHorizontalBox!(ui_interface::MapUI, label::String)
76    if (ui_interface.root == "") ui_interface.root = label end
77    pushLabel!(ui_interface.path_builder, label)
78end
79function openVerticalBox!(ui_interface::MapUI, label::String)
80    if (ui_interface.root == "") ui_interface.root = label end
81    pushLabel!(ui_interface.path_builder, label)
82end
83function closeBox!(ui_interface::MapUI)
84    popLabel!(ui_interface.path_builder)
85end
86
87# -- active widgets
88function addButton!(ui_interface::MapUI, label::String, param::Symbol)
89    zone = UIZone(param, 0, 0, 1, 0)
90    ui_interface.label_paths[label] = zone
91    ui_interface.osc_paths[buildPath(ui_interface.path_builder, label)] = zone
92end
93function addCheckButton!(ui_interface::MapUI, label::String, param::Symbol)
94    zone = UIZone(param, 0, 0, 1, 0)
95    ui_interface.label_paths[label] = zone
96    ui_interface.osc_paths[buildPath(ui_interface.path_builder, label)] = zone
97end
98function addHorizontalSlider!(ui_interface::MapUI, label::String, param::Symbol, init::FAUSTFLOAT, min::FAUSTFLOAT, max::FAUSTFLOAT, step::FAUSTFLOAT)
99    zone = UIZone(param, init, min, max, step)
100    ui_interface.label_paths[label] = zone
101    ui_interface.osc_paths[buildPath(ui_interface.path_builder, label)] = zone
102end
103function addVerticalSlider!(ui_interface::MapUI, label::String, param::Symbol, init::FAUSTFLOAT, min::FAUSTFLOAT, max::FAUSTFLOAT, step::FAUSTFLOAT)
104    zone = UIZone(param, init, min, max, step)
105    ui_interface.label_paths[label] = zone
106    ui_interface.osc_paths[buildPath(ui_interface.path_builder, label)] = zone
107end
108function addNumEntry!(ui_interface::MapUI, label::String, param::Symbol, init::FAUSTFLOAT, min::FAUSTFLOAT, max::FAUSTFLOAT, step::FAUSTFLOAT)
109    zone = UIZone(param, init, min, max, step)
110    ui_interface.label_paths[label] = zone
111    ui_interface.osc_paths[buildPath(ui_interface.path_builder, label)] = zone
112end
113
114# -- passive widgets
115function addHorizontalBargraph!(ui_interface::MapUI, label::String, param::Symbol, min::FAUSTFLOAT, max::FAUSTFLOAT)
116    zone = UIZone(param, 0, min, max, 0)
117    ui_interface.label_paths[label] = zone
118    ui_interface.osc_paths[buildPath(ui_interface.path_builder, label)] = zone
119end
120function addVerticalBargraph!(ui_interface::MapUI, label::String, param::Symbol, min::FAUSTFLOAT, max::FAUSTFLOAT)
121    zone = UIZone(param, 0, min, max, 0)
122    ui_interface.label_paths[label] = zone
123    ui_interface.osc_paths[buildPath(ui_interface.path_builder, label)] = zone
124end
125
126# setParamValue/getParamValue
127function setParamValue!(ui_interface::MapUI, path::String, value::FAUSTFLOAT)
128    if (haskey(ui_interface.osc_paths, path))
129        setproperty!(ui_interface.dsp, ui_interface.osc_paths[path].field, value)
130    elseif (haskey(ui_interface.label_paths, path))
131        setproperty!(ui_interface.dsp, ui_interface.label_paths[path].field, value)
132    else
133        println("ERROR : setParamValue! '", path, "' not found")
134    end
135end
136
137function getParamValue(ui_interface::MapUI, path::String)
138    if (haskey(ui_interface.osc_paths, path))
139        return getproperty(ui_interface.dsp, ui_interface.osc_paths[path].field)
140    elseif (haskey(ui_interface.label_paths, path))
141        return getproperty(ui_interface.dsp, ui_interface.label_paths[path].field)
142    else
143        println("ERROR : getParamValue '", path, "' not found")
144        return 0;
145    end
146end
147
148function getZoneMap(ui_interface::MapUI)
149    return ui_interface.osc_paths
150end
151
152function getRoot(ui_interface::MapUI)
153    return "/" * ui_interface.root
154end