1 /** 2 Copyright: Guillaume Piolat 2015-2017. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 4 */ 5 module gui; 6 7 import std.math; 8 9 import dplug.math; 10 import dplug.gui; 11 import dplug.pbrwidgets; 12 import dplug.client; 13 import dplug.flatwidgets; 14 import leveldisplay; 15 import main; 16 17 // Plugin GUI, based on PBRBackgroundGUI. 18 // If you don't want to use PBR, you not inherit from it. 19 class DistortGUI : PBRBackgroundGUI!("basecolor.jpg", "emissive.png", "material.png", 20 "depth.png", "skybox.jpg", 21 22 // Enter here the absolute path to the gfx directory. 23 // This will allow to reload images at debug-time with the press of ENTER. 24 `C:\Users\myuser\Products\distort\gfx\`) 25 { 26 public: 27 nothrow: 28 @nogc: 29 30 this(DistortClient client) 31 { 32 _client = client; 33 34 35 static immutable float[7] ratios = [0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f]; 36 super( makeSizeConstraintsDiscrete(620, 330, ratios) ); 37 38 // Note: PBRCompositor default lighting might change in a future version (increase of light to allow white plastics). 39 // So we keep the value. 40 PBRCompositor comp = cast(PBRCompositor)compositor; 41 comp.light1Color = vec3f(0.26, 0.24, 0.22f) * 0.98f; 42 comp.light2Dir = vec3f(-0.5f, 1.0f, 0.23f).normalized; 43 comp.light2Color = vec3f(0.36, 0.38f, 0.40) * 1.148; 44 comp.light3Dir = vec3f(0.0f, 1.0f, 0.1f).normalized; 45 comp.light3Color = vec3f(0.2f, 0.2f, 0.2f) * 0.84f; 46 comp.ambientLight = 0.042f; 47 comp.skyboxAmount = 0.56f; 48 49 // Sets the number of pixels recomputed around dirtied controls. 50 // This is a tradeoff between Emissive light accuracy and speed. 51 // A typical good value is 20, and this is the default, as this is 52 // what `PBRCompositor` needs for the emissive pass. 53 setUpdateMargin(20); 54 55 // All resources are bundled as a string import. 56 // You can avoid resource compilers that way. 57 // The only cost is that each resource is in each binary, this creates overhead with 58 _font = mallocNew!Font(cast(ubyte[])( import("VeraBd.ttf") )); 59 60 // Builds the UI hierarchy 61 // Meanwhile, we hardcode each position. 62 63 RGBA litTrailDiffuse = RGBA(151, 119, 255, 100); 64 RGBA unlitTrailDiffuse = RGBA(81, 54, 108, 0); 65 66 _knobImageData = loadKnobImage( import("imageknob.png") ); 67 addChild(_imageKnob = mallocNew!UIImageKnob(context(), _knobImageData, cast(FloatParameter) _client.param(paramBias))); 68 _imageKnob.hasTrail = false; // no trail by default 69 70 // Add procedural knobs 71 addChild(_driveKnob = mallocNew!UIKnob(context(), cast(FloatParameter) _client.param(paramDrive))); 72 _driveKnob.knobRadius = 0.65f; 73 _driveKnob.knobDiffuse = RGBA(255, 255, 238, 0); 74 _driveKnob.knobMaterial = RGBA(0, 255, 128, 255); 75 _driveKnob.numLEDs = 15; 76 _driveKnob.litTrailDiffuse = litTrailDiffuse; 77 _driveKnob.unlitTrailDiffuse = unlitTrailDiffuse; 78 _driveKnob.LEDDiffuseLit = RGBA(40, 40, 40, 100); 79 _driveKnob.LEDDiffuseUnlit = RGBA(40, 40, 40, 0); 80 _driveKnob.LEDRadiusMin = 0.06f; 81 _driveKnob.LEDRadiusMax = 0.06f; 82 83 // Add sliders 84 addChild(_inputSlider = mallocNew!UISlider(context(), cast(FloatParameter) _client.param(paramInput))); 85 _inputSlider.litTrailDiffuse = litTrailDiffuse; 86 _inputSlider.unlitTrailDiffuse = unlitTrailDiffuse; 87 88 addChild(_outputSlider = mallocNew!UISlider(context(), cast(FloatParameter) _client.param(paramOutput))); 89 _outputSlider.litTrailDiffuse = litTrailDiffuse; 90 _outputSlider.unlitTrailDiffuse = unlitTrailDiffuse; 91 92 // Add switch 93 addChild(_onOffSwitch = mallocNew!UIOnOffSwitch(context(), cast(BoolParameter) _client.param(paramOnOff))); 94 _onOffSwitch.diffuseOn = litTrailDiffuse; 95 _onOffSwitch.diffuseOff = unlitTrailDiffuse; 96 97 // Add bargraphs 98 addChild(_inputLevel = mallocNew!UILevelDisplay(context())); 99 addChild(_outputLevel = mallocNew!UILevelDisplay(context())); 100 101 // Add resizer corner 102 addChild(_resizer = mallocNew!UIWindowResizer(context())); 103 104 // Global color correction. 105 // Very useful at the end of the UI creating process. 106 // As the sole Raw-only widget it is always on top and doesn't need zOrder adjustment. 107 { 108 mat3x4!float colorCorrectionMatrix = mat3x4!float(- 0.07f, 1.0f , 1.15f, 0.03f, 109 + 0.01f, 0.93f, 1.16f, 0.08f, 110 + 0.0f , 1.0f , 1.10f, -0.01f); 111 addChild(_colorCorrection = mallocNew!UIColorCorrection(context())); 112 _colorCorrection.setLiftGammaGainContrastRGB(colorCorrectionMatrix); 113 } 114 } 115 116 ~this() 117 { 118 // Note: UI widgets are owned by the UI and don't need to be destroyed manually 119 // However some of the resources they consumed aren't owned by them, but borrowed. 120 _font.destroyFree(); 121 _knobImageData.destroyFree(); 122 } 123 124 override void reflow() 125 { 126 super.reflow(); 127 int W = position.width; 128 int H = position.height; 129 float S = W / cast(float)(context.getDefaultUIWidth()); 130 _imageKnob.position = rectangle(517, 176, 46, 46).scaleByFactor(S); 131 _inputSlider.position = rectangle(190, 132, 30, 130).scaleByFactor(S); 132 _outputSlider.position = rectangle(410, 132, 30, 130).scaleByFactor(S); 133 _onOffSwitch.position = rectangle(90, 177, 30, 40).scaleByFactor(S); 134 _driveKnob.position = rectangle(250, 140, 120, 120).scaleByFactor(S); 135 _inputLevel.position = rectangle(150, 132, 30, 130).scaleByFactor(S); 136 _outputLevel.position = rectangle(450, 132, 30, 130).scaleByFactor(S); 137 138 _colorCorrection.position = rectangle(0, 0, W, H); 139 _resizer.position = rectangle(W-30, H-30, 30, 30); 140 } 141 142 void sendFeedbackToUI(float* inputRMS, float* outputRMS, int frames, float sampleRate) 143 { 144 _inputLevel.sendFeedbackToUI(inputRMS, frames, sampleRate); 145 _outputLevel.sendFeedbackToUI(outputRMS, frames, sampleRate); 146 } 147 148 private: 149 DistortClient _client; 150 UISlider _inputSlider; 151 UIKnob _driveKnob; 152 UISlider _outputSlider; 153 UIOnOffSwitch _onOffSwitch; 154 UILevelDisplay _inputLevel, _outputLevel; 155 UIColorCorrection _colorCorrection; 156 Font _font; 157 KnobImage _knobImageData; 158 UIImageKnob _imageKnob; 159 UIWindowResizer _resizer; 160 }